Imported Upstream version 1.7.1 94/76794/1 upstream/1.7.1
authorDongsun Lee <ds73.lee@samsung.com>
Mon, 27 Jun 2016 05:19:02 +0000 (14:19 +0900)
committerDongsun Lee <ds73.lee@samsung.com>
Mon, 27 Jun 2016 08:32:23 +0000 (17:32 +0900)
Change-Id: I327d8fd9ff77babc20a0dd1e7e8f6890ec0da1db
Signed-off-by: Dongsun Lee <ds73.lee@samsung.com>
281 files changed:
AUTHORS
ChangeLog
LICENSES
Makefile.am
Makefile.in
NEWS
README
VERSION
acinclude.m4
aclocal.m4
build-aux/compile
build-aux/config.guess
build-aux/config.rpath
build-aux/config.sub
build-aux/depcomp
build-aux/install-sh
build-aux/mdate-sh
build-aux/missing
build-aux/texinfo.tex
cipher/Makefile.am
cipher/Makefile.in
cipher/Manifest [deleted file]
cipher/arcfour-amd64.S [new file with mode: 0644]
cipher/arcfour.c
cipher/bithelp.h
cipher/blowfish-amd64.S
cipher/blowfish-arm.S
cipher/blowfish.c
cipher/bufhelp.h
cipher/camellia-aesni-avx-amd64.S
cipher/camellia-aesni-avx2-amd64.S
cipher/camellia-arm.S
cipher/camellia-glue.c
cipher/cast5-amd64.S
cipher/cast5-arm.S
cipher/cast5.c
cipher/chacha20-armv7-neon.S [new file with mode: 0644]
cipher/chacha20-avx2-amd64.S [new file with mode: 0644]
cipher/chacha20-sse2-amd64.S [new file with mode: 0644]
cipher/chacha20-ssse3-amd64.S [new file with mode: 0644]
cipher/chacha20.c [new file with mode: 0644]
cipher/cipher-aeswrap.c
cipher/cipher-cbc.c
cipher/cipher-ccm.c
cipher/cipher-cfb.c
cipher/cipher-cmac.c
cipher/cipher-ctr.c
cipher/cipher-gcm-intel-pclmul.c [new file with mode: 0644]
cipher/cipher-gcm.c
cipher/cipher-internal.h
cipher/cipher-ocb.c [new file with mode: 0644]
cipher/cipher-ofb.c
cipher/cipher-poly1305.c [new file with mode: 0644]
cipher/cipher-selftest.c
cipher/cipher-selftest.h
cipher/cipher.c
cipher/crc-intel-pclmul.c [new file with mode: 0644]
cipher/crc.c
cipher/des-amd64.S [new file with mode: 0644]
cipher/des.c
cipher/dsa-common.c
cipher/dsa.c
cipher/ecc-common.h
cipher/ecc-curves.c
cipher/ecc-eddsa.c
cipher/ecc-misc.c
cipher/ecc.c
cipher/elgamal.c
cipher/gost-s-box.c [new file with mode: 0644]
cipher/gost.h
cipher/gost28147.c
cipher/gostr3411-94.c
cipher/hash-common.c
cipher/hash-common.h
cipher/hmac-tests.c
cipher/kdf.c
cipher/keccak-armv7-neon.S [new file with mode: 0644]
cipher/keccak.c [new file with mode: 0644]
cipher/keccak_permute_32.h [new file with mode: 0644]
cipher/keccak_permute_64.h [new file with mode: 0644]
cipher/mac-cmac.c
cipher/mac-gmac.c
cipher/mac-hmac.c
cipher/mac-internal.h
cipher/mac-poly1305.c [new file with mode: 0644]
cipher/mac.c
cipher/md.c
cipher/md4.c
cipher/md5.c
cipher/poly1305-armv7-neon.S [new file with mode: 0644]
cipher/poly1305-avx2-amd64.S [new file with mode: 0644]
cipher/poly1305-internal.h [new file with mode: 0644]
cipher/poly1305-sse2-amd64.S [new file with mode: 0644]
cipher/poly1305.c [new file with mode: 0644]
cipher/primegen.c
cipher/pubkey-internal.h
cipher/pubkey-util.c
cipher/pubkey.c
cipher/rijndael-aesni.c [new file with mode: 0644]
cipher/rijndael-amd64.S
cipher/rijndael-arm.S
cipher/rijndael-internal.h [new file with mode: 0644]
cipher/rijndael-padlock.c [new file with mode: 0644]
cipher/rijndael-ssse3-amd64.c [new file with mode: 0644]
cipher/rijndael-tables.h
cipher/rijndael.c
cipher/rmd160.c
cipher/rsa-common.c
cipher/rsa.c
cipher/salsa20-amd64.S
cipher/salsa20-armv7-neon.S
cipher/salsa20.c
cipher/scrypt.c
cipher/serpent-armv7-neon.S
cipher/serpent-avx2-amd64.S
cipher/serpent-sse2-amd64.S
cipher/serpent.c
cipher/sha1-armv7-neon.S [new file with mode: 0644]
cipher/sha1-avx-amd64.S [new file with mode: 0644]
cipher/sha1-avx-bmi2-amd64.S [new file with mode: 0644]
cipher/sha1-ssse3-amd64.S
cipher/sha1.c
cipher/sha1.h [moved from cipher/rmd.h with 54% similarity]
cipher/sha256-avx-amd64.S [new file with mode: 0644]
cipher/sha256-avx2-bmi2-amd64.S [new file with mode: 0644]
cipher/sha256-ssse3-amd64.S
cipher/sha256.c
cipher/sha512-arm.S [new file with mode: 0644]
cipher/sha512-armv7-neon.S
cipher/sha512-avx-amd64.S
cipher/sha512-avx2-bmi2-amd64.S
cipher/sha512-ssse3-amd64.S
cipher/sha512.c
cipher/stribog.c
cipher/tiger.c
cipher/twofish-amd64.S
cipher/twofish-arm.S
cipher/twofish.c
cipher/whirlpool-sse2-amd64.S [new file with mode: 0644]
cipher/whirlpool.c
compat/Makefile.in
compat/compat.c
config.h.in
configure
configure.ac
doc/Makefile.am
doc/Makefile.in
doc/fips-fsm.eps
doc/fips-fsm.pdf
doc/fips-fsm.png
doc/gcrypt.info
doc/gcrypt.info-1 [deleted file]
doc/gcrypt.info-2 [deleted file]
doc/gcrypt.texi
doc/libgcrypt-modules.eps
doc/libgcrypt-modules.pdf
doc/libgcrypt-modules.png
doc/stamp-vti
doc/version.texi
doc/yat2m.c
m4/Makefile.am
m4/Makefile.in
m4/gpg-error.m4
m4/lock.m4 [deleted file]
m4/threadlib.m4 [deleted file]
mpi/Makefile.am
mpi/Makefile.in
mpi/Manifest [deleted file]
mpi/amd64/distfiles
mpi/amd64/func_abi.h [new file with mode: 0644]
mpi/amd64/mpih-add1.S
mpi/amd64/mpih-lshift.S
mpi/amd64/mpih-mul1.S
mpi/amd64/mpih-mul2.S
mpi/amd64/mpih-mul3.S
mpi/amd64/mpih-rshift.S
mpi/amd64/mpih-sub1.S
mpi/config.links
mpi/ec.c
mpi/generic/Manifest [deleted file]
mpi/generic/distfiles
mpi/i386/Manifest [deleted file]
mpi/i386/distfiles
mpi/i586/Manifest [deleted file]
mpi/i586/distfiles
mpi/longlong.h
mpi/m68k/Manifest [deleted file]
mpi/m68k/distfiles
mpi/m68k/mc68020/Manifest [deleted file]
mpi/m68k/mc68020/distfiles
mpi/mips3/Manifest [deleted file]
mpi/mips3/distfiles
mpi/mpi-pow.c
mpi/mpicoder.c
mpi/mpiutil.c
mpi/pa7100/Manifest [deleted file]
mpi/pa7100/distfiles
mpi/power/Manifest [deleted file]
mpi/power/distfiles
mpi/powerpc32/Manifest [deleted file]
mpi/powerpc32/distfiles
mpi/sparc32/Manifest [deleted file]
mpi/sparc32/distfiles
mpi/sparc32v8/Manifest [deleted file]
mpi/sparc32v8/distfiles
mpi/supersparc/Manifest [deleted file]
mpi/supersparc/distfiles
random/Makefile.am
random/Makefile.in
random/rand-internal.h
random/random-csprng.c
random/random-daemon.c
random/random-drbg.c [new file with mode: 0644]
random/random-fips.c [deleted file]
random/random-system.c
random/random.c
random/random.h
random/rndegd.c
random/rndhw.c
random/rndlinux.c
random/rndunix.c
random/rndw32.c
src/Makefile.am
src/Makefile.in
src/Manifest [deleted file]
src/ath.c [deleted file]
src/ath.h [deleted file]
src/cipher-proto.h
src/cipher.h
src/context.c
src/ec-context.h
src/fips.c
src/g10lib.h
src/gcrypt-int.h
src/gcrypt-testapi.h [new file with mode: 0644]
src/gcrypt.h [deleted file]
src/gcrypt.h.in
src/global.c
src/hmac256.c
src/hwf-arm.c
src/hwf-x86.c
src/hwfeatures.c
src/libgcrypt.def
src/libgcrypt.m4
src/libgcrypt.vers
src/misc.c
src/mpi.h
src/mpicalc.c
src/secmem.c
src/sexp.c
src/types.h
src/versioninfo.rc.in
src/visibility.c
src/visibility.h
tests/Makefile.am
tests/Makefile.in
tests/basic.c
tests/bench-slope.c
tests/benchmark.c
tests/curves.c
tests/fips186-dsa.c
tests/fipsdrv.c
tests/gchash.c [new file with mode: 0644]
tests/hashtest.c
tests/keygen.c
tests/keygrip.c
tests/mpitests.c
tests/pubkey.c
tests/random.c
tests/sha3-224.h [new file with mode: 0644]
tests/sha3-256.h [new file with mode: 0644]
tests/sha3-384.h [new file with mode: 0644]
tests/sha3-512.h [new file with mode: 0644]
tests/stopwatch.h
tests/t-common.h
tests/t-cv25519.c [new file with mode: 0644]
tests/t-ed25519.c
tests/t-kdf.c
tests/t-lock.c
tests/t-mpi-point.c
tests/t-sexp.c [moved from tests/tsexp.c with 89% similarity]

diff --git a/AUTHORS b/AUTHORS
index 7c3c671..25de16c 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,11 +1,15 @@
 Library: Libgcrypt
-Homepage: http://www.gnu.org/software/libgcrypt/
+Homepage: https://www.gnupg.org/related_software/libgcrypt/
+Download: https://ftp.gnupg.org/ftp/gcrypt/libgcrypt/
+          ftp://ftp.gnupg.org/gcrypt/libgcrypt/
+Repository: git://git.gnupg.org/libgcrypt.git
 Maintainer: Werner Koch <wk@gnupg.org>
-Bug reports: http://bugs.gnupg.org
+Bug reports: https://bugs.gnupg.org
 Security related bug reports: <security@gnupg.org>
 License (library): LGPLv2.1+
 License (manual and tools): GPLv2+
 
+
 Libgcrypt is free software.  See the files COPYING.LIB and COPYING for
 copying conditions, and LICENSES for notices about a few contributions
 that require these additional notices to be distributed.  License
@@ -17,7 +21,7 @@ year that would otherwise be listed individually.
 List of Copyright holders
 =========================
 
-  Copyright (C) 1989,1991-2012 Free Software Foundation, Inc.
+  Copyright (C) 1989,1991-2016 Free Software Foundation, Inc.
   Copyright (C) 1994 X Consortium
   Copyright (C) 1996 L. Peter Deutsch
   Copyright (C) 1997 Werner Koch
@@ -26,12 +30,13 @@ List of Copyright holders
   Copyright (C) 1996-2006 Peter Gutmann, Matt Thomlinson and Blake Coverett
   Copyright (C) 2003 Nikos Mavroyanopoulos
   Copyright (C) 2006-2007 NTT (Nippon Telegraph and Telephone Corporation)
-  Copyright (C) 2012-2014 g10 Code GmbH
+  Copyright (C) 2012-2016 g10 Code GmbH
   Copyright (C) 2012 Simon Josefsson, Niels Möller
   Copyright (c) 2012 Intel Corporation
   Copyright (C) 2013 Christian Grothoff
-  Copyright (C) 2013-2014 Jussi Kivilinna
+  Copyright (C) 2013-2016 Jussi Kivilinna
   Copyright (C) 2013-2014 Dmitry Eremin-Solenikov
+  Copyright (C) 2014 Stephan Mueller
 
 
 Authors with a FSF copyright assignment
@@ -136,6 +141,9 @@ phcoder@gmail.com
 Authors with a DCO
 ==================
 
+Andrei Scherer <andsch@inbox.com>
+2014-08-22:BF7CEF794F9.000003F0andsch@inbox.com:
+
 Christian Aistleitner <christian@quelltextlich.at>
 2013-02-26:20130226110144.GA12678@quelltextlich.at:
 
@@ -148,21 +156,39 @@ Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
 Dmitry Kasatkin <dmitry.kasatkin@intel.com>
 2012-12-14:50CAE2DB.80302@intel.com:
 
+Jérémie Courrèges-Anglas <jca@wxcvbn.org>
+2016-05-26:87bn3ssqg0.fsf@ritchie.wxcvbn.org:
+
 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
 2012-11-15:20121115172331.150537dzb5i6jmy8@www.dalek.fi:
 
 Jussi Kivilinna <jussi.kivilinna@iki.fi>
 2013-05-06:5186720A.4090101@iki.fi:
 
+Markus Teich <markus dot teich at stusta dot mhn dot de>
+2014-10-08:20141008180509.GA2770@trolle:
+
+Milan Broz <gmazyland@gmail.com>
+2014-01-13:52D44CC6.4050707@gmail.com:
+
+Peter Wu <peter@lekensteyn.nl>
+2015-07-22:20150722191325.GA8113@al:
+
 Rafaël Carré <funman@videolan.org>
 2012-04-20:4F91988B.1080502@videolan.org:
 
 Sergey V. <sftp.mtuci@gmail.com>
 2013-11-07:2066221.5IYa7Yq760@darkstar:
 
+Stephan Mueller <smueller@chronox.de>
+2014-08-22:2008899.25OeoelVVA@myon.chronox.de:
+
 Tomáš Mráz <tm@t8m.info>
 2012-04-16:1334571250.5056.52.camel@vespa.frost.loc:
 
+Vitezslav Cizek <vcizek@suse.com>
+2015-11-05:20151105131424.GA32700@kolac.suse.cz:
+
 Werner Koch <wk@gnupg.org> (g10 Code GmbH)
 2012-12-05:87obi8u4h2.fsf@vigenere.g10code.de:
 
@@ -173,10 +199,6 @@ More credits
 Libgcrypt used to be part of GnuPG but has been taken out into its own
 package on 2000-12-21.
 
-The ATH implementation (src/ath*) has been taken from GPGME and
-relicensed to the LGPL by the copyright holder of GPGME (g10 Code
-GmbH); it is now considered to be a part of Libgcrypt.
-
 Most of the stuff in mpi has been taken from an old GMP library
 version by Torbjorn Granlund <tege@noisy.tmg.se>.
 
index 62ccbab..574d97d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
-2014-08-21  Werner Koch  <wk@gnupg.org>
+2016-06-15  Werner Koch  <wk@gnupg.org>
+
+       Release 1.7.1.
+
+       doc: Describe envvars.
+       * doc/gcrypt.texi: Add chapter Configuration.
+
+       random: Change names of debug envvars.
+       * random/rndunix.c (start_gatherer): Change GNUPG_RNDUNIX_DBG to
+       GCRYPT_RNDUNIX_DBG, change GNUPG_RNDUNIX_DBG to GCRYPT_RNDUNIX_DBG.
+       * random/rndw32.c (registry_poll): Change GNUPG_RNDW32_NOPERF to
+       GCRYPT_RNDW32_NOPERF.
+
+2016-06-14  Werner Koch  <wk@gnupg.org>
+
+       cipher: Assign OIDs to the Serpent cipher.
+       * cipher/serpent.c (serpent128_oids, serpent192_oids)
+       (serpent256_oids): New. Add them to the specs blow.
+       (serpent128_aliases): Add "SERPENT-128".
+       (serpent256_aliases, serpent192_aliases): New.
+
+       cipher: Assign OIDs to the Serpent cipher.
+       * cipher/serpent.c (serpent128_oids, serpent192_oids)
+       (serpent256_oids): New. Add them to the specs blow.
+       (serpent128_aliases): Add "SERPENT-128".
+       (serpent256_aliases, serpent192_aliases): New.
+
+2016-06-08  Werner Koch  <wk@gnupg.org>
+
+       rsa: Implement blinding also for signing.
+       * cipher/rsa.c (rsa_decrypt): Factor blinding code out to ...
+       (secret_blinded): new.
+       (rsa_sign): Use blinding by default.
+
+       random: Remove debug output for getrandom(2) output.
+       * random/rndlinux.c (_gcry_rndlinux_gather_random): Remove debug
+       output.
+
+       Fix gcc portability on Solaris 9 SPARC boxes.
+       * mpi/longlong.h: Use __sparcv8 as alias for __sparc_v8__.
+
+2016-06-08  Jérémie Courrèges-Anglas  <jca@wxcvbn.org>
+
+       Check for compiler SSE4.1 support in PCLMUL CRC code.
+       * cipher/crc-intel-pclmul.c: Build PCLMUL CRC implementation only if
+         compiler supports PCLMUL *and* SSE4.1
+       * cipher/crc.c: Ditto
+       * configure.ac (sse41support, gcry_cv_gcc_inline_asm_sse41): New.
+
+2016-06-08  NIIBE Yutaka  <gniibe@fsij.org>
+
+       ecc: Fix ecc_verify for cofactor support.
+       * cipher/ecc.c (ecc_verify): Fix the argument for cofactor "h".
+
+2016-06-08  Werner Koch  <wk@gnupg.org>
+
+       random: Try to use getrandom() instead of /dev/urandom (Linux only).
+       * configure.ac: Check for syscall.
+       * random/rndlinux.c [HAVE_SYSCALL]: Include sys/syscall.h.
+       (_gcry_rndlinux_gather_random): Use getrandom is available.
+
+2016-06-03  Werner Koch  <wk@gnupg.org>
+
+       rsa: Implement blinding also for signing.
+       * cipher/rsa.c (rsa_decrypt): Factor blinding code out to ...
+       (secret_blinded): new.
+       (rsa_sign): Use blinding by default.
+
+       random: Remove debug output for getrandom(2) output.
+       * random/rndlinux.c (_gcry_rndlinux_gather_random): Remove debug
+       output.
+
+2016-06-02  Werner Koch  <wk@gnupg.org>
+
+       Fix gcc portability on Solaris 9 SPARC boxes.
+       * mpi/longlong.h: Use __sparcv8 as alias for __sparc_v8__.
+
+2016-05-28  Jérémie Courrèges-Anglas  <jca@wxcvbn.org>
+
+       Check for compiler SSE4.1 support in PCLMUL CRC code.
+       * cipher/crc-intel-pclmul.c: Build PCLMUL CRC implementation only if
+         compiler supports PCLMUL *and* SSE4.1
+       * cipher/crc.c: Ditto
+       * configure.ac (sse41support, gcry_cv_gcc_inline_asm_sse41): New.
+
+2016-05-06  NIIBE Yutaka  <gniibe@fsij.org>
+
+       ecc: Fix ecc_verify for cofactor support.
+       * cipher/ecc.c (ecc_verify): Fix the argument for cofactor "h".
+
+2016-04-26  Werner Koch  <wk@gnupg.org>
+
+       random: Try to use getrandom() instead of /dev/urandom (Linux only).
+       * configure.ac: Check for syscall.
+       * random/rndlinux.c [HAVE_SYSCALL]: Include sys/syscall.h.
+       (_gcry_rndlinux_gather_random): Use getrandom is available.
+
+2016-04-19  Werner Koch  <wk@gnupg.org>
+
+       asm fix for older gcc versions.
+       * cipher/crc-intel-pclmul.c: Remove extra trailing colon from
+       asm statements.
+
+       asm fix for older gcc versions.
+       * cipher/crc-intel-pclmul.c: Remove extra trailing colon from
+       asm statements.
+
+2016-04-15  Werner Koch  <wk@gnupg.org>
+
+       Release 1.7.0.
+
+2016-04-14  Werner Koch  <wk@gnupg.org>
+
+       tests: Add test vectors for 256 GiB test of SHA3-256.
+       * tests/hashtest.c: Add new test vectros.
+
+2016-04-14  Justus Winter  <justus@g10code.com>
+
+       src: Improve S-expression parsing.
+       * src/sexp.c (do_vsexp_sscan): Return an error if a closing
+       parenthesis is encountered with no matching opening parenthesis.
+
+2016-04-14  Werner Koch  <wk@gnupg.org>
 
-       Release 1.6.2.
-       * configure.ac: Set LT version to C20/A0/R2.
+       cipher: Add constant for 8 bit CFB mode.
+       * src/gcrypt.h.in (GCRY_CIPHER_MODE_CFB8): New.
+       * tests/basic.c (check_cfb_cipher): Prepare for CFB-8 tests.
+
+       tests: Add a new test for S-expressions.
+       * tests/t-sexp.c (compare_to_canon): New.
+       (back_and_forth_one): Add another test.
+
+2016-04-13  NIIBE Yutaka  <gniibe@fsij.org>
+
+       ecc: Fix corner cases for X25519.
+       * cipher/ecc.c (ecc_encrypt_raw): For invalid input, returns
+       GPG_ERR_INV_DATA instead of aborting with log_fatal.  For X25519,
+       it's not an error, thus, let it return 0.
+       (ecc_decrypt_raw): Use the flag PUBKEY_FLAG_DJB_TWEAK to distinguish
+       X25519, not by the name of the curve.
+       (ecc_decrypt_raw): For invalid input, returns GPG_ERR_INV_DATA instead
+       of aborting with log_fatal.  For X25519, it's not an error by its
+       definition, but we deliberately let it return the error to detect
+       looks-like-encrypted-message.
+       * tests/t-cv25519.c: Add points to record the issue.
+
+2016-04-12  Werner Koch  <wk@gnupg.org>
+
+       cipher: Buffer data from gcry_cipher_authenticate in OCB mode.
+       * cipher/cipher-internal.h (gcry_cipher_handle): Add fields
+       aad_leftover and aad_nleftover to u_mode.ocb.
+       * cipher/cipher-ocb.c (_gcry_cipher_ocb_set_nonce): Clear
+       aad_nleftover.
+       (_gcry_cipher_ocb_authenticate): Add buffering and facor some code out
+       to ...
+       (ocb_aad_finalize): new.
+       (compute_tag_if_needed): Call new function.
+       * tests/basic.c (check_ocb_cipher_splitaad): New.
+       (check_ocb_cipher): Call new function.
+       (main): Also call check_cipher_modes with --ciper-modes.
+
+2016-04-12  NIIBE Yutaka  <gniibe@fsij.org>
+
+       ecc: Fix X25519 computation on Curve25519.
+       * cipher/ecc.c (ecc_encrypt_raw): Tweak of bits when
+       PUBKEY_FLAG_DJB_TWEAK is enabled.
+       (ecc_decrypt_raw): Return 0 when PUBKEY_FLAG_DJB_TWEAK is enabled.
+       * tests/t-cv25519.c (test_cv): Update by using gcry_pk_encrypt.
+
+       ecc: Fix initialization of EC context.
+       * cipher/ecc.c (test_ecdh_only_keys, ecc_generate)
+       (ecc_check_secret_key, ecc_encrypt_raw, ecc_decrypt_raw): Initialize
+       by _gcry_mpi_ec_p_internal_new should carry FLAGS.
+
+2016-04-06  Werner Koch  <wk@gnupg.org>
+
+       Allow building with configure option --enable-hmac-binary-check.
+       * src/Makefile.am (mpicalc_LDADD): Add DL_LIBS.
+       * src/fips.c (check_binary_integrity): Allow use of hmac256 output.
+       * src/hmac256.c (main): Add option --stdkey
+
+2016-04-06  NIIBE Yutaka  <gniibe@fsij.org>
+
+       ecc: Positive values in computation.
+       * cipher/ecc-curves.c (_gcry_ecc_fill_in_curve): Make sure
+       coefficients A and B are positive.
+       * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_recover_x): For negation, do
+       "P - T" instead of "-T", so that the result will be positive.
+       (_gcry_ecc_eddsa_verify): Likewise.
+       * cipher/ecc.c (ecc_check_secret_key): Use _gcry_ecc_fill_in_curve
+       instead of _gcry_ecc_update_curve_param.
+       * mpi/ec.c (ec_subm): Make sure the result will be positive.
+       (dup_point_edwards, sub_points_edwards, _gcry_mpi_ec_curve_point): Use
+       mpi_sub instead of mpi_neg.
+       (add_points_edwards): Simply use ec_addm.
+       * tests/t-mpi-point.c (test_curve): Define curves with positive
+       coefficients.
+
+2016-04-01  Werner Koch  <wk@gnupg.org>
+
+       mpi: Explicitly limit the allowed input length for gcry_mpi_scan.
+       * mpi/mpicoder.c (MAX_EXTERN_SCAN_BYTES): New.
+       (mpi_fromstr): Check against this limit.
+       (_gcry_mpi_scan): Ditto.
+       * tests/mpitests.c (test_maxsize): New.
+       (main): Cal that test.
+
+2016-03-31  Werner Koch  <wk@gnupg.org>
+
+       cipher: Remove specialized rmd160 functions.
+       * cipher/rmd160.c: Replace rmd.h by hash-common.h.
+       (RMD160_CONTEXT): Move from rmd.h to here.
+       (_gcry_rmd160_init): Remove.
+       (_gcry_rmd160_mixblock): Remove.
+       (_gcry_rmd160_hash_buffer): Use rmd160_init directly.
+       * cipher/md.c: Remove rmd.h which was not actually used.
+       * cipher/rmd.h: Remove.
+       * cipher/Makefile.am (libcipher_la_SOURCES): Remove rmd.h.
+       * configure.ac (USE_RMD160): Allow to build without RMD160.
+
+       random: Replace RMD160 by SHA-1 for mixing the CSPRNG pool.
+       * cipher/sha1.c (_gcry_sha1_mixblock_init): New.
+       (_gcry_sha1_mixblock): New.
+       * random/random-csprng.c: Include sha1.h instead of rmd.h.
+       (mix_pool): Use SHA-1 instead of RIPE-MD-160 for mixing.
+
+       cipher: Move sha1 context definition to a separate file.
+       * cipher/sha1.c: Replace hash-common.h by sha1.h.
+       (SHA1_CONTEXT): Move to ...
+       * cipher/sha1.h: new.  Always include all flags.
+       * cipher/Makefile.am (libcipher_la_SOURCES): Add sha1.h.
+
+2016-03-29  Werner Koch  <wk@gnupg.org>
+
+       tests: Fix buffer overflow in bench-slope.
+       * tests/bench-slope.c (bench_print_result_std): Remove wrong use of
+       strncat.
+
+2016-03-27  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       cipher: GCM: check that length of supplied tag is one of valid lengths.
+       * cipher/cipher-gcm.c (is_tag_length_valid): New.
+       (_gcry_cipher_gcm_tag): Check that 'outbuflen' has valid tag length.
+       * tests/basic.c (_check_gcm_cipher): Add test-vectors with different
+       valid tag lengths and negative test vectors with invalid lengths.
+
+2016-03-24  Peter Wu  <peter@lekensteyn.nl>
+
+       cipher: Fix memleaks in (self)tests.
+       * cipher/dsa.c: Release memory for MPI and sexp structures.
+       * cipher/ecc.c: Release memory for sexp structure.
+       * tests/keygen.c: Likewise.
+
+       Mark constant MPIs as non-leaked.
+       * mpi/mpiutil.c: Mark "constant" MPIs as explicitly leaked.
+
+2016-03-23  Werner Koch  <wk@gnupg.org>
+
+       Add new control GCRYCTL_GET_TAGLEN for use with gcry_cipher_info.
+       * src/gcrypt.h.in (GCRYCTL_GET_TAGLEN): New.
+       * cipher/cipher.c (_gcry_cipher_info): Add GCRYCTL_GET_TAGLEN feature.
+
+       * tests/basic.c (_check_gcm_cipher): Check that new feature.
+       (_check_poly1305_cipher): Ditto.
+       (check_ccm_cipher): Ditto.
+       (do_check_ocb_cipher): Ditto.
+       (check_ctr_cipher): Add negative test for new feature.
+
+       cipher: Avoid NULL-segv in GCM mode if a key has not been set.
+       * cipher/cipher-gcm.c (_gcry_cipher_gcm_encrypt): Check that GHASH_FN
+       has been initialized.
+       (_gcry_cipher_gcm_decrypt): Ditto.
+       (_gcry_cipher_gcm_authenticate): Ditto.
+       (_gcry_cipher_gcm_initiv): Ditto.
+       (_gcry_cipher_gcm_tag): Ditto.
+
+       cipher: Check length of supplied tag in _gcry_cipher_poly1305_check_tag.
+       * cipher/cipher-poly1305.c (_gcry_cipher_poly1305_tag): Check that the
+       provided tag length matches the actual tag length.
+
+2016-03-23  Peter Wu  <peter@lekensteyn.nl>
+
+       Fix buffer overrun in gettag for Poly1305.
+       * cipher/cipher-poly1305.c: copy a fixed length instead of the
+         user-supplied number.
+
+2016-03-23  Werner Koch  <wk@gnupg.org>
+
+       cipher: Check length of supplied tag in _gcry_cipher_gcm_check_tag.
+       * cipher/cipher-gcm.c (_gcry_cipher_gcm_tag): Check that the provided
+       tag length matches the actual tag length.  Avoid gratuitous return
+       statements.
+
+2016-03-23  Peter Wu  <peter@lekensteyn.nl>
+
+       Fix buffer overrun in gettag for GCM.
+       * cipher/cipher-gcm.c: copy a fixed length instead of the user-supplied
+         number.
+
+2016-03-22  Werner Koch  <wk@gnupg.org>
+
+       tests: Add options --fips to keygen for manual tests.
+       (main): Add option --fips.
+       * tests/keygen.c (check_rsa_keys): Create an 2048 bit key with e=65539
+       because that is valid in FIPS mode.  Check that key generation fails
+       for too short keys in FIPS mode.
+       (check_ecc_keys): Check that key generation fails for Ed25519 keys in
+       FIPS mode.
+
+2016-03-22  Tomáš Mráz  <tmraz@redhat.com>
+
+       rsa: Add FIPS 186-4 compliant RSA probable prime key generator.
+       * cipher/primegen.c (_gcry_fips186_4_prime_check): New.
+       * cipher/rsa.c (generate_fips): New.
+       (rsa_generate): Use new function in fips mode or with test-parms.
+
+       * tests/keygen.c (check_rsa_keys): Add test using e=65539.
+
+2016-03-20  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Fix ARM NEON support detection on ARMv6 target.
+       * configure.ac (gcry_cv_gcc_inline_asm_neon): Use '.arm' directive
+       instead of '.thumb'.
+
+2016-03-18  Werner Koch  <wk@gnupg.org>
+
+       Always require a 64 bit integer type.
+       * configure.ac (available_digests_64): Merge with available_digests.
+       (available_kdfs_64): Merge with available_kdfs.
+       <64 bit datatype test>: Bail out if no such type is available.
+       * src/types.h: Emit #error if no u64 can be defined.
+       (PROPERLY_ALIGNED_TYPE): Always add u64 type.
+       * cipher/bithelp.h: Remove all code paths which handle the
+       case of !HAVE_U64_TYPEDEF.
+       * cipher/bufhelp.h: Ditto.
+       * cipher/cipher-ccm.c: Ditto.
+       * cipher/cipher-gcm.c: Ditto.
+       * cipher/cipher-internal.h: Ditto.
+       * cipher/cipher.c: Ditto.
+       * cipher/hash-common.h: Ditto.
+       * cipher/md.c: Ditto.
+       * cipher/poly1305.c: Ditto.
+       * cipher/scrypt.c: Ditto.
+       * cipher/tiger.c: Ditto.
+       * src/g10lib.h: Ditto.
+       * tests/basic.c: Ditto.
+       * tests/bench-slope.c: Ditto.
+       * tests/benchmark.c: Ditto.
+
+2016-03-18  Vitezslav Cizek  <vcizek@suse.com>
+
+       tests: Fix testsuite after the FIPS adjustments.
+       * tests/benchmark.c (ecc_bench): Avoid not approved curves in FIPS.
+       * tests/curves.c (check_get_params): Skip Brainpool curves in FIPS.
+       * tests/keygen.c (check_dsa_keys): Generate 2048 and 3072 bits keys.
+       (check_ecc_keys): Skip Ed25519 in FIPS mode.
+       * tests/random.c (main): Don't switch DRBG in FIPS mode.
+       * tests/t-ed25519.c (main): Ed25519 isn't supported in FIPS mode.
+       * tests/t-kdf.c (check_openpgp): Skip vectors using md5 in FIPS.
+       * tests/t-mpi-point.c (context_param): Skip P-192 and Ed25519 in FIPS.
+       (main): Skip math tests that use P-192 and Ed25519 in FIPS.
+
+       tests: Add new --pss option to fipsdrv.
+       * tests/fipsdrv.c (run_rsa_sign, run_rsa_verify): Set salt-length
+       to 0 for PSS.
+
+       cipher: Add option to specify salt length for PSS verification.
+       * cipher/pubkey-util.c (_gcry_pk_util_data_to_mpi): Check for
+       salt-length token.
+
+       tests: Add support for RSA keygen tests to fipsdrv.
+       * tests/fipsdrv.c (run_rsa_keygen): New.
+       (main): Support RSA keygen and RSA keygen KAT tests.
+
+       tests: Fixes for RSA testsuite in FIPS mode.
+       * tests/basic.c (get_keys_new): Generate 2048 bit key.
+       * tests/benchmark.c (rsa_bench): Skip keys of lengths different
+       than 2048 and 3072 in FIPS mode.
+       * tests/keygen.c (check_rsa_keys): Failure if short keys can be
+       generated in FIPS mode.
+       (check_dsa_keys): Ditto for DSA keys.
+       * tests/pubkey.c (check_x931_derived_key): Skip keys < 2048 in FIPS.
+
+       rsa: Use 2048 bit RSA keys for selftest.
+       * cipher/rsa.c (selftests_rsa): Use 2048 bit keys.
+       (selftest_encr_1024): Replaced by selftest_encr_2048.
+       (selftest_sign_1024): Replaced by selftest_sign_2048.
+       (selftest_encr_2048): Add check against known ciphertext.
+       (selftest_sign_2048): Add check against known signature.
+       (selftest_sign_2048): Free SIG_MPI.
+       * tests/pubkey.c (get_keys_new): Generate 2048 bit keys.
+
+       Disable non-allowed algorithms in FIPS mode.
+       * cipher/cipher.c (_gcry_cipher_init),
+       * cipher/mac.c (_gcry_mac_init),
+       * cipher/md.c (_gcry_md_init),
+       * cipher/pubkey.c (_gcry_pk_init): In the FIPS mode, disable all the
+       non-allowed ciphers.
+       * cipher/md5.c: Mark MD5 as not allowed in FIPS.
+       * src/g10lib.h (_gcry_mac_init): New.
+       * src/global.c (global_init): Call the new _gcry_mac_init.
+       * tests/basic.c (check_ciphers): Fix a typo.
+
+2016-03-18  Werner Koch  <wk@gnupg.org>
+
+       kdf: Make PBKDF2 check work on all platforms.
+       * cipher/kdf.c (_gcry_kdf_pkdf2): Chnage DKLEN to unsigned long.
+
+2016-03-18  Vitezslav Cizek  <vcizek@suse.com>
+
+       kdf: Add upper bound for derived key length in PBKDF2.
+       * cipher/kdf.c (_gcry_kdf_pkdf2): limit dkLen.
+
+       ecc: ECDSA adjustments for FIPS 186-4.
+       * cipher/ecc-curves.c: Unmark curve P-192 for FIPS.
+       * cipher/ecc.c: Add ECDSA self test.
+       * cipher/pubkey-util.c (_gcry_pk_util_init_encoding_ctx): Use SHA-2
+       in FIPS mode.
+       * tests/fipsdrv.c: Add support for ECDSA signatures.
+
+2016-03-18  Werner Koch  <wk@gnupg.org>
+
+       dsa: Make regression tests work.
+       * cipher/dsa.c (sample_secret_key_1024): Comment out unused constant.
+       (ogenerate_fips186): Make it work with use-fips183-2 flag.
+       * cipher/primegen.c (_gcry_generate_fips186_3_prime): Use Emacs
+       standard comment out format.
+       * tests/fips186-dsa.c (check_dsa_gen_186_3): New dummy fucntion.
+       (main): Call it.
+       (main): Compare against current version.
+       * tests/pubkey.c (get_dsa_key_fips186_new): Create 2048 bit key.
+       (get_dsa_key_fips186_with_seed_new): Ditto.
+       (get_dsa_key_fips186_with_domain_new): Comment out.
+       (check_run): Do not call that function.
+
+2016-03-18  Vitezslav Cizek  <vcizek@suse.com>
+
+       dsa: Adjustments to conform with FIPS 186-4.
+       * cipher/dsa.c (generate_fips186): FIPS 186-4 adjustments.
+       * cipher/primegen.c (_gcry_generate_fips186_3_prime): Fix incorrect
+         buflen passed to _gcry_mpi_scan.
+
+2016-03-16  Justus Winter  <justus@g10code.com>
+
+       Update documentation for 'gcry_sexp_extract_param'.
+       * doc/gcrypt.texi (gcry_sexp_extract_param): Mention that all MIPs
+       must be set to NULL first, and document how the function behaves in
+       case of errors.
+       * src/sexp.c (_gcry_sexp_extract_param): Likewise.
+       * src/gcrypt.h.in (gcry_sexp_extract_param): Copy the comment from
+       '_gcry_sexp_extract_param'.
+
+       cipher: Update comment.
+       * cipher/ecc.c (ecc_get_nbits): Update comment to reflect the fact
+       that a curve parameter can be given.
+
+2016-03-12  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Add Intel PCLMUL implementations of CRC algorithms.
+       * cipher/Makefile.am: Add 'crc-intel-pclmul.c'.
+       * cipher/crc-intel-pclmul.c: New.
+       * cipher/crc.c (USE_INTEL_PCLMUL): New macro.
+       (CRC_CONTEXT) [USE_INTEL_PCLMUL]: Add 'use_pclmul'.
+       [USE_INTEL_PCLMUL] (_gcry_crc32_intel_pclmul)
+       (gcry_crc24rfc2440_intel_pclmul): New.
+       (crc32_init, crc32rfc1510_init, crc24rfc2440_init)
+       [USE_INTEL_PCLMUL]: Select PCLMUL implementation if SSE4.1 and PCLMUL
+       HW features detected.
+       (crc32_write, crc24rfc2440_write) [USE_INTEL_PCLMUL]: Use PCLMUL
+       implementation if enabled.
+       (crc24_init): Document storage format of 24-bit CRC.
+       (crc24_next4): Use only 'data' for last table look-up.
+       * configure.ac: Add 'crc-intel-pclmul.lo'.
+       * src/g10lib.h (HWF_*, HWF_INTEL_SSE4_1): Update HWF flags to include
+       Intel SSE4.1.
+       * src/hwf-x86.c (detect_x86_gnuc): Add SSE4.1 detection.
+       * src/hwfeatures.c (hwflist): Add 'intel-sse4.1'.
+       * tests/basic.c (fillbuf_count): New.
+       (check_one_md): Add "?" check (million byte data-set with byte pattern
+       0x00,0x01,0x02,...); Test all buffer sizes 1 to 1000, for "!" and "?"
+       checks.
+       (check_one_md_multi): Skip "?".
+       (check_digests): Add "?" test-vectors for MD5, SHA1, SHA224, SHA256,
+       SHA384, SHA512, SHA3_224, SHA3_256, SHA3_384, SHA3_512, RIPEMD160,
+       CRC32, CRC32_RFC1510, CRC24_RFC2440, TIGER1 and WHIRLPOOL; Add "!"
+       test-vectors for CRC32_RFC1510 and CRC24_RFC2440.
+
+2016-02-25  NIIBE Yutaka  <gniibe@fsij.org>
+
+       mpi: Normalize EXPO for mpi_powm.
+       * mpi/mpi-pow.c (gcry_mpi_powm): Normalize EP.
+
+2016-02-22  Andreas Metzler  <ametzler@bebt.de>
+
+       Do not ship generated header file in tarball.
+       * src/Makefile.am: Move gcrypt.h from include_HEADERS to
+         nodist_include_HEADERS to prevent inclusion in release tarball.
+         This could break out-of-tree-builds because the potentially outdated
+         src/gcrypt.h was not updated but was in the compiler search path.
+
+2016-02-20  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Fix building random-drbg for Win32/64.
+       * random/random-drbg.c: Remove include for sys/types.h and asm/types.h.
+       (DRBG_PREDICTION_RESIST, DRBG_CTRAES, DRBG_CTRSERPENT, DRBG_CTRTWOFISH)
+       (DRBG_HASHSHA1, DRBG_HASHSHA224, DRBG_HASHSHA256, DRBG_HASHSHA384)
+       (DRBG_HASHSHA512, DRBG_HMAC, DRBG_SYM128, DRBG_SYM192)
+       (DRBG_SYM256): Change 'u_int32_t' to 'u32'.
+       (drbg_get_entropy) [USE_RNDUNIX, USE_RNDW32]: Fix parameters
+       'drbg_read_cb' and 'len'.
+
+2016-02-20  Werner Koch  <wk@gnupg.org>
+
+       tests: Do not test DRBG_REINIT from "make check"
+       * tests/random.c (main): Run check_drbg_reinit only if the envvar
+       GCRYPT_IN_REGRESSION_TEST is set.
+
+       doc: Fix possible dependency problem.
+       * doc/Makefile.am (gcrypt.texi): Use the right traget.
+
+2016-02-19  Stephan Mueller  <smueller@chronox.de>
+
+       random: Remove ANSI X9.31 DRNG.
+       * random-fips.c: Remove.
+
+2016-02-19  Werner Koch  <wk@gnupg.org>
+
+       random: Add a test case for DRBG_REINIT.
+       * src/global.c (_gcry_vcontrol) <DRBG_REINIT>: Test for FIPS RNG.
+       * tests/random.c (check_drbg_reinit): New.
+       (main): Call new test.
+
+       random: Allow DRBG_REINIT before initialization.
+       * random/random-drbg.c (DRBG_DEFAULT_TYPE): New.
+       (_drbg_init_internal): Set the default type if no type has been set
+       before.
+       (_gcry_rngdrbg_inititialize): Pass 0 for flags to use the default.
+
+       Add new private header gcrypt-testapi.h.
+       * src/gcrypt-testapi.h: New.
+       * src/Makefile.am (libgcrypt_la_SOURCES): Add new file.
+       * random/random.h: Include gcrypt-testapi.h.
+       (struct gcry_drbg_test_vector) : Move to gcrypt-testapi.h.
+       * src/global.c: Include gcrypt-testapi.h.
+       (_gcry_vcontrol): Use PRIV_CTL_* constants instead of 58, 59, 60, 61.
+       * cipher/cipher.c: Include gcrypt-testapi.h.
+       (_gcry_cipher_ctl): Use PRIV_CIPHERCTL_ constants instead of 61, 62.
+       * tests/fipsdrv.c: Include gcrypt-testapi.h.  Remove definition of
+       PRIV_CTL_ constants and replace their use by the new PRIV_CIPHERCTL_
+       constants.
+       * tests/t-lock.c: Include gcrypt-testapi.h.  Remove
+       PRIV_CTL_EXTERNAL_LOCK_TEST and EXTERNAL_LOCK_TEST_ constants.
+
+       * random/random-drbg.c (gcry_rngdrbg_cavs_test): Rename to ...
+       (_gcry_rngdrbg_cavs_test): this.
+       (gcry_rngdrbg_healthcheck_one): Rename to ...
+       (_gcry_rngdrbg_healthcheck_one): this.
+
+       random: Make the DRBG C-90 clean and use a flag string.
+       * random/random.h (struct gcry_drbg_test_vector): Rename "flags" to
+       "flagstr" and turn it into a string.
+       * random/random-drbg.c (drbg_test_pr, drbg_test_nopr): Replace use of
+       designated initializers.  Use a string for the flags.
+       (gcry_rngdrbg_cavs_test): Parse the flag string into a flag value.
+       (drbg_healthcheck_sanity): Ditto.
+
+       random: Symbol name cleanup for random-drbg.c.
+       * random/random-drbg.c: Rename all static objects and macros from
+       "gcry_drbg" to "drbg".
+       (drbg_string_t): New typedef.
+       (drbg_gen_t): New typedef.
+       (drbg_state_t): New typedef.  Replace all "struct drbg_state_s *" by
+       this.
+       (_drbg_init_internal): Replace xcalloc_secure by xtrycalloc_secure so
+       that an error if actually returned.
+       (gcry_rngdrbg_cavs_test): Ditto.
+       (gcry_drbg_healthcheck_sanity): Ditto.
+
+       random: Use our symbol name pattern also for drbg functions.
+       * random/random-drbg.c: Rename global functions from _gcry_drbg_*
+       to _gcry_rngdrbg_*.
+       * random/random.c: Adjust for this change.
+       * src/global.c: Ditto.
+
+       random: Rename drbg.c to random-drbg.c.
+       * random/drbg.c: Rename to ...
+       * random/random-drbg.c: this.
+       * random/Makefile.am (librandom_la_SOURCES): Adjust accordingly.
+
+       random: Remove the new API introduced by the new DRBG.
+       * src/gcrypt.h.in (struct gcry_drbg_gen): Move to random/drbg.c.
+       (struct gcry_drbg_string): Ditto.
+       (gcry_drbg_string_fill): Ditto.
+       (gcry_randomize_drbg): Remove.
+       * random/drbg.c (parse_flag_string): New.
+       (_gcry_drbg_reinit): Change the way the arguments are passed.
+       * src/global.c (_gcry_vcontrol) <GCRYCTL_DRBG_REINIT>: Change calling
+       convention.
+
+       Add helper function _gcry_strtokenize.
+       * src/misc.c (_gcry_strtokenize): New.
+
+2016-02-18  Werner Koch  <wk@gnupg.org>
+
+       random: Remove DRBG constants from the public API.
+       * src/gcrypt.h.in (GCRY_DRBG_): Remove all new flags to ...
+       * random/drbg.c: here.
+
+2016-02-18  Stephan Mueller  <smueller@chronox.de>
+
+       random: Add SP800-90A DRBG.
+       * random/drbg.c: New.
+       * random/random.c (_gcry_random_initialize): Replace rngfips init by
+       drbg init.
+       (__gcry_random_close_fds): Likewise.
+       (_gcry_random_dump_stats): Likewise.
+       (_gcry_random_is_faked): Likewise.
+       (do_randomize): Likewise.
+       (_gcry_random_selftest): Likewise.
+       (_gcry_create_nonce): Replace rngfips_create_noce by drbg_randomize.
+       (_gcry_random_init_external_test): Remove.
+       (_gcry_random_run_external_test): Remove.
+       (_gcry_random_deinit_external_test): Remove.
+       * random/random.h (struct gcry_drbg_test_vector): New.
+       * src/gcrypt.h.in (struct gcry_drbg_gen): New.
+       (struct gcry_drbg_string): New.
+       (gcry_drbg_string_fill): New.
+       (gcry_randomize_drbg): New.
+       (GCRY_DRBG_): Lots of new macros.
+       * src/global.c (_gcry_vcontrol) <Init external random test>: Turn into
+       a nop.
+       (_gcry_vcontrol) <Deinit external random test>: Ditto.
+       (_gcry_vcontrol) <Run external random test>: Change.
+       (_gcry_vcontrol) <GCRYCTL_DRBG_REINIT>: New.
+
+2016-02-13  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       bufhelp: disable unaligned memory accesses on powerpc.
+       * cipher/bufhelp.h (BUFHELP_FAST_UNALIGNED_ACCESS): Disable for
+       __powerpc__ and __powerpc64__.
+
+2016-02-12  NIIBE Yutaka  <gniibe@fsij.org>
+
+       ecc: Not validate input point for Curve25519.
+       * cipher/ecc.c (ecc_decrypt_raw): Curve25519 is an exception.
+
+2016-02-10  NIIBE Yutaka  <gniibe@fsij.org>
+
+       ecc: Fix memory leaks on error.
+       * cipher/ecc.c (ecc_decrypt_raw): Go to leave to release memory.
+       * mpi/ec.c (_gcry_mpi_ec_curve_point): Likewise.
+
+2016-02-09  NIIBE Yutaka  <gniibe@fsij.org>
+
+       ecc: input validation on ECDH.
+       * cipher/ecc.c (ecc_decrypt_raw): Validate the point.
+
+2016-02-08  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Add ARM assembly implementation of SHA-512.
+       * cipher/Makefile.am: Add 'sha512-arm.S'.
+       * cipher/sha512-arm.S: New.
+       * cipher/sha512.c (USE_ARM_ASM): New.
+       (_gcry_sha512_transform_arm): New.
+       (transform) [USE_ARM_ASM]: Use ARM assembly implementation instead of
+       generic.
+       * configure.ac: Add 'sha512-arm.lo'.
+
+2016-02-03  NIIBE Yutaka  <gniibe@fsij.org>
+
+       tests: Add a test for Curve25519.
+       * tests/Makefile.am (tests_bin): Add t-cv25519.
+       * tests/t-cv25519.c: New.
+
+2016-02-02  NIIBE Yutaka  <gniibe@fsij.org>
+
+       ecc: Fix Curve25519 for data by older implementation.
+       * cipher/ecc-misc.c (gcry_ecc_mont_decodepoint): Fix code path for
+       short length data.
+
+       ecc: more fix of Curve25519.
+       * cipher/ecc-misc.c (gcry_ecc_mont_decodepoint): Fix removing of
+       prefix.  Clear the MSB, according to RFC7748.
+
+       ecc: Fix ECDH of Curve25519.
+       * cipher/ecc-misc.c (_gcry_ecc_mont_decodepoint): Fix calc of NBITS
+       and prefix detection.
+       * cipher/ecc.c (ecc_generate): Use NBITS instead of CTX->NBITS.
+       (ecc_encrypt_raw): Use NBITS from curve instead of from P.
+       Fix rawmpilen calculation.
+       (ecc_decrypt_raw): Likewise.  Add debug output.
+
+2016-01-29  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Improve performance of generic SHA256 implementation.
+       * cipher/sha256.c (R): Let caller do variable shuffling.
+       (Chro, Maj, Sum0, Sum1): Convert from inline functions to macros.
+       (W, I): New.
+       (transform_blk): Unroll round loop; inline message expansion to rounds
+       to make message expansion buffer smaller.
+
+2016-01-28  Werner Koch  <wk@gnupg.org>
+
+       ecc: New API function gcry_mpi_ec_decode_point.
+       * mpi/ec.c (_gcry_mpi_ec_decode_point): New.
+       * cipher/ecc-common.h: Move two prototypes to ...
+       * src/ec-context.h: here.
+       * src/gcrypt.h.in (gcry_mpi_ec_decode_point): New.
+       * src/libgcrypt.def (gcry_mpi_ec_decode_point): New.
+       * src/libgcrypt.vers (gcry_mpi_ec_decode_point): New.
+       * src/visibility.c (gcry_mpi_ec_decode_point): New.
+       * src/visibility.h: Add new function.
+
+2016-01-15  Werner Koch  <wk@gnupg.org>
+
+       Fix build problem for rndegd.c.
+       * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Test all RND modules.
+       * random/rndegd.c (_gcry_rndegd_connect_socket)
+       (my_make_filename): Use functions with '_' prefix.
+
+       random: Fix possible AIX problem with sysconf in rndunix.
+       * random/rndunix.c [HAVE_STDINT_H]: Include stdint.h.
+       (start_gatherer): Detect misbehaving sysconf.
+
+2015-12-27  Werner Koch  <wk@gnupg.org>
+
+       random: Take at max 25% from RDRAND.
+       * random/rndlinux.c (_gcry_rndlinux_gather_random): Change use of
+       RDRAND from 50% to 25%.
+
+2015-12-07  Justus Winter  <justus@g10code.com>
+
+       cipher: Improve error handling.
+       * cipher/ecc.c (ecc_decrypt_raw): Improve error handling.
+
+       cipher: Initialize 'flags'.
+       * cipher/ecc.c (ecc_encrypt_raw): Initialize 'flags' to 0.
+
+2015-12-05  NIIBE Yutaka  <gniibe@fsij.org>
+
+       ecc: CHANGE point representation of Curve25519.
+       * cipher/ecc-misc.c (_gcry_ecc_mont_decodepoint): Decode point with
+       the prefix 0x40, additional 0x00 by MPI handling, and shorter octets
+       by MPI normalization.
+       * cipher/ecc.c (ecc_generate, ecc_encrypt_raw, ecc_decrypt_raw):
+       Always add the prefix 0x40.
+
+2015-12-03  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       chacha20: fix alignment of self-test context.
+       * cipher/chacha20.c (selftest): Ensure 16-byte alignment for chacha20
+       context structure.
+
+       salsa20: fix alignment of self-test context.
+       * cipher/salsa20.c (selftest): Ensure 16-byte alignment for salsa20
+       context structure.
+
+2015-12-02  Justus Winter  <justus@g10code.com>
+
+       random: Drop fake entropy gathering function.
+       * random/random-csprng.c (faked_rng): Drop variable.
+       (gather_faked): Drop prototype and function.
+       (initialize): Drop fallback code.
+       (_gcry_rngcsprng_is_faked): Change accordingly.
+
+       random: Fix selection of entropy gathering function.
+       * random/random-csprng.c (getfnc_gather_random): Do return NULL if no
+       usable entropy gathering function is found.  The callsite then
+       installs the fake gather function.
+
+2015-11-26  NIIBE Yutaka  <gniibe@fsij.org>
+
+       ecc: minor improvement of point multiplication.
+       * mpi/ec.c (_gcry_mpi_ec_mul_point): Move ec_subm out of the loop.
+
+2015-11-25  NIIBE Yutaka  <gniibe@fsij.org>
+
+       ecc: Constant-time multiplication for Weierstrass curve.
+       * mpi/ec.c (_gcry_mpi_ec_mul_point): Use simple left-to-right binary
+       method for Weierstrass curve when SCALAR is secure.
+
+       mpi: fix gcry_mpi_swap_cond.
+       * mpi/mpiutil.c (_gcry_mpi_swap_cond): Relax the condition.
+
+       mpi: Fix mpi_set_cond and mpi_swap_cond .
+       * mpi/mpiutil.c (_gcry_mpi_set_cond, _gcry_mpi_swap_cond): Don't use
+       the operator of !!, but assume SET/SWAP is 0 or 1.
+
+       ecc: multiplication of Edwards curve to be constant-time.
+       * mpi/ec.c (_gcry_mpi_ec_mul_point): Use point_swap_cond.
+
+       ecc: Add point_resize and point_swap_cond.
+       * mpi/ec.c (point_resize, point_swap_cond): New.
+       (_gcry_mpi_ec_mul_point): Use point_resize and point_swap_cond.
+
+2015-11-18  Justus Winter  <justus@g10code.com>
+
+       cipher: Fix error handling.
+       * cipher/cipher.c (_gcry_cipher_ctl): Fix error handling.
+
+2015-11-18  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Tweak Keccak for small speed-up.
+       * cipher/keccak_permute_32.h (KECCAK_F1600_PERMUTE_FUNC_NAME): Track
+       rounds with round constant pointer instead of separate round counter.
+       * cipher/keccak_permute_64.h (KECCAK_F1600_PERMUTE_FUNC_NAME): Ditto.
+       (KECCAK_F1600_ABSORB_FUNC_NAME): Tweak lanes pointer increment for bulk
+       absorb loops.
+
+       Update license information for CRC.
+       * LICENSES: Remove 'Simple permissive' and 'IETF permissive' licenses
+       for 'cipher/crc.c' as result of rewrite of CRC implementations.
+
+2015-11-17  Justus Winter  <justus@g10code.com>
+
+       Fix typos found using codespell.
+       * cipher/cipher-ocb.c: Fix typos.
+       * cipher/des.c: Likewise.
+       * cipher/dsa-common.c: Likewise.
+       * cipher/ecc.c: Likewise.
+       * cipher/pubkey.c: Likewise.
+       * cipher/rsa-common.c: Likewise.
+       * cipher/scrypt.c: Likewise.
+       * random/random-csprng.c: Likewise.
+       * random/random-fips.c: Likewise.
+       * random/rndw32.c: Likewise.
+       * src/cipher-proto.h: Likewise.
+       * src/context.c: Likewise.
+       * src/fips.c: Likewise.
+       * src/gcrypt.h.in: Likewise.
+       * src/global.c: Likewise.
+       * src/sexp.c: Likewise.
+       * tests/mpitests.c: Likewise.
+       * tests/t-lock.c: Likewise.
+
+2015-11-01  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Improve performance of Tiger hash algorithms.
+       * cipher/tiger.c (tiger_round, pass, key_schedule): Convert functions
+       to macros.
+       (transform_blk): Pass variable names instead of pointers to 'pass'.
+
+       Add ARMv7/NEON implementation of Keccak.
+       * cipher/Makefile.am: Add 'keccak-armv7-neon.S'.
+       * cipher/keccak-armv7-neon.S: New.
+       * cipher/keccak.c (USE_64BIT_ARM_NEON): New.
+       (NEED_COMMON64): Select if USE_64BIT_ARM_NEON.
+       [NEED_COMMON64] (round_consts_64bit): Rename to...
+       [NEED_COMMON64] (_gcry_keccak_round_consts_64bit): ...this; Add
+       terminator at end.
+       [USE_64BIT_ARM_NEON] (_gcry_keccak_permute_armv7_neon)
+       (_gcry_keccak_absorb_lanes64_armv7_neon, keccak_permute64_armv7_neon)
+       (keccak_absorb_lanes64_armv7_neon, keccak_armv7_neon_64_ops): New.
+       (keccak_init) [USE_64BIT_ARM_NEON]: Select ARM/NEON implementation
+       if supported by HW.
+       * cipher/keccak_permute_64.h (KECCAK_F1600_PERMUTE_FUNC_NAME): Update
+       to use new round constant table.
+       * configure.ac: Add 'keccak-armv7-neon.lo'.
+
+       Optimize Keccak 64-bit absorb functions.
+       * cipher/keccak.c [USE_64BIT] [__x86_64__] (absorb_lanes64_8)
+       (absorb_lanes64_4, absorb_lanes64_2, absorb_lanes64_1): New.
+       * cipher/keccak.c [USE_64BIT] [!__x86_64__] (absorb_lanes64_8)
+       (absorb_lanes64_4, absorb_lanes64_2, absorb_lanes64_1): New.
+       [USE_64BIT] (KECCAK_F1600_ABSORB_FUNC_NAME): New.
+       [USE_64BIT] (keccak_absorb_lanes64): Remove.
+       [USE_64BIT_SHLD] (KECCAK_F1600_ABSORB_FUNC_NAME): New.
+       [USE_64BIT_SHLD] (keccak_absorb_lanes64_shld): Remove.
+       [USE_64BIT_BMI2] (KECCAK_F1600_ABSORB_FUNC_NAME): New.
+       [USE_64BIT_BMI2] (keccak_absorb_lanes64_bmi2): Remove.
+       * cipher/keccak_permute_64.h (KECCAK_F1600_ABSORB_FUNC_NAME): New.
+
+2015-10-31  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Enable CRC test vectors with zero bytes.
+       * tests/basic.c (check_digests): Enable CRC test-vectors with zero
+       bytes.
+
+       Keccak: Add SHAKE Extendable-Output Functions.
+       * src/hash-common.c (_gcry_hash_selftest_check_one): Add handling for
+       XOFs.
+       * src/keccak.c (keccak_ops_t): Rename 'extract_inplace' to 'extract'
+       and add 'pos' argument.
+       (KECCAK_CONTEXT): Add 'suffix'.
+       (keccak_extract_inplace64): Rename to...
+       (keccak_extract64): ...this; Add handling for 'pos' argument.
+       (keccak_extract_inplace32bi): Rename to...
+       (keccak_extract32bi): ...this; Add handling for 'pos' argument.
+       (keccak_extract_inplace64): Rename to...
+       (keccak_extract64): ...this; Add handling for 'pos' argument.
+       (keccak_extract_inplace32bi_bmi2): Rename to...
+       (keccak_extract32bi_bmi2): ...this; Add handling for 'pos' argument.
+       (keccak_init): Setup 'suffix'; add SHAKE128 & SHAKE256.
+       (shake128_init, shake256_init): New.
+       (keccak_final): Do not initial permute for SHAKE output; use correct
+       suffix for SHAKE.
+       (keccak_extract): New.
+       (keccak_selftests_keccak): Add SHAKE128 & SHAKE256 test-vectors.
+       (run_selftests): Add SHAKE128 & SHAKE256.
+       (shake128_asn, oid_spec_shake128, shake256_asn, oid_spec_shake256)
+       (_gcry_digest_spec_shake128, _gcry_digest_spec_shake256): New.
+       * cipher/md.c (digest_list): Add SHAKE128 & SHAKE256.
+       * doc/gcrypt.texi: Ditto.
+       * src/cipher.h (_gcry_digest_spec_shake128)
+       (_gcry_digest_spec_shake256): New.
+       * src/gcrypt.h.in (GCRY_MD_SHAKE128, GCRY_MD_SHAKE256): New.
+       * tests/basic.c (check_one_md): Add XOF check; Add 'elen' argument.
+       (check_one_md_multi): Skip if algo is XOF.
+       (check_digests): Add SHAKE128 & SHAKE256 test vectors.
+       * tests/bench-slope.c (kdf_bench_one): Skip XOFs.
+
+       Few updates to documentation.
+       * doc/gcrypt.text: Add mention of new 'intel-fast-shld' hw feature
+       flag; Add mention of x86 RDRAND support in rndhw.
+
+       Add HMAC-SHA3 test vectors.
+       * tests/basic.c (check_mac): Add HMAC_SHA3 test vectors.
+
+2015-10-28  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       md: add variable length output interface.
+       * cipher/crc.c (_gcry_digest_spec_crc32)
+       (_gcry_digest_spec_crc32_rfc1510, _gcry_digest_spec_crc24_rfc2440): Set
+       'extract' NULL.
+       * cipher/gostr3411-94.c (_gcry_digest_spec_gost3411_94)
+       (_gcry_digest_spec_gost3411_cp): Ditto.
+       * cipher/keccak.c (_gcry_digest_spec_sha3_224)
+       (_gcry_digest_spec_sha3_256, _gcry_digest_spec_sha3_384)
+       (_gcry_digest_spec_sha3_512): Ditto.
+       * cipher/md2.c (_gcry_digest_spec_md2): Ditto.
+       * cipher/md4.c (_gcry_digest_spec_md4): Ditto.
+       * cipher/md5.c (_gcry_digest_spec_md5): Ditto.
+       * cipher/rmd160.c (_gcry_digest_spec_rmd160): Ditto.
+       * cipher/sha1.c (_gcry_digest_spec_sha1): Ditto.
+       * cipher/sha256.c (_gcry_digest_spec_sha224)
+       (_gcry_digest_spec_sha256): Ditto.
+       * cipher/sha512.c (_gcry_digest_spec_sha384)
+       (_gcry_digest_spec_sha512): Ditto.
+       * cipher/stribog.c (_gcry_digest_spec_stribog_256)
+       (_gcry_digest_spec_stribog_512): Ditto.
+       * cipher/tiger.c (_gcry_digest_spec_tiger)
+       (_gcry_digest_spec_tiger1, _gcry_digest_spec_tiger2): Ditto.
+       * cipher/whirlpool.c (_gcry_digest_spec_whirlpool): Ditto.
+       * cipher/md.c (md_enable): Do not allow combination of HMAC and
+       'expandable-output function'.
+       (md_final): Check if spec->read is NULL before calling.
+       (md_read): Ditto.
+       (md_extract, _gcry_md_extract): New.
+       * doc/gcrypt.texi: Add SHA3 algorithms and gcry_md_extract.
+       * src/cipher-proto.h (gcry_md_extract_t): New.
+       (gcry_md_spec_t): Add 'extract'.
+       * src/gcrypt-int.g (_gcry_md_extract): New.
+       * src/gcrypt.h.in (gcry_md_extract): New.
+       * src/libgcrypt.def: Add gcry_md_extract.
+       * src/libgcrypt.vers: Add gcry_md_extract.
+       * src/visibility.c (gcry_md_extract): New.
+       * src/visibility.h (gcry_md_extract): New.
+
+       md: check hmac flag in prepare_macpads.
+       * cipher/md.c (prepare_macpads): Check hmac flag.
+
+       keccak: rewrite for improved performance.
+       * cipher/Makefile.am: Add 'keccak_permute_32.h' and
+       'keccak_permute_64.h'.
+       * cipher/hash-common.h [USE_SHA3] (MD_BLOCK_MAX_BLOCKSIZE): Remove.
+       * cipher/keccak.c (USE_64BIT, USE_32BIT, USE_64BIT_BMI2)
+       (USE_64BIT_SHLD, USE_32BIT_BMI2, NEED_COMMON64, NEED_COMMON32BI)
+       (keccak_ops_t): New.
+       (KECCAK_STATE): Add 'state64' and 'state32bi' members.
+       (KECCAK_CONTEXT): Remove 'bctx'; add 'blocksize', 'count' and 'ops'.
+       (rol64, keccak_f1600_state_permute): Remove.
+       [NEED_COMMON64] (round_consts_64bit, keccak_extract_inplace64): New.
+       [NEED_COMMON32BI] (round_consts_32bit, keccak_extract_inplace32bi)
+       (keccak_absorb_lane32bi): New.
+       [USE_64BIT] (ANDN64, ROL64, keccak_f1600_state_permute64)
+       (keccak_absorb_lanes64, keccak_generic64_ops): New.
+       [USE_64BIT_SHLD] (ANDN64, ROL64, keccak_f1600_state_permute64_shld)
+       (keccak_absorb_lanes64_shld, keccak_shld_64_ops): New.
+       [USE_64BIT_BMI2] (ANDN64, ROL64, keccak_f1600_state_permute64_bmi2)
+       (keccak_absorb_lanes64_bmi2, keccak_bmi2_64_ops): New.
+       [USE_32BIT] (ANDN64, ROL64, keccak_f1600_state_permute32bi)
+       (keccak_absorb_lanes32bi, keccak_generic32bi_ops): New.
+       [USE_32BIT_BMI2] (ANDN64, ROL64, keccak_f1600_state_permute32bi_bmi2)
+       (pext, pdep, keccak_absorb_lane32bi_bmi2, keccak_absorb_lanes32bi_bmi2)
+       (keccak_extract_inplace32bi_bmi2, keccak_bmi2_32bi_ops): New.
+       (keccak_write): New.
+       (keccak_init): Adjust to KECCAK_CONTEXT changes; add implementation
+       selection based on HWF features.
+       (keccak_final): Adjust to KECCAK_CONTEXT changes; use selected 'ops'
+       for state manipulation.
+       (keccak_read): Adjust to KECCAK_CONTEXT changes.
+       (_gcry_digest_spec_sha3_224, _gcry_digest_spec_sha3_256)
+       (_gcry_digest_spec_sha3_348, _gcry_digest_spec_sha3_512): Use
+       'keccak_write' instead of '_gcry_md_block_write'.
+       * cipher/keccak_permute_32.h: New.
+       * cipher/keccak_permute_64.h: New.
+
+       hwf-x86: add detection for Intel CPUs with fast SHLD instruction.
+       * cipher/sha1.c (sha1_init): Use HWF_INTEL_FAST_SHLD instead of
+       HWF_INTEL_CPU.
+       * cipher/sha256.c (sha256_init, sha224_init): Ditto.
+       * cipher/sha512.c (sha512_init, sha384_init): Ditto.
+       * src/g10lib.h (HWF_INTEL_FAST_SHLD): New.
+       (HWF_INTEL_BMI2, HWF_INTEL_SSSE3, HWF_INTEL_PCLMUL, HWF_INTEL_AESNI)
+       (HWF_INTEL_RDRAND, HWF_INTEL_AVX, HWF_INTEL_AVX2)
+       (HWF_ARM_NEON): Update.
+       * src/hwf-x86.c (detect_x86_gnuc): Add detection of Intel Core
+       CPUs with fast SHLD/SHRD instruction.
+       * src/hwfeatures.c (hwflist): Add "intel-fast-shld".
+
+       Fix OCB amd64 assembly implementations for x32.
+       * cipher/camellia-glue.c (_gcry_camellia_aesni_avx_ocb_enc)
+       (_gcry_camellia_aesni_avx_ocb_dec, _gcry_camellia_aesni_avx_ocb_auth)
+       (_gcry_camellia_aesni_avx2_ocb_enc, _gcry_camellia_aesni_avx2_ocb_dec)
+       (_gcry_camellia_aesni_avx2_ocb_auth, _gcry_camellia_ocb_crypt)
+       (_gcry_camellia_ocb_auth): Change 'Ls' from pointer array to u64 array.
+       * cipher/serpent.c (_gcry_serpent_sse2_ocb_enc)
+       (_gcry_serpent_sse2_ocb_dec, _gcry_serpent_sse2_ocb_auth)
+       (_gcry_serpent_avx2_ocb_enc, _gcry_serpent_avx2_ocb_dec)
+       (_gcry_serpent_ocb_crypt, _gcry_serpent_ocb_auth): Ditto.
+       * cipher/twofish.c (_gcry_twofish_amd64_ocb_enc)
+       (_gcry_twofish_amd64_ocb_dec, _gcry_twofish_amd64_ocb_auth)
+       (twofish_amd64_ocb_enc, twofish_amd64_ocb_dec, twofish_amd64_ocb_auth)
+       (_gcry_twofish_ocb_crypt, _gcry_twofish_ocb_auth): Ditto.
+
+       bench-slope: add KDF/PBKDF2 benchmark.
+       * tests/bench-slope.c (bench_kdf_mode, bench_kdf_init, bench_kdf_free)
+       (bench_kdf_do_bench, kdf_ops, kdf_bench_one, kdf_bench): New.
+       (print_help): Add 'kdf'.
+       (main): Add KDF benchmarks.
+
+2015-10-22  NIIBE Yutaka  <gniibe@fsij.org>
+
+       md: keep contexts for HMAC in GcryDigestEntry.
+       * cipher/md.c (struct gcry_md_context): Add flags.hmac.
+       Remove macpads and mcpads_Bsize.
+       (md_open): Initialize flags.hmac.  Remove macpads initialization.
+       (md_enable): Allocate contexts when flags.hmac is enabled.
+       (md_copy): Remove macpads copying.  Add copying contexts.
+       (_gcry_md_reset): When flags.hmac is enabled, restore precomputed
+       context with input pad
+       (md_close): Remove macpads wiping.
+       (md_final): When flags.hmac is enabled, compute hmac by precomputed
+       context with output pad.
+       (prepare_macpads): Prepare precomputed contexts with input pad and
+       output pad for each registered digest entry.
+       (_gcry_md_setkey): Just call prepare_macpads.
+
+2015-10-15  NIIBE Yutaka  <gniibe@fsij.org>
+
+       Fix double free on error.
+       * src/hmac256.c (_gcry_hmac256_finalize): Don't free HD.
+
+2015-10-14  NIIBE Yutaka  <gniibe@fsij.org>
+
+       Fix gpg_error_t and gpg_err_code_t confusion.
+       * src/gcrypt-int.h (_gcry_sexp_extract_param): Revert the change.
+       * cipher/dsa.c (dsa_check_secret_key): Ditto.
+       * src/sexp.c (_gcry_sexp_extract_param): Return gpg_err_code_t.
+
+       * src/gcrypt-int.h (_gcry_err_make_from_errno)
+       (_gcry_error_from_errno): Return gpg_error_t.
+       * cipher/cipher.c (_gcry_cipher_open_internal)
+       (_gcry_cipher_ctl, _gcry_cipher_ctl): Don't use gcry_error.
+       * src/global.c (_gcry_vcontrol): Likewise.
+       * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_genkey): Use
+        gpg_err_code_from_syserror.
+       * cipher/mac.c (mac_reset, mac_setkey, mac_setiv, mac_write)
+       (mac_read, mac_verify): Return gcry_err_code_t.
+       * cipher/rsa-common.c (mgf1): Use gcry_err_code_t for ERR.
+       * src/visibility.c (gcry_error_from_errno): Return gpg_error_t.
+
+2015-10-13  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Fix compiling AES/AES-NI implementation on linux-i386.
+       * cipher/rijndael-aesni.c (do_aesni_ctr_4): Split assembly block in
+       two parts to reduce number of register constraints needed.
+
+2015-10-13  NIIBE Yutaka  <gniibe@fsij.org>
+
+       Fix declaration of return type.
+       * src/gcrypt-int.h (_gcry_sexp_extract_param): Return gpg_error_t.
+       * cipher/dsa.c (dsa_generate): Fix call to _gcry_sexp_extract_param.
+       * src/g10lib.h (_gcry_vcontrol): Return gcry_err_code_t.
+       * src/visibility.c (gcry_mpi_snatch): Fix call to _gcry_mpi_snatch.
+
+2015-09-07  Werner Koch  <wk@gnupg.org>
+
+       Improve GCRYCTL_DISABLE_PRIV_DROP by also disabling cap_ calls.
+       * src/secmem.c (lock_pool, secmem_init): Do not call any cap_
+       functions if NO_PRIV_DROP is set.
+
+2015-09-04  Werner Koch  <wk@gnupg.org>
+
+       w32: Avoid a few compiler warnings.
+       * cipher/cipher-selftest.c (_gcry_selftest_helper_cbc)
+       (_gcry_selftest_helper_cfb, _gcry_selftest_helper_ctr): Mark variable
+       as unused.
+       * random/rndw32.c (slow_gatherer): Avoid signed pointer mismatch
+       warning.
+       * src/secmem.c (init_pool): Avoid unused variable warning.
+       * tests/random.c (writen, readn): Include on if needed.
+
+       w32: Fix alignment problem with AESNI on Windows >= 8.
+       * cipher/cipher-selftest.c (_gcry_cipher_selftest_alloc_ctx): New.
+       * cipher/rijndael.c (selftest_basic_128, selftest_basic_192)
+       (selftest_basic_256): Allocate context on the heap.
+
+2015-08-31  Werner Koch  <wk@gnupg.org>
+
+       rsa: Add verify after sign to avoid Lenstra's CRT attack.
+       * cipher/rsa.c (rsa_sign): Check the CRT.
+
+       Add pubkey algo id for EdDSA.
+       * src/gcrypt.h.in (GCRY_PK_EDDSA): New.
+
+2015-08-25  Werner Koch  <wk@gnupg.org>
+
+       Add configure option --enable-build-timestamp.
+       * configure.ac (BUILD_TIMESTAMP): Set to "<none>" by default.
+
+2015-08-23  Werner Koch  <wk@gnupg.org>
+
+       tests: Add missing files for the make distcheck target.
+       * tests/Makefile.am (EXTRA_DIST): Add sha3-x test vector files.
+
+2015-08-19  Werner Koch  <wk@gnupg.org>
+
+       Change SHA-3 algorithm ids.
+       * src/gcrypt.h.in (GCRY_MD_SHA3_224, GCRY_MD_SHA3_256)
+       (GCRY_MD_SHA3_384, GCRY_MD_SHA3_512): Change values.
+
+2015-08-12  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Keccak: Fix array indexes in θ step.
+       * cipher/keccak.c (keccak_f1600_state_permute): Fix indexes for D[5].
+
+       Simplify OCB offset calculation for parallel implementations.
+       * cipher/camellia-glue.c (_gcry_camellia_ocb_crypt)
+       (_gcry_camellia_ocb_auth): Precalculate Ls array always, instead of
+       just if 'blkn % <parallel blocks> == 0'.
+       * cipher/serpent.c (_gcry_serpent_ocb_crypt)
+       (_gcry_serpent_ocb_auth): Ditto.
+       * cipher/rijndael-aesni.c (get_l): Remove low-bit checks.
+       (aes_ocb_enc, aes_ocb_dec, _gcry_aes_aesni_ocb_auth): Handle leading
+       blocks until block counter is multiple of 4, so that parallel block
+       processing loop can use 'c->u_mode.ocb.L' array directly.
+       * tests/basic.c (check_ocb_cipher_largebuf): Rename to...
+       (check_ocb_cipher_largebuf_split): ...this and add option to process
+       large buffer as two split buffers.
+       (check_ocb_cipher_largebuf): New.
+
+       Add carryless 8-bit addition fast-path for AES-NI CTR mode.
+       * cipher/rijndael-aesni.c (do_aesni_ctr_4): Do addition using
+       CTR in big-endian form, if least-significant byte does not overflow.
+
+2015-08-10  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Add additional SHA3 test-vectors.
+       * tests/basic.c (check_digests): Allow datalen to be specified so that
+       input data can have byte with value 0x00; Include sha3-*.h header files
+       to test-vector structure.
+       * tests/sha3-224.h: New.
+       * tests/sha3-256.h: New.
+       * tests/sha3-384.h: New.
+       * tests/sha3-512.h: New.
+
+       Add generic SHA3 implementation.
+       * cipher/hash-common.h (MD_BLOCK_MAX_BLOCKSIZE): Increase blocksize
+       USE_SHA3 enabled.
+       * cipher/keccak.c (SHA3_DELIMITED_SUFFIX, SHAKE_DELIMITED_SUFFIX): New.
+       (KECCAK_STATE): Add proper state.
+       (KECCAK_CONTEXT): Add 'outlen'.
+       (rol64, keccak_f1600_state_permute, transform_blk, transform): New.
+       (keccak_init): Add proper initialization.
+       (keccak_final): Add proper finalization.
+       (selftests_keccak): Add selftests.
+       (oid_spec_sha3_224, oid_spec_sha3_256, oid_spec_sha3_384)
+       (oid_spec_sha3_512): Add OID.
+       (_gcry_digest_spec_sha3_224, _gcry_digest_spec_sha3_256)
+       (_gcry_digest_spec_sha3_384, _gcry_digest_spec_sha3_512): Fix output
+       length.
+       * cipher/mac-hmac.c (map_mac_algo_to_md): Fix mapping for SHA3-512.
+       (hmac_get_keylen): Return proper blocksizes for SHA3 algorithms.
+       [USE_SHA3] (_gcry_mac_type_spec_hmac_sha3_224)
+       (_gcry_mac_type_spec_hmac_sha3_256, _gcry_mac_type_spec_hmac_sha3_384)
+       (_gcry_mac_type_spec_hmac_sha3_512): New.
+       * cipher/mac-internal [USE_SHA3] (_gcry_mac_type_spec_hmac_sha3_224)
+       (_gcry_mac_type_spec_hmac_sha3_256, _gcry_mac_type_spec_hmac_sha3_384)
+       (_gcry_mac_type_spec_hmac_sha3_512): New.
+       * cipher/mac.c (mac_list) [USE_SHA3]: Add SHA3 algorithms.
+       * cipher/md.c (md_open): Use proper SHA-3 blocksizes for HMAC macpads.
+       * tests/basic.c (check_digests): Add SHA3 test vectors.
+
+       Optimize OCB offset calculation.
+       * cipher/cipher-internal.h (ocb_get_l): New.
+       * cipher/cipher-ocb.c (_gcry_cipher_ocb_authenticate)
+       (ocb_crypt): Use 'ocb_get_l' instead of '_gcry_cipher_ocb_get_l'.
+       * cipher/camellia-glue.c (get_l): Remove.
+       (_gcry_camellia_ocb_crypt, _gcry_camellia_ocb_auth): Precalculate
+       offset array when block count matches parallel operation size; Use
+       'ocb_get_l' instead of 'get_l'.
+       * cipher/rijndael-aesni.c (get_l): Add fast path for 75% most common
+       offsets.
+       (aesni_ocb_enc, aesni_ocb_dec, _gcry_aes_aesni_ocb_auth): Precalculate
+       offset array when block count matches parallel operation size.
+       * cipher/rijndael-ssse3-amd64.c (get_l): Add fast path for 75% most
+       common offsets.
+       * cipher/rijndael.c (_gcry_aes_ocb_crypt, _gcry_aes_ocb_auth): Use
+       'ocb_get_l' instead of '_gcry_cipher_ocb_get_l'.
+       * cipher/serpent.c (get_l): Remove.
+       (_gcry_serpent_ocb_crypt, _gcry_serpent_ocb_auth): Precalculate
+       offset array when block count matches parallel operation size; Use
+       'ocb_get_l' instead of 'get_l'.
+       * cipher/twofish.c (get_l): Remove.
+       (_gcry_twofish_ocb_crypt, _gcry_twofish_ocb_auth): Use 'ocb_get_l'
+       instead of 'get_l'.
+
+2015-08-10  NIIBE Yutaka  <gniibe@fsij.org>
+
+       ecc: fix Montgomery curve bugs.
+       * cipher/ecc.c (check_secret_key): Y1 should not be NULL when check.
+       (ecc_check_secret_key): Support Montgomery curve.
+       * mpi/ec.c (_gcry_mpi_ec_curve_point): Fix condition.
+
+2015-08-08  Werner Koch  <wk@gnupg.org>
+
+       Add framework to eventually support SHA3.
+       * src/gcrypt.h.in (GCRY_MD_SHA3_224, GCRY_MD_SHA3_256)
+       (GCRY_MD_SHA3_384, GCRY_MD_SHA3_512): New.
+       (GCRY_MAC_HMAC_SHA3_224, GCRY_MAC_HMAC_SHA3_256)
+       (GCRY_MAC_HMAC_SHA3_384, GCRY_MAC_HMAC_SHA3_512): New.
+       * cipher/keccak.c: New with stub functions.
+       * cipher/Makefile.am (EXTRA_libcipher_la_SOURCES): Add keccak.c.
+       * configure.ac (available_digests): Add sha3.
+       (USE_SHA3): New.
+       * src/fips.c (run_hmac_selftests): Add SHA3 to the required selftests.
+       * cipher/md.c (digest_list) [USE_SHA3]: Add standard SHA3 algos.
+       (md_open): Ditto for hmac processing.
+       * cipher/mac-hmac.c (map_mac_algo_to_md): Add mapping.
+       * cipher/hmac-tests.c (run_selftests): Prepare for tests.
+       * cipher/pubkey-util.c (get_hash_algo): Add "sha3-xxx".
+
+2015-08-06  Werner Koch  <wk@gnupg.org>
+
+       tools: Fix memory leak for functions "I" and "G".
+       * src/mpicalc.c (do_inv, do_gcd): Init A after stack check.
+
+2015-08-06  Ismo Puustinen  <ismo.puustinen@intel.com>
+
+       ecc: Free memory also when in error branch.
+       * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_sign): Init DISGEST and goto
+       leave on error.
+
+2015-08-06  NIIBE Yutaka  <gniibe@fsij.org>
+
+       Add Curve25519 support.
+       * cipher/ecc-curves.c (curve_aliases, domain_parms): Add Curve25519.
+       * tests/curves.c (N_CURVES): It's 22 now.
+       * src/cipher.h (PUBKEY_FLAG_DJB_TWEAK): New.
+       * cipher/ecc-common.h (_gcry_ecc_mont_decodepoint): New.
+       * cipher/ecc-misc.c (_gcry_ecc_mont_decodepoint): New.
+       * cipher/ecc.c (nist_generate_key): Handle the case of
+       PUBKEY_FLAG_DJB_TWEAK and Montgomery curve.
+       (test_ecdh_only_keys, check_secret_key): Likewise.
+       (ecc_generate): Support Curve25519 which is Montgomery curve with flag
+       PUBKEY_FLAG_DJB_TWEAK and PUBKEY_FLAG_COMP.
+       (ecc_encrypt_raw): Get flags from KEYPARMS and handle
+       PUBKEY_FLAG_DJB_TWEAK and Montgomery curve.
+       (ecc_decrypt_raw): Likewise.
+       (compute_keygrip): Handle the case of PUBKEY_FLAG_DJB_TWEAK.
+       * cipher/pubkey-util.c (_gcry_pk_util_parse_flaglist):
+       PUBKEY_FLAG_EDDSA implies PUBKEY_FLAG_DJB_TWEAK.
+       Parse "djb-tweak" for PUBKEY_FLAG_DJB_TWEAK.
+
+2015-07-27  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Reduce code size for Twofish key-setup and remove key dependend branch.
+       * cipher/twofish.c (poly_to_exp): Increase size by one, change type
+       from byte to u16 and insert '492' to index 0.
+       (exp_to_poly): Increase size by 256, let new cells have zero value.
+       (CALC_S): Execute unconditionally with help of modified tables.
+       (do_twofish_setkey): Change type for 'tmp' to 'unsigned int'; Un-unroll
+       CALC_K256 and CALC_K phases to reduce generated object size.
+
+       Reduce amount of duplicated code in OCB bulk implementations.
+       * cipher/cipher-ocb.c (_gcry_cipher_ocb_authenticate)
+       (ocb_crypt): Change bulk function to return number of unprocessed
+       blocks.
+       * src/cipher.h (_gcry_aes_ocb_crypt, _gcry_aes_ocb_auth)
+       (_gcry_camellia_ocb_crypt, _gcry_camellia_ocb_auth)
+       (_gcry_serpent_ocb_crypt, _gcry_serpent_ocb_auth)
+       (_gcry_twofish_ocb_crypt, _gcry_twofish_ocb_auth): Change return type
+       to 'size_t'.
+       * cipher/camellia-glue.c (get_l): Only if USE_AESNI_AVX or
+       USE_AESNI_AVX2 defined.
+       (_gcry_camellia_ocb_crypt, _gcry_camellia_ocb_auth): Change return type
+       to 'size_t' and return remaining blocks; Remove unaccelerated common
+       code path. Enable remaining common code only if USE_AESNI_AVX or
+       USE_AESNI_AVX2 defined; Remove unaccelerated common code.
+       * cipher/rijndael.c (_gcry_aes_ocb_crypt, _gcry_aes_ocb_auth): Change
+       return type to 'size_t' and return zero.
+       * cipher/serpent.c (get_l): Only if USE_SSE2, USE_AVX2 or USE_NEON
+       defined.
+       (_gcry_serpent_ocb_crypt, _gcry_serpent_ocb_auth): Change return type
+       to 'size_t' and return remaining blocks; Remove unaccelerated common
+       code path. Enable remaining common code only if USE_SSE2, USE_AVX2 or
+       USE_NEON defined; Remove unaccelerated common code.
+       * cipher/twofish.c (get_l): Only if USE_AMD64_ASM defined.
+       (_gcry_twofish_ocb_crypt, _gcry_twofish_ocb_auth): Change return type
+       to 'size_t' and return remaining blocks; Remove unaccelerated common
+       code path. Enable remaining common code only if USE_AMD64_ASM defined;
+       Remove unaccelerated common code.
+
+       Add bulk OCB for Serpent SSE2, AVX2 and NEON implementations.
+       * cipher/cipher.c (_gcry_cipher_open_internal): Setup OCB bulk
+       functions for Serpent.
+       * cipher/serpent-armv7-neon.S: Add OCB assembly functions.
+       * cipher/serpent-avx2-amd64.S: Add OCB assembly functions.
+       * cipher/serpent-sse2-amd64.S: Add OCB assembly functions.
+       * cipher/serpent.c (_gcry_serpent_sse2_ocb_enc)
+       (_gcry_serpent_sse2_ocb_dec, _gcry_serpent_sse2_ocb_auth)
+       (_gcry_serpent_neon_ocb_enc, _gcry_serpent_neon_ocb_dec)
+       (_gcry_serpent_neon_ocb_auth, _gcry_serpent_avx2_ocb_enc)
+       (_gcry_serpent_avx2_ocb_dec, _gcry_serpent_avx2_ocb_auth): New
+       prototypes.
+       (get_l, _gcry_serpent_ocb_crypt, _gcry_serpent_ocb_auth): New.
+       * src/cipher.h (_gcry_serpent_ocb_crypt)
+       (_gcry_serpent_ocb_auth): New.
+       * tests/basic.c (check_ocb_cipher): Add test-vector for serpent.
+
+       Add bulk OCB for Twofish AMD64 implementation.
+       * cipher/cipher.c (_gcry_cipher_open_internal): Setup OCB bulk
+       functions for Twofish.
+       * cipher/twofish-amd64.S: Add OCB assembly functions.
+       * cipher/twofish.c (_gcry_twofish_amd64_ocb_enc)
+       (_gcry_twofish_amd64_ocb_dec, _gcry_twofish_amd64_ocb_auth): New
+       prototypes.
+       (call_sysv_fn5, call_sysv_fn6, twofish_amd64_ocb_enc)
+       (twofish_amd64_ocb_dec, twofish_amd64_ocb_auth, get_l)
+       (_gcry_twofish_ocb_crypt, _gcry_twofish_ocb_auth): New.
+       * src/cipher.h (_gcry_twofish_ocb_crypt)
+       (_gcry_twofish_ocb_auth): New.
+       * tests/basic.c (check_ocb_cipher): Add test-vector for Twofish.
+
+       Add bulk OCB for Camellia AES-NI/AVX and AES-NI/AVX2 implementations.
+       * cipher/camellia-aesni-avx-amd64.S: Add OCB assembly functions.
+       * cipher/camellia-aesni-avx2-amd64.S: Add OCB assembly functions.
+       * cipher/camellia-glue.c (_gcry_camellia_aesni_avx_ocb_enc)
+       (_gcry_camellia_aesni_avx_ocb_dec, _gcry_camellia_aesni_avx_ocb_auth)
+       (_gcry_camellia_aesni_avx2_ocb_enc, _gcry_camellia_aesni_avx2_ocb_dec)
+       (_gcry_camellia_aesni_avx2_ocb_auth): New prototypes.
+       (get_l, _gcry_camellia_ocb_crypt, _gcry_camellia_ocb_auth): New.
+       * cipher/cipher.c (_gcry_cipher_open_internal): Setup OCB bulk
+       functions for Camellia.
+       * src/cipher.h (_gcry_camellia_ocb_crypt)
+       (_gcry_camellia_ocb_auth): New.
+       * tests/basic.c (check_ocb_cipher): Add test-vector for Camellia.
+
+2015-07-26  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Add OCB bulk mode for AES SSSE3 implementation.
+       * cipher/rijndael-ssse3-amd64.c (SSSE3_STATE_SIZE): New.
+       [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS] (vpaes_ssse3_prepare): Use
+       'ssse3_state' for storing current SSSE3 state.
+       [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS]
+       (vpaes_ssse3_cleanup): Restore SSSE3 state from 'ssse3_state'.
+       (_gcry_aes_ssse3_do_setkey, _gcry_aes_ssse3_prepare_decryption)
+       (_gcry_aes_ssse3_encrypt, _gcry_aes_ssse3_cfb_enc)
+       (_gcry_aes_ssse3_cbc_enc, _gcry_aes_ssse3_ctr_enc)
+       (_gcry_aes_ssse3_decrypt, _gcry_aes_ssse3_cfb_dec)
+       (_gcry_aes_ssse3_cbc_dec, _gcry_aes_ssse3_cbc_dec): Add 'ssse3_state'
+       array.
+       (get_l, ssse3_ocb_enc, ssse3_ocb_dec, _gcry_aes_ssse3_ocb_crypt)
+       (_gcry_aes_ssse3_ocb_auth): New.
+       * cipher/rijndael.c (_gcry_aes_ssse3_ocb_crypt)
+       (_gcry_aes_ssse3_ocb_auth): New.
+       (_gcry_aes_ocb_crypt, _gcry_aes_ocb_auth) [USE_SSSE3]: Use SSSE3
+       implementation for OCB.
+
+2015-07-26  Peter Wu  <peter@lekensteyn.nl>
+
+       Fix undefined behavior wrt memcpy.
+       * cipher/cipher-gcm.c: Do not copy zero bytes from an empty buffer. Let
+       the function continue to add padding as needed though.
+       * cipher/mac-poly1305.c: If the caller requested to finish the hash
+       function without a copy of the result, return immediately.
+
+2015-07-23  Peter Wu  <peter@lekensteyn.nl>
+
+       build: ignore scissor line for the commit-msg hook.
+       * build-aux/git-hooks/commit-msg: Stop processing more lines when the
+         scissor line is encountered.
+
+2015-07-16  Peter Wu  <peter@lekensteyn.nl>
+
+       rsa: Fix error in comments.
+       * cipher/rsa.c: Fix.
+
+2015-07-14  Peter Wu  <peter@lekensteyn.nl>
+
+       sexp: Fix invalid deallocation in error path.
+       * src/sexp.c: Fix wrong condition.
+
+2015-07-10  Peter Wu  <peter@lekensteyn.nl>
+
+       ecc: fix memory leak.
+       * cipher/ecc.c (ecc_verify): Release memory which was allocated before
+       by _gcry_pk_util_preparse_sigval.
+       (ecc_decrypt_raw): Likewise.
+
+2015-07-06  NIIBE Yutaka  <gniibe@fsij.org>
+
+       ecc: fix memory leaks.
+       cipher/ecc.c (ecc_generate): Fix memory leak on error of
+       _gcry_pk_util_parse_flaglist and _gcry_ecc_eddsa_encodepoint.
+       (ecc_check_secret_key): Fix memory leak on error of
+       _gcry_ecc_update_curve_param.
+       (ecc_sign, ecc_verify, ecc_encrypt_raw, ecc_decrypt_raw): Remove
+       unnecessary sexp_release and fix memory leak on error of
+       _gcry_ecc_fill_in_curve.
+       (ecc_decrypt_raw): Fix double free of the point kG and memory leak
+       on error of _gcry_ecc_os2ec.
+
+2015-06-11  NIIBE Yutaka  <gniibe@fsij.org>
+
+       mpi: Support FreeBSD 10 or later.
+       * mpi/config.links: Include FreeBSD 10 to 29.
+
+2015-05-21  Werner Koch  <wk@gnupg.org>
+
+       ecc: Add key generation flag "no-keytest".
+       * src/cipher.h (PUBKEY_FLAG_NO_KEYTEST): New.
+       * cipher/pubkey-util.c (_gcry_pk_util_parse_flaglist): Add flag
+       "no-keytest".  Return an error for invalid flags of length 10.
+
+       * cipher/ecc.c (nist_generate_key): Replace arg random_level by flags
+       set random level depending on flags.
+       * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_genkey): Ditto.
+       * cipher/ecc.c (ecc_generate): Pass flags to generate fucntion and
+       remove var random_level.
+       (nist_generate_key): Implement "no-keytest" flag.
+
+       * tests/keygen.c (check_ecc_keys): Add tests for transient-key and
+       no-keytest.
+
+       ecc: Avoid double conversion to affine coordinates in keygen.
+       * cipher/ecc.c (nist_generate_key): Add args r_x and r_y.
+       (ecc_generate): Rename vars.  Convert to affine coordinates only if
+       not returned by the lower level generation function.
+
+       random: Change initial extra seeding from 2400 bits to 128 bits.
+       * random/random-csprng.c (read_pool): Reduce initial seeding.
+
+2015-05-14  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Enable AMD64 Twofish implementation on WIN64.
+       * cipher/twofish-amd64.S: Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       (ELF): New macro to mask lines with ELF specific commands.
+       * cipher/twofish.c (USE_AMD64_ASM): Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS] (call_sysv_fn): New.
+       (twofish_amd64_encrypt_block, twofish_amd64_decrypt_block)
+       (twofish_amd64_ctr_enc, twofish_amd64_cbc_dec)
+       (twofish_amd64_cfb_dec): New wrapper functions for AMD64
+       assembly functions.
+
+       Enable AMD64 Serpent implementations on WIN64.
+       * cipher/serpent-avx2-amd64.S: Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       (ELF): New macro to mask lines with ELF specific commands.
+       * cipher/serpent-sse2-amd64.S: Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       (ELF): New macro to mask lines with ELF specific commands.
+       * cipher/chacha20.c (USE_SSE2, USE_AVX2): Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       [USE_SSE2 || USE_AVX2] (ASM_FUNC_ABI): New.
+       (_gcry_serpent_sse2_ctr_enc, _gcry_serpent_sse2_cbc_dec)
+       (_gcry_serpent_sse2_cfb_dec, _gcry_serpent_avx2_ctr_enc)
+       (_gcry_serpent_avx2_cbc_dec, _gcry_serpent_avx2_cfb_dec): Add
+       ASM_FUNC_ABI.
+
+       Enable AMD64 Salsa20 implementation on WIN64.
+       * cipher/salsa20-amd64.S: Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       (ELF): New macro to mask lines with ELF specific commands.
+       * cipher/salsa20.c (USE_AMD64): Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       [USE_AMD64] (ASM_FUNC_ABI, ASM_EXTRA_STACK): New.
+       (_gcry_salsa20_amd64_keysetup, _gcry_salsa20_amd64_ivsetup)
+       (_gcry_salsa20_amd64_encrypt_blocks): Add ASM_FUNC_ABI.
+       [USE_AMD64] (salsa20_core): Add ASM_EXTRA_STACK.
+       (salsa20_do_encrypt_stream) [USE_AMD64]: Add ASM_EXTRA_STACK.
+
+       Enable AMD64 Poly1305 implementations on WIN64.
+       * cipher/poly1305-avx2-amd64.S: Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       (ELF): New macro to mask lines with ELF specific commands.
+       * cipher/poly1305-sse2-amd64.S: Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       (ELF): New macro to mask lines with ELF specific commands.
+       * cipher/poly1305-internal.h (POLY1305_SYSV_FUNC_ABI): New.
+       (POLY1305_USE_SSE2, POLY1305_USE_AVX2): Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       (OPS_FUNC_ABI): New.
+       (poly1305_ops_t): Use OPS_FUNC_ABI.
+       * cipher/poly1305.c (_gcry_poly1305_amd64_sse2_init_ext)
+       (_gcry_poly1305_amd64_sse2_finish_ext)
+       (_gcry_poly1305_amd64_sse2_blocks, _gcry_poly1305_amd64_avx2_init_ext)
+       (_gcry_poly1305_amd64_avx2_finish_ext)
+       (_gcry_poly1305_amd64_avx2_blocks, _gcry_poly1305_armv7_neon_init_ext)
+       (_gcry_poly1305_armv7_neon_finish_ext)
+       (_gcry_poly1305_armv7_neon_blocks, poly1305_init_ext_ref32)
+       (poly1305_blocks_ref32, poly1305_finish_ext_ref32)
+       (poly1305_init_ext_ref8, poly1305_blocks_ref8)
+       (poly1305_finish_ext_ref8): Use OPS_FUNC_ABI.
+
+       Enable AMD64 3DES implementation on WIN64.
+       * cipher/des-amd64.S: Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       (ELF): New macro to mask lines with ELF specific commands.
+       * cipher/des.c (USE_AMD64_ASM): Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS] (call_sysv_fn): New.
+       (tripledes_ecb_crypt) [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS]: Call
+       assembly function through 'call_sysv_fn'.
+       (tripledes_amd64_ctr_enc, tripledes_amd64_cbc_dec)
+       (tripledes_amd64_cfb_dec): New wrapper functions for bulk
+       assembly functions.
+
+       Enable AMD64 ChaCha20 implementations on WIN64.
+       * cipher/chacha20-avx2-amd64.S: Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       (ELF): New macro to mask lines with ELF specific commands.
+       * cipher/chacha20-sse2-amd64.S: Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       (ELF): New macro to mask lines with ELF specific commands.
+       * cipher/chacha20-ssse3-amd64.S: Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       (ELF): New macro to mask lines with ELF specific commands.
+       * cipher/chacha20.c (USE_SSE2, USE_SSSE3, USE_AVX2): Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       (ASM_FUNC_ABI, ASM_EXTRA_STACK): New.
+       (chacha20_blocks_t, _gcry_chacha20_amd64_sse2_blocks)
+       (_gcry_chacha20_amd64_ssse3_blocks, _gcry_chacha20_amd64_avx2_blocks)
+       (_gcry_chacha20_armv7_neon_blocks, chacha20_blocks): Add ASM_FUNC_ABI.
+       (chacha20_core): Add ASM_EXTRA_STACK.
+
+       Enable AMD64 CAST5 implementation on WIN64.
+       * cipher/cast5-amd64.S: Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       (RIP): Remove.
+       (GET_EXTERN_POINTER): Use 'leaq' version on WIN64.
+       (ELF): New macro to mask lines with ELF specific commands.
+       * cipher/cast5.c (USE_AMD64_ASM): Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS] (call_sysv_fn): New.
+       (do_encrypt_block, do_decrypt_block)
+       [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS]: Call assembly
+       function through 'call_sysv_fn'.
+       (cast5_amd64_ctr_enc, cast5_amd64_cbc_dec)
+       (cast5_amd64_cfb_dec): New wrapper functions for bulk
+       assembly functions.
+
+       Enable AMD64 Camellia implementations on WIN64.
+       * cipher/camellia-aesni-avx-amd64.S: Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       (ELF): New macro to mask lines with ELF specific commands.
+       * cipher/camellia-aesni-avx2-amd64.S: Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       (ELF): New macro to mask lines with ELF specific commands.
+       * cipher/camellia-glue.c (USE_AESNI_AVX, USE_AESNI_AVX2): Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       [USE_AESNI_AVX || USE_AESNI_AVX2] (ASM_FUNC_ABI, ASM_EXTRA_STACK): New.
+       (_gcry_camellia_aesni_avx_ctr_enc, _gcry_camellia_aesni_avx_cbc_dec)
+       (_gcry_camellia_aesni_avx_cfb_dec, _gcry_camellia_aesni_avx_keygen)
+       (_gcry_camellia_aesni_avx2_ctr_enc, _gcry_camellia_aesni_avx2_cbc_dec)
+       (_gcry_camellia_aesni_avx2_cfb_dec): Add ASM_FUNC_ABI.
+
+       Enable AMD64 Blowfish implementation on WIN64.
+       * cipher/blowfish-amd64.S: Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       (ELF): New macro to mask lines with ELF specific commands.
+       * cipher/blowfish.c (USE_AMD64_ASM): Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS] (call_sysv_fn): New.
+       (do_encrypt, do_encrypt_block, do_decrypt_block)
+       [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS]: Call assembly
+       function through 'call_sysv_fn'.
+       (blowfish_amd64_ctr_enc, blowfish_amd64_cbc_dec)
+       (blowfish_amd64_cfb_dec): New wrapper functions for bulk
+       assembly functions.
+       ..
+
+       Enable AMD64 arcfour implementation on WIN64.
+       * cipher/arcfour-amd64.S: Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       (ELF): New macro to mask lines with ELF specific commands.
+       * cipher/arcfour.c (USE_AMD64_ASM): Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       (do_encrypt, do_decrypt) [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS]: Use
+       assembly block to call AMD64 assembly function.
+
+       Update documentation for Poly1305-ChaCha20 AEAD, RFC-7539.
+       * cipher/cipher-poly1305.c: Add RFC-7539 to header.
+       * doc/gcrypt.texi: Update Poly1305 AEAD documentation with mention of
+       RFC-7539; Drop Salsa from supported stream ciphers for Poly1305 AEAD.
+
+       hwf-x86: use edi for passing value to ebx for i386 cpuid.
+       * src/hwf-x86.c [__i386__] (get_cpuid): Use '=D' for regs[1] instead
+       of '=r'.
+
+       hwf-x86: add EDX as output register for xgetbv asm block.
+       * src/hwf-x86.c (get_xgetbv): Add EDX as output.
+
+2015-05-04  Werner Koch  <wk@gnupg.org>
+
+       build: Update build-aux files.
+
+       Fix possible regression on old 32 bit mingw compilers.
+       * acinclude.m4: Add new pattern for mingw32.
+
+       build: Add new file.
+       * mpi/amd64/distfiles: Add func_abi.h.
+
+2015-05-03  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Fix WIN64 assembly glue for AES.
+       * cipher/rinjdael.c (do_encrypt, do_decrypt)
+       [!HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS]: Change input operands to
+       input+output to mark volatile nature of the used registers.
+
+       Add '1 million a characters' test vectors.
+       * tests/basic.c (check_digests): Add "!" test vectors for MD5, SHA-384,
+       SHA-512, RIPEMD160 and CRC32.
+
+2015-05-02  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       More optimized CRC implementations.
+       * cipher/crc.c (crc32_table, crc24_table): Replace with new table
+       contents.
+       (update_crc32, CRC24_INIT, CRC24_POLY): Remove.
+       (crc32_next, crc32_next4, crc24_init, crc24_next, crc24_next4)
+       (crc24_final): New.
+       (crc24rfc2440_init): Use crc24_init.
+       (crc32_write): Rewrite to use crc32_next & crc32_next4.
+       (crc24_write): Rewrite to use crc24_next & crc24_next4.
+       (crc32_final, crc32rfc1510_final): Use buf_put_be32.
+       (crc24rfc2440_final): Use crc24_final & buf_put_le32.
+       * tests/basic.c (check_digests): Add CRC "123456789" tests.
+
+       Enable AMD64 AES implementation for WIN64.
+       * cipher/rijndael-amd64.S: Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       (ELF): New macro to mask lines with ELF specific commands.
+       * cipher/rijndael-internal.h (USE_AMD64_ASM): Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       (do_encrypt, do_decrypt)
+       [USE_AMD64_ASM && !HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS]: Use
+       assembly block to call AMD64 assembly encrypt/decrypt function.
+
+       Enable AMD64 Whirlpool implementation for WIN64.
+       * cipher/whirlpool-sse2-amd64.S: Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       (ELF): New macro to mask lines with ELF specific commands.
+       * cipher/whirlpool.c (USE_AMD64_ASM): Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       [USE_AMD64_ASM] (ASM_FUNC_ABI, ASM_EXTRA_STACK): New.
+       [USE_AMD64_ASM] (_gcry_whirlpool_transform_amd64): Add ASM_FUNC_ABI to
+       prototype.
+       [USE_AMD64_ASM] (whirlpool_transform): Add ASM_EXTRA_STACK to stack
+       burn value.
+
+       Enable AMD64 SHA512 implementations for WIN64.
+       * cipher/sha512-avx-amd64.S: Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       (ELF): New macro to mask lines with ELF specific commands.
+       * cipher/sha512-avx-bmi2-amd64.S: Ditto.
+       * cipher/sha512-ssse3-amd64.S: Ditto.
+       * cipher/sha512.c (USE_SSSE3, USE_AVX, USE_AVX2): Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       [USE_SSSE3 || USE_AVX || USE_AVX2] (ASM_FUNC_ABI)
+       (ASM_EXTRA_STACK): New.
+       (_gcry_sha512_transform_amd64_ssse3, _gcry_sha512_transform_amd64_avx)
+       (_gcry_sha512_transform_amd64_avx_bmi2): Add ASM_FUNC_ABI to
+       prototypes.
+       (transform): Add ASM_EXTRA_STACK to stack burn value.
+
+       Enable AMD64 SHA256 implementations for WIN64.
+       * cipher/sha256-avx-amd64.S: Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       (ELF): New macro to mask lines with ELF specific commands.
+       * cipher/sha256-avx2-bmi2-amd64.S: Ditto.
+       * cipher/sha256-ssse3-amd64.S: Ditto.
+       * cipher/sha256.c (USE_SSSE3, USE_AVX, USE_AVX2): Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       [USE_SSSE3 || USE_AVX || USE_AVX2] (ASM_FUNC_ABI)
+       (ASM_EXTRA_STACK): New.
+       (_gcry_sha256_transform_amd64_ssse3, _gcry_sha256_transform_amd64_avx)
+       (_gcry_sha256_transform_amd64_avx2): Add ASM_FUNC_ABI to prototypes.
+       (transform): Add ASM_EXTRA_STACK to stack burn value.
+
+       Enable AMD64 SHA1 implementations for WIN64.
+       * cipher/sha1-avx-amd64.S: Enable when
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       (ELF): New macro to mask lines with ELF specific commands.
+       * cipher/sha1-avx-bmi2-amd64.S: Ditto.
+       * cipher/sha1-ssse3-amd64.S: Ditto.
+       * cipher/sha1.c (USE_SSSE3, USE_AVX, USE_BMI2): Enable
+       when HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+       [USE_SSSE3 || USE_AVX || USE_BMI2] (ASM_FUNC_ABI)
+       (ASM_EXTRA_STACK): New.
+       (_gcry_sha1_transform_amd64_ssse3, _gcry_sha1_transform_amd64_avx)
+       (_gcry_sha1_transform_amd64_avx_bmi2): Add ASM_FUNC_ABI to
+       prototypes.
+       (transform): Add ASM_EXTRA_STACK to stack burn value.
+
+2015-05-01  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Enable AES/AES-NI, AES/SSSE3 and GCM/PCLMUL implementations on WIN64.
+       * cipher/cipher-gcm-intel-pclmul.c (_gcry_ghash_intel_pclmul)
+       ( _gcry_ghash_intel_pclmul) [__WIN64__]: Store non-volatile vector
+       registers before use and restore after.
+       * cipher/cipher-internal.h (GCM_USE_INTEL_PCLMUL): Remove dependency
+       on !defined(__WIN64__).
+       * cipher/rijndael-aesni.c [__WIN64__] (aesni_prepare_2_6_variable,
+       aesni_prepare, aesni_prepare_2_6, aesni_cleanup)
+       ( aesni_cleanup_2_6): New.
+       [!__WIN64__] (aesni_prepare_2_6_variable, aesni_prepare_2_6): New.
+       (_gcry_aes_aesni_do_setkey, _gcry_aes_aesni_cbc_enc)
+       (_gcry_aesni_ctr_enc, _gcry_aesni_cfb_dec, _gcry_aesni_cbc_dec)
+       (_gcry_aesni_ocb_crypt, _gcry_aesni_ocb_auth): Use
+       'aesni_prepare_2_6'.
+       * cipher/rijndael-internal.h (USE_SSSE3): Enable if
+       HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS or
+       HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS.
+       (USE_AESNI): Remove dependency on !defined(__WIN64__)
+       * cipher/rijndael-ssse3-amd64.c [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS]
+       (vpaes_ssse3_prepare, vpaes_ssse3_cleanup): New.
+       [!HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS] (vpaes_ssse3_prepare): New.
+       (vpaes_ssse3_prepare_enc, vpaes_ssse3_prepare_dec): Use
+       'vpaes_ssse3_prepare'.
+       (_gcry_aes_ssse3_do_setkey, _gcry_aes_ssse3_prepare_decryption): Use
+       'vpaes_ssse3_prepare' and 'vpaes_ssse3_cleanup'.
+       [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS] (X): Add masking macro to
+       exclude '.type' and '.size' markers from assembly code, as they are
+       not support on WIN64/COFF objects.
+       * configure.ac (gcry_cv_gcc_attribute_ms_abi)
+       (gcry_cv_gcc_attribute_sysv_abi, gcry_cv_gcc_default_abi_is_ms_abi)
+       (gcry_cv_gcc_default_abi_is_sysv_abi)
+       (gcry_cv_gcc_win64_platform_as_ok): New checks.
+
+       Add W64 support for mpi amd64 assembly.
+       acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Set
+       'ac_cv_sys_symbol_underscore=no' on MingW-W64.
+       mpi/amd64/func_abi.h: New.
+       mpi/amd64/mpih-add1.S (_gcry_mpih_add_n): Add FUNC_ENTRY and FUNC_EXIT.
+       mpi/amd64/mpih-lshift.S (_gcry_mpih_lshift): Ditto.
+       mpi/amd64/mpih-mul1.S (_gcry_mpih_mul_1): Ditto.
+       mpi/amd64/mpih-mul2.S (_gcry_mpih_addmul_1): Ditto.
+       mpi/amd64/mpih-mul3.S (_gcry_mpih_submul_1): Ditto.
+       mpi/amd64/mpih-rshift.S (_gcry_mpih_rshift): Ditto.
+       mpi/amd64/mpih-sub1.S (_gcry_mpih_sub_n): Ditto.
+       mpi/config.links [host=x86_64-*mingw*]: Enable assembly modules.
+       [host=x86_64-*-*]: Append mpi/amd64/func_abi.h to mpi/asm-syntax.h.
+
+       DES: Silence compiler warnings on Windows.
+       * cipher/des.c (working_memcmp): Make pointer arguments 'const void *'.
+
+       Cast pointers to integers using uintptr_t instead of long.
+
+       Fix rndhw for 64-bit Windows build.
+       * configure.ac: Add sizeof check for 'void *'.
+       * random/rndhw.c (poll_padlock): Check for SIZEOF_VOID_P == 8
+       instead of defined(__LP64__).
+       (RDRAND_LONG): Check for SIZEOF_UNSIGNED_LONG == 8 instead of
+       defined(__LP64__).
+
+       Prepare random/win32.c fast poll for 64-bit Windows.
+       * random/win32.c (_gcry_rndw32_gather_random_fast) [ADD]: Rename to
+       ADDINT.
+       (_gcry_rndw32_gather_random_fast): Add ADDPTR.
+       (_gcry_rndw32_gather_random_fast): Disable entropy gathering from
+       GetQueueStatus(QS_ALLEVENTS).
+       (_gcry_rndw32_gather_random_fast): Change minimumWorkingSetSize and
+       maximumWorkingSetSize to SIZE_T from DWORD.
+       (_gcry_rndw32_gather_random_fast): Only add lower 32-bits of
+       minimumWorkingSetSize and maximumWorkingSetSize to random poll.
+       (_gcry_rndw32_gather_random_fast) [__WIN64__]: Read TSC directly
+       using intrinsic.
+
+       Disable GCM and AES-NI assembly implementations for WIN64.
+       * cipher/cipher-internal.h (GCM_USE_INTEL_PCLMUL): Do not enable when
+       __WIN64__ defined.
+       * cipher/rijndael-internal.h (USE_AESNI): Ditto.
+
+       Disable building mpi assembly routines on WIN64.
+       * mpi/config.links: Disable assembly for host 'x86_64-*mingw32*'.
+
+       Fix packed attribute check for Windows targets.
+       * configure.ac (gcry_cv_gcc_attribute_packed): Move 'long b' to its
+       own packed structure.
+
+       Fix tail handling in buf_xor_1.
+       * cipher/bufhelp.h (buf_xor_1): Increment source pointer at tail
+       handling.
+
+       Add --disable-hwf for basic tests.
+       * tests/basic.c (main): Add handling for '--disable-hwf'.
+
+       Use more odd chuck sizes for check_one_md.
+       * tests/basic.c (check_one_md): Make chuck size vary oddly, instead
+       of using fixed length of 1000 bytes.
+
+       Enable more modes in basic ciphers test.
+       * src/gcrypt.h.in (GCRY_OCB_BLOCK_LEN): New.
+       * tests/basic.c (check_one_cipher_core_reset): New.
+       (check_one_cipher_core): Use check_one_cipher_core_reset inplace of
+       gcry_cipher_reset.
+       (check_ciphers): Add CCM and OCB modes for block cipher tests.
+
+       Fix reseting cipher in OCB mode.
+       * cipher/cipher.c (cipher_reset): Setup default taglen for OCB after
+       clearing state.
+
+2015-04-30  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Fix buggy RC4 AMD64 assembly and add test to notice similar issues.
+       * cipher/arcfour-amd64.S (_gcry_arcfour_amd64): Fix swapped store of
+       'x' and 'y'.
+       * tests/basic.c (get_algo_mode_blklen): New.
+       (check_one_cipher_core): Add new tests for split buffer input on
+       encryption and decryption.
+
+2015-04-26  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Disallow compiler from generating SSE instructions in mixed C+asm source
+       * cipher/cipher-gcm-intel-pclmul.c [gcc-version >= 4.4]: Add GCC target
+       pragma to disable compiler use of SSE.
+       * cipher/rijndael-aesni.c [gcc-version >= 4.4]: Ditto.
+       * cipher/rijndael-ssse3-amd64.c [gcc-version >= 4.4]: Ditto.
+
+2015-04-18  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Add OCB bulk crypt/auth functions for AES/AES-NI.
+       * cipher/cipher-internal.h (gcry_cipher_handle): Add bulk.ocb_crypt
+       and bulk.ocb_auth.
+       (_gcry_cipher_ocb_get_l): New prototype.
+       * cipher/cipher-ocb.c (get_l): Rename to ...
+       (_gcry_cipher_ocb_get_l): ... this.
+       (_gcry_cipher_ocb_authenticate, ocb_crypt): Use bulk function when
+       available.
+       * cipher/cipher.c (_gcry_cipher_open_internal): Setup OCB bulk
+       functions for AES.
+       * cipher/rijndael-aesni.c (get_l, aesni_ocb_enc, aes_ocb_dec)
+       (_gcry_aes_aesni_ocb_crypt, _gcry_aes_aesni_ocb_auth): New.
+       * cipher/rijndael.c [USE_AESNI] (_gcry_aes_aesni_ocb_crypt)
+       (_gcry_aes_aesni_ocb_auth): New prototypes.
+       (_gcry_aes_ocb_crypt, _gcry_aes_ocb_auth): New.
+       * src/cipher.h (_gcry_aes_ocb_crypt, _gcry_aes_ocb_auth): New
+       prototypes.
+       * tests/basic.c (check_ocb_cipher_largebuf): New.
+       (check_ocb_cipher): Add large buffer encryption/decryption test.
 
-       build: Fix typo in help string.
-       * configure.ac: Fix.
+2015-04-15  Werner Koch  <wk@gnupg.org>
+
+       tests: Add option to time the S2K function.
+       * tests/t-kdf.c: Include stopwatch.h.
+       (dummy_consumer): new.
+       (bench_s2k): New.
+       (main): Add option parser and option --s2k.
+
+       tests: Improve stopwatch.h.
+       * tests/stopwatch.h (elapsed_time): Add arg divisor.
+
+2015-04-13  Werner Koch  <wk@gnupg.org>
+
+       mpi: Fix gcry_mpi_copy for NULL opaque data.
+       * mpi/mpiutil.c (_gcry_mpi_copy): Copy opaque only if needed.
+
+2015-03-21  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       wipememory: use one-byte aligned type for unaligned memory accesses.
+       * src/g10lib.h (fast_wipememory2_unaligned_head): Enable unaligned
+       access only when HAVE_GCC_ATTRIBUTE_PACKED and
+       HAVE_GCC_ATTRIBUTE_ALIGNED defined.
+       (fast_wipememory_t): New.
+       (fast_wipememory2): Use 'fast_wipememory_t'.
+
+       bufhelp: use one-byte aligned type for unaligned memory accesses.
+       * cipher/bufhelp.h (BUFHELP_FAST_UNALIGNED_ACCESS): Enable only when
+       HAVE_GCC_ATTRIBUTE_PACKED and HAVE_GCC_ATTRIBUTE_ALIGNED are defined.
+       (bufhelp_int_t): New type.
+       (buf_cpy, buf_xor, buf_xor_1, buf_xor_2dst, buf_xor_n_copy_2): Use
+       'bufhelp_int_t'.
+       [BUFHELP_FAST_UNALIGNED_ACCESS] (bufhelp_u32_t, bufhelp_u64_t): New.
+       [BUFHELP_FAST_UNALIGNED_ACCESS] (buf_get_be32, buf_get_le32)
+       (buf_put_be32, buf_put_le32, buf_get_be64, buf_get_le64)
+       (buf_put_be64, buf_put_le64): Use 'bufhelp_uXX_t'.
+       * configure.ac (gcry_cv_gcc_attribute_packed): New.
+
+       tests/bench-slope: fix memory-leak and use-after-free bugs.
+       * tests/bench-slope.c (do_slope_benchmark): Free 'measurements' at end.
+       (bench_mac_init): Move 'key' free at end of function.
+
+2015-03-19  Werner Koch  <wk@gnupg.org>
+
+       Fix two pedantic warnings.
+       * src/gcrypt.h.in (gcry_mpi_flag, gcry_mac_algos): Remove trailing
+       comma.
+
+2015-03-16  Werner Koch  <wk@gnupg.org>
+
+       Use well defined type instead of size_t in secmem.c.
+       * src/secmem.c (ptr_into_pool_p): Replace size_t by uintptr_t.
+
+       Make uintptr_t global available.
+       * cipher/bufhelp.h: Move include for uintptr_t to ...
+       * src/types.h: here.  Check that config.h has been included.
+
+       mpi: Remove useless condition.
+       * mpi/mpi-pow.c: Remove condition rp==mp.
+
+       cipher: Remove useless NULL check.
+       * cipher/hash-common.c (_gcry_md_block_write): Remove NUL check for
+       hd->buf.
+
+2015-02-28  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Fix in-place encryption for OCB mode.
+       * cipher/cipher-ocb.c (ocb_checksum): New.
+       (ocb_crypt): Move checksum calculation outside main crypt loop, do
+       checksum calculation for encryption before inbuf is overwritten.
+       * tests/basic.c (check_ocb_cipher): Rename to ...
+       (do_check_ocb_cipher): ... to this and add argument for testing
+       in-place encryption/decryption.
+       (check_ocb_cipher): New.
+
+2015-02-27  NIIBE Yutaka  <gniibe@fsij.org>
+
+       tests: fix t-sexp.c.
+       * tests/t-sexp.c (bug_1594): Free N and PUBKEY.
+
+       mpi: Avoid data-dependent timing variations in mpi_powm.
+       * mpi/mpi-pow.c (mpi_powm): Access all data in the table by
+       mpi_set_cond.
+
+       mpi: Revise mpi_powm.
+       * mpi/mpi-pow.c (_gcry_mpi_powm): Rename the table to PRECOMP.
+
+2015-02-23  Werner Koch  <wk@gnupg.org>
+
+       cipher: Use ciphertext blinding for Elgamal decryption.
+       * cipher/elgamal.c (USE_BLINDING): New.
+       (decrypt): Rewrite to use ciphertext blinding.
+
+2015-02-12  NIIBE Yutaka  <gniibe@fsij.org>
+
+       mpi: Add mpi_set_cond.
+       * mpi/mpiutil.c (_gcry_mpi_set_cond): New.
+       (_gcry_mpi_swap_cond): Fix types.
+       * src/mpi.h (mpi_set_cond): New.
+
+2015-01-30  Werner Koch  <wk@gnupg.org>
+
+       w32: Use -static-libgcc to avoid linking to libgcc_s_sjlj-1.dll.
+       * src/Makefile.am (extra_ltoptions): New.
+       (libgcrypt_la_LDFLAGS): Use it.
+
+2015-01-28  Werner Koch  <wk@gnupg.org>
+
+       Fix building of GOST s-boxes when cross-compiling.
+       * cipher/Makefile.am (gost-s-box): USe CC_FOR_BUILD.
+       (noinst_PROGRAMS): Remove.
+       (EXTRA_DIST): New.
+       (CLEANFILES): New.
+
+2015-01-20  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       rijndael: fix wrong ifdef for SSSE3 setkey.
+       * cipher/rijndael.c (do_setkey): Use USE_SSSE3 instead of USE_AESNI
+       around SSSE3 setkey selection.
+
+2015-01-16  Werner Koch  <wk@gnupg.org>
+
+       Add OCB cipher mode.
+       * cipher/cipher-ocb.c: New.
+       * cipher/Makefile.am (libcipher_la_SOURCES): Add cipher-ocb.c
+       * cipher/cipher-internal.h (OCB_BLOCK_LEN, OCB_L_TABLE_SIZE): New.
+       (gcry_cipher_handle): Add fields marks.finalize and u_mode.ocb.
+       * cipher/cipher.c (_gcry_cipher_open_internal): Add OCB mode.
+       (_gcry_cipher_open_internal): Setup default taglen of OCB.
+       (cipher_reset): Clear OCB specific data.
+       (cipher_encrypt, cipher_decrypt, _gcry_cipher_authenticate)
+       (_gcry_cipher_gettag, _gcry_cipher_checktag): Call OCB functions.
+       (_gcry_cipher_setiv): Add OCB specific nonce setting.
+       (_gcry_cipher_ctl): Add GCRYCTL_FINALIZE and GCRYCTL_SET_TAGLEN
+
+       * src/gcrypt.h.in (GCRYCTL_SET_TAGLEN): New.
+       (gcry_cipher_final): New.
+
+       * cipher/bufhelp.h (buf_xor_1): New.
+
+       * tests/basic.c (hex2buffer): New.
+       (check_ocb_cipher): New.
+       (main): Call it here.  Add option --cipher-modes.
+       * tests/bench-slope.c (bench_aead_encrypt_do_bench): Call
+       gcry_cipher_final.
+       (bench_aead_decrypt_do_bench): Ditto.
+       (bench_aead_authenticate_do_bench): Ditto.  Check error code.
+       (bench_ocb_encrypt_do_bench): New.
+       (bench_ocb_decrypt_do_bench): New.
+       (bench_ocb_authenticate_do_bench): New.
+       (ocb_encrypt_ops): New.
+       (ocb_decrypt_ops): New.
+       (ocb_authenticate_ops): New.
+       (cipher_modes): Add them.
+       (cipher_bench_one): Skip wrong block length for OCB.
+       * tests/benchmark.c (cipher_bench): Add field noncelen to MODES.  Add
+       OCB support.
+
+2015-01-15  Werner Koch  <wk@gnupg.org>
+
+       Add functions to count trailing zero bits in a word.
+       * cipher/bithelp.h (_gcry_ctz, _gcry_ctz64): New.
+       * configure.ac (HAVE_BUILTIN_CTZ): Add new test.
+
+2015-01-08  Werner Koch  <wk@gnupg.org>
+
+       cipher: Prepare for OCB mode.
+       * src/gcrypt.h.in (GCRY_CIPHER_MODE_OCB): New.
+
+2015-01-06  Werner Koch  <wk@gnupg.org>
+
+       Make make distcheck work again.
+       * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Remove --enable-ciphers.
+       * cipher/Makefile.am (DISTCLEANFILES): Add gost-sb.h.
+
+2015-01-06  Dmitry Eremin-Solenikov  <dbaryshkov@gmail.com>
+
+       stribog: Reduce table size to the needed one.
+       * cipher/stribog.c (C16): Avoid allocating superfluous space.
+
+       gostr3411-94: Fix the iteration count for length filling loop.
+       * cipher/gostr3411-94.c (gost3411_final): Fix loop
+
+2015-01-05  Werner Koch  <wk@gnupg.org>
+
+       random: Silent warning under NetBSD using rndunix.
+       * random/rndunix.c (STDERR_FILENO): Define if needed.
+       (start_gatherer): Re-open standard descriptors.  Fix an
+       unsigned/signed pointer warning.
+
+       primegen: Fix memory leak for invalid call sequences.
+       * cipher/primegen.c (prime_generate_internal): Refactor generator code
+       to not leak memory for non-implemented feature.
+       (_gcry_prime_group_generator): Refactor to not leak memory for invalid
+       args.  Also make sure that R_G is set as soon as possible.
+
+       doc: Update yat2m to current upstream version (GnuPG).
+
+       build: Require automake 1.14.
+       * configure.ac (AM_INIT_AUTOMAKE): Add serial-tests.
+
+       Replace camel case of internal scrypt functions.
+       * cipher/scrypt.c (_salsa20_core): Rename to salsa20_core.  Change
+       callers.
+       (_scryptBlockMix): Rename to scrypt_block_mix.  Change callers.
+       (_scryptROMix): Rename to scrypt_ro_mix. Change callers.
+
+2015-01-02  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       rmd160: restore native-endian store in _gcry_rmd160_mixblock.
+       * cipher/rmd160.c (_gcry_rmd160_mixblock): Store result to buffer in
+       native-endianess.
+
+2014-12-27  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Add Intel SSSE3 based vector permutation AES implementation.
+       * cipher/Makefile.am: Add 'rijndael-ssse3-amd64.c'.
+       * cipher/rijndael-internal.h (USE_SSSE3): New.
+       (RIJNDAEL_context_s) [USE_SSSE3]: Add 'use_ssse3'.
+       * cipher/rijndael-ssse3-amd64.c: New.
+       * cipher/rijndael.c [USE_SSSE3] (_gcry_aes_ssse3_do_setkey)
+       (_gcry_aes_ssse3_prepare_decryption, _gcry_aes_ssse3_encrypt)
+       (_gcry_aes_ssse3_decrypt, _gcry_aes_ssse3_cfb_enc)
+       (_gcry_aes_ssse3_cbc_enc, _gcry_aes_ssse3_ctr_enc)
+       (_gcry_aes_ssse3_cfb_dec, _gcry_aes_ssse3_cbc_dec): New.
+       (do_setkey): Add HWF check for SSSE3 and setup for SSSE3
+       implementation.
+       (prepare_decryption, _gcry_aes_cfb_enc, _gcry_aes_cbc_enc)
+       (_gcry_aes_ctr_enc, _gcry_aes_cfb_dec, _gcry_aes_cbc_dec): Add
+       selection for SSSE3 implementation.
+       * configure.ac [host=x86_64]: Add 'rijndael-ssse3-amd64.lo'.
+
+2014-12-25  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       random-csprng: fix compiler warnings on ARM.
+       * random/random-csprng.c (_gcry_rngcsprng_update_seed_file)
+       (read_pool): Cast keypool and rndpool to 'unsigned long *' through
+       'void *'.
+
+       scrypt: fix compiler warnings on ARM.
+       * cipher/scrypt.c (_scryptBlockMix): Cast X to 'u32 *' through 'void *'.
+
+       secmem: fix compiler warnings on ARM.
+       * src/secmem.c (ADDR_TO_BLOCK, mb_get_next, mb_get_new): Cast pointer
+       from 'char *' to 'memblock_t *' through 'void *'.
+       (MB_WIPE_OUT): Remove unneeded cast to 'memblock_t *'.
+
+       hash: fix compiler warning on ARM.
+       * cipher/md.c (md_open, md_copy): Cast 'char *' to ctx through
+       'void *'.
+       * cipher/md4.c (md4_final): Use buf_put_* helper instead of
+       converting 'char *' to 'u32 *'.
+       * cipher/md5.c (md5_final): Ditto.
+       * cipher/rmd160.c (_gcry_rmd160_mixblock, rmd160_final): Ditto.
+       * cipher/sha1.c (sha1_final): Ditto.
+       * cipher/sha256.c (sha256_final): Ditto.
+       * cipher/sha512.c (sha512_final): Ditto.
+       * cipher/tiger.c (tiger_final): Ditto.
+
+       rijndael: fix compiler warnings on ARM.
+       * cipher/rijndael-internal.h (RIJNDAEL_context_s): Add u32 variants of
+       keyschedule arrays to unions u1 and u2.
+       (keyschedenc32, keyscheddec32): New.
+       * cipher/rijndael.c (u32_a_t): Remove.
+       (do_setkey): Add and use tkk[].data32, k_u32, tk_u32 and W_u32; Remove
+       casting byte arrays to u32_a_t.
+       (prepare_decryption, do_encrypt_fn, do_decrypt_fn): Use keyschedenc32
+       and keyscheddec32; Remove casting byte arrays to u32_a_t.
+
+2014-12-23  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Poly1305-AEAD: updated implementation to match draft-irtf-cfrg-chacha20-poly1305-03
+       * cipher/cipher-internal.h (gcry_cipher_handle): Use separate byte
+       counters for AAD and data in Poly1305.
+       * cipher/cipher-poly1305.c (poly1305_fill_bytecount): Remove.
+       (poly1305_fill_bytecounts, poly1305_do_padding): New.
+       (poly1305_aad_finish): Fill padding to Poly1305 and do not fill AAD
+       length.
+       (_gcry_cipher_poly1305_authenticate, _gcry_cipher_poly1305_encrypt)
+       (_gcry_cipher_poly1305_decrypt): Update AAD and data length separately.
+       (_gcry_cipher_poly1305_tag): Fill padding and bytecounts to Poly1305.
+       (_gcry_cipher_poly1305_setkey, _gcry_cipher_poly1305_setiv): Reset
+       AAD and data byte counts; only allow 96-bit IV.
+       * cipher/cipher.c (_gcry_cipher_open_internal): Limit Poly1305-AEAD to
+       ChaCha20 cipher.
+       * tests/basic.c (_check_poly1305_cipher): Update test-vectors.
+       (check_ciphers): Limit Poly1305-AEAD checks to ChaCha20.
+       * tests/bench-slope.c (cipher_bench_one): Ditto.
+
+       chacha20: allow setting counter for stream random access.
+       * cipher/chacha20.c (CHACHA20_CTR_SIZE): New.
+       (chacha20_ivsetup): Add setup for full counter.
+       (chacha20_setiv): Allow ivlen == CHACHA20_CTR_SIZE.
+
+       gcm: do not pass extra key pointer for setupM/fillM.
+       * cipher/cipher-gcm-intel-pclmul.c
+       (_gcry_ghash_setup_intel_pclmul): Remove 'h' parameter.
+       * cipher/cipher-gcm.c (_gcry_ghash_setup_intel_pclmul): Ditto.
+       (fillM): Get 'h' pointer from 'c'.
+       (setupM): Remome 'h' parameter.
+       (_gcry_cipher_gcm_setkey): Only pass 'c' to setupM.
+
+       rijndael: use more compact look-up tables and add table prefetching.
+       * cipher/rijndael-internal.h (rijndael_prefetchfn_t): New.
+       (RIJNDAEL_context): Add 'prefetch_enc_fn' and 'prefetch_dec_fn'.
+       * cipher/rijndael-tables.h (S, T1, T2, T3, T4, T5, T6, T7, T8, S5, U1)
+       (U2, U3, U4): Remove.
+       (encT, dec_tables, decT, inv_sbox): Add.
+       * cipher/rijndael.c (_gcry_aes_amd64_encrypt_block)
+       (_gcry_aes_amd64_decrypt_block, _gcry_aes_arm_encrypt_block)
+       (_gcry_aes_arm_encrypt_block): Add parameter for passing table pointer
+       to assembly implementation.
+       (prefetch_table, prefetch_enc, prefetch_dec): New.
+       (do_setkey): Setup context prefetch functions depending on selected
+       rijndael implementation; Use new tables for key setup.
+       (prepare_decryption): Use new tables for decryption key setup.
+       (do_encrypt_aligned): Rename to...
+       (do_encrypt_fn): ... to this, change to use new compact tables,
+       make handle unaligned input and unroll rounds loop by two.
+       (do_encrypt): Remove handling of unaligned input/output; pass table
+       pointer to assembly implementations.
+       (rijndael_encrypt, _gcry_aes_cfb_enc, _gcry_aes_cbc_enc)
+       (_gcry_aes_ctr_enc, _gcry_aes_cfb_dec): Prefetch encryption tables
+       before encryption.
+       (do_decrypt_aligned): Rename to...
+       (do_decrypt_fn): ... to this, change to use new compact tables,
+       make handle unaligned input and unroll rounds loop by two.
+       (do_decrypt): Remove handling of unaligned input/output; pass table
+       pointer to assembly implementations.
+       (rijndael_decrypt, _gcry_aes_cbc_dec): Prefetch decryption tables
+       before decryption.
+       * cipher/rijndael-amd64.S: Use 1+1.25 KiB tables for
+       encryption+decryption; remove tables from assembly file.
+       * cipher/rijndael-arm.S: Ditto.
+
+2014-12-15  Werner Koch  <wk@gnupg.org>
+
+       build: Add configure option --disable-doc.
+       * Makefile.am (AUTOMAKE_OPTIONS): Remove.
+       (doc) [!BUILD_DOC]: Do not recurse into the dir.
+       * configure.ac (AM_INIT_AUTOMAKE): Add option formerly in Makefile.am.
+       (BUILD_DOC): Add new am_conditional.
+
+2014-12-12  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       rijndael: further optimizations for AES-NI accelerated CBC and CFB bulk modes
+       * cipher/rijndael-aesni.c (do_aesni_enc, do_aesni_dec): Pass
+       input/output through SSE register XMM0.
+       (do_aesni_cfb): Remove.
+       (_gcry_aes_aesni_encrypt, _gcry_aes_aesni_decrypt): Add loading/storing
+       input/output to/from XMM0.
+       (_gcry_aes_aesni_cfb_enc, _gcry_aes_aesni_cbc_enc)
+       (_gcry_aes_aesni_cfb_dec): Update to use renewed 'do_aesni_enc' and
+       move IV loading/storing outside loop.
+       (_gcry_aes_aesni_cbc_dec): Update to use renewed 'do_aesni_dec'.
+
+       GCM: move Intel PCLMUL accelerated implementation to separate file.
+       * cipher/Makefile.am: Add 'cipher-gcm-intel-pclmul.c'.
+       * cipher/cipher-gcm-intel-pclmul.c: New.
+       * cipher/cipher-gcm.c [GCM_USE_INTEL_PCLMUL]
+       (_gcry_ghash_setup_intel_pclmul, _gcry_ghash_intel_pclmul): New
+       prototypes.
+       [GCM_USE_INTEL_PCLMUL] (gfmul_pclmul, gfmul_pclmul_aggr4): Move
+       to 'cipher-gcm-intel-pclmul.c'.
+       (ghash): Rename to...
+       (ghash_internal): ...this and move GCM_USE_INTEL_PCLMUL part to new
+       function in 'cipher-gcm-intel-pclmul.c'.
+       (setupM): Move GCM_USE_INTEL_PCLMUL part to new function in
+       'cipher-gcm-intel-pclmul.c'; Add selection of ghash function based
+       on available HW acceleration.
+       (do_ghash_buf): Change use of 'ghash' to 'c->u_mode.gcm.ghash_fn'.
+       * cipher/internal.h (ghash_fn_t): New.
+       (gcry_cipher_handle): Remove 'use_intel_pclmul'; Add 'ghash_fn'.
+
+2014-12-06  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       rijndael: split Padlock part to separate file.
+       * cipher/Makefile.am: Add 'rijndael-padlock.c'.
+       * cipher/rijndael-padlock.c: New.
+       * cipher/rijndael.c (do_padlock, do_padlock_encrypt)
+       (do_padlock_decrypt): Move to 'rijndael-padlock.c'.
+       * configure.ac [mpi_cpu_arch=x86]: Add 'rijndael-padlock.lo'.
+
+2014-12-01  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       rijndael: refactor to reduce number of #ifdefs and branches.
+       * cipher/rijndael-aesni.c (_gcry_aes_aesni_encrypt)
+       (_gcry_aes_aesni_decrypt): Make return stack burn depth.
+       * cipher/rijndael-amd64.S (_gcry_aes_amd64_encrypt_block)
+       (_gcry_aes_amd64_decrypt_block): Ditto.
+       * cipher/rijndael-arm.S (_gcry_aes_arm_encrypt_block)
+       (_gcry_aes_arm_decrypt_block): Ditto.
+       * cipher/rijndael-internal.h (RIJNDAEL_context_s)
+       (rijndael_cryptfn_t): New.
+       (RIJNDAEL_context): New members 'encrypt_fn' and 'decrypt_fn'.
+       * cipher/rijndael.c (_gcry_aes_amd64_encrypt_block)
+       (_gcry_aes_amd64_decrypt_block, _gcry_aes_aesni_encrypt)
+       (_gcry_aes_aesni_decrypt, _gcry_aes_arm_encrypt_block)
+       (_gcry_aes_arm_decrypt_block): Change prototypes.
+       (do_padlock_encrypt, do_padlock_decrypt): New.
+       (do_setkey): Separate key-length to rounds conversion from
+       HW features check; Add selection for ctx->encrypt_fn and
+       ctx->decrypt_fn.
+       (do_encrypt_aligned, do_decrypt_aligned): Move inside
+       '[!USE_AMD64_ASM && !USE_ARM_ASM]'; Move USE_AMD64_ASM and
+       USE_ARM_ASM to...
+       (do_encrypt, do_decrypt): ...here; Return stack depth; Remove second
+       temporary buffer from non-aligned input/output case.
+       (do_padlock): Move decrypt_flag to last argument; Return stack depth.
+       (rijndael_encrypt): Remove #ifdefs, just call ctx->encrypt_fn.
+       (_gcry_aes_cfb_enc, _gcry_aes_cbc_enc): Remove USE_PADLOCK; Call
+       ctx->encrypt_fn in place of do_encrypt/do_encrypt_aligned.
+       (_gcry_aes_ctr_enc): Call ctx->encrypt_fn in place of
+       do_encrypt_aligned; Make tmp buffer 16-byte aligned and wipe buffer
+       after use.
+       (rijndael_encrypt): Remove #ifdefs, just call ctx->decrypt_fn.
+       (_gcry_aes_cfb_dec): Remove USE_PADLOCK; Call ctx->decrypt_fn in place
+       of do_decrypt/do_decrypt_aligned.
+       (_gcry_aes_cbc_dec): Ditto; Make savebuf buffer 16-byte aligned.
+
+       rijndael: move AES-NI blocks before Padlock.
+       * cipher/rijndael.c (do_setkey, rijndael_encrypt, _gcry_aes_cfb_enc)
+       (rijndael_decrypt, _gcry_aes_cfb_dec): Move USE_AESNI before
+       USE_PADLOCK.
+       (check_decryption_praparation) [USE_PADLOCK]: Move to...
+       (prepare_decryption) [USE_PADLOCK]: ...here.
+
+       rijndael: split AES-NI functions to separate file.
+       * cipher/Makefile.in: Add 'rijndael-aesni.c'.
+       * cipher/rijndael-aesni.c: New.
+       * cipher/rijndael-internal.h: New.
+       * cipher/rijndael.c (MAXKC, MAXROUNDS, BLOCKSIZE, ATTR_ALIGNED_16)
+       (USE_AMD64_ASM, USE_ARM_ASM, USE_PADLOCK, USE_AESNI, RIJNDAEL_context)
+       (keyschenc, keyschdec, padlockkey): Move to 'rijndael-internal.h'.
+       (u128_s, aesni_prepare, aesni_cleanup, aesni_cleanup_2_6)
+       (aesni_do_setkey, do_aesni_enc, do_aesni_dec, do_aesni_enc_vec4)
+       (do_aesni_dec_vec4, do_aesni_cfb, do_aesni_ctr, do_aesni_ctr_4): Move
+       to 'rijndael-aesni.c'.
+       (prepare_decryption, rijndael_encrypt, _gcry_aes_cfb_enc)
+       (_gcry_aes_cbc_enc, _gcry_aes_ctr_enc, rijndael_decrypt)
+       (_gcry_aes_cfb_dec, _gcry_aes_cbc_dec) [USE_AESNI]: Move to functions
+       in 'rijdael-aesni.c'.
+       * configure.ac [mpi_cpu_arch=x86]: Add 'rijndael-aesni.lo'.
+
+2014-11-24  Werner Koch  <wk@gnupg.org>
+
+       Remove duplicated prototypes.
+       * src/gcrypt-int.h (_gcry_mpi_ec_new, _gcry_mpi_ec_set_mpi)
+       (gcry_mpi_ec_set_point): Remove.
+
+       tests: Add a prime mode to benchmark.
+       * tests/benchmark.c (progress_cb): Add a single char mode.
+       (prime_bench): New.
+       (main): Add a "prime" mode.  Factor with_progress out to file scope.
+
+2014-11-19  NIIBE Yutaka  <gniibe@fsij.org>
+
+       ecc: Improve Montgomery curve implementation.
+       * cipher/ecc-curves.c (_gcry_ecc_fill_in_curve): Support
+       MPI_EC_MONTGOMERY.
+       * cipher/ecc.c (test_ecdh_only_keys): New.
+       (nist_generate_key): Call test_ecdh_only_keys for MPI_EC_MONTGOMERY.
+       (check_secret_key): Handle Montgomery curve of x-coordinate only.
+       * mpi/ec.c (_gcry_mpi_ec_mul_point): Resize points before the loop.
+       Simplify, using pointers of Q1, Q2, PRD, and SUM.
+
+2014-11-02  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Disable NEON for CPUs that are known to have broken NEON implementation.
+       * src/hwf-arm.c (detect_arm_proc_cpuinfo): Add parsing for CPU version
+       information and check if CPU is known to have broken NEON
+       implementation.
+       (_gcry_hwf_detect_arm): Filter out broken HW features.
+
+       Add ARM/NEON implementation of Poly1305.
+       * cipher/Makefile.am: Add 'poly1305-armv7-neon.S'.
+       * cipher/poly1305-armv7-neon.S: New.
+       * cipher/poly1305-internal.h (POLY1305_USE_NEON)
+       (POLY1305_NEON_BLOCKSIZE, POLY1305_NEON_STATESIZE)
+       (POLY1305_NEON_ALIGNMENT): New.
+       * cipher/poly1305.c [POLY1305_USE_NEON]
+       (_gcry_poly1305_armv7_neon_init_ext)
+       (_gcry_poly1305_armv7_neon_finish_ext)
+       (_gcry_poly1305_armv7_neon_blocks, poly1305_armv7_neon_ops): New.
+       (_gcry_poly1305_init) [POLY1305_USE_NEON]: Select NEON implementation
+       if HWF_ARM_NEON set.
+       * configure.ac [neonsupport=yes]: Add 'poly1305-armv7-neon.lo'.
+
+       chacha20: add ARMv7/NEON implementation.
+       * cipher/Makefile.am: Add 'chacha20-armv7-neon.S'.
+       * cipher/chacha20-armv7-neon.S: New.
+       * cipher/chacha20.c (USE_NEON): New.
+       [USE_NEON] (_gcry_chacha20_armv7_neon_blocks): New.
+       (chacha20_do_setkey) [USE_NEON]: Use Neon implementation if
+       HWF_ARM_NEON flag set.
+       (selftest): Self-test encrypting buffer byte by byte.
+       * configure.ac [neonsupport=yes]: Add 'chacha20-armv7-neon.lo'.
+
+2014-10-08  Markus Teich  <markus.teich@stusta.mhn.de>
+
+       mpi: Add gcry_mpi_ec_sub.
+       * NEWS (gcry_mpi_ec_sub): New.
+       * doc/gcrypt.texi (gcry_mpi_ec_sub): New.
+       * mpi/ec.c (_gcry_mpi_ec_sub, sub_points_edwards): New.
+       (sub_points_montgomery, sub_points_weierstrass): New stubs.
+       * src/gcrypt-int.h (_gcry_mpi_ec_sub): New.
+       * src/gcrypt.h.in (gcry_mpi_ec_sub): New.
+       * src/libgcrypt.def (gcry_mpi_ec_sub): New.
+       * src/libgcrypt.vers (gcry_mpi_ec_sub): New.
+       * src/mpi.h (_gcry_mpi_ec_sub_points): New.
+       * src/visibility.c (gcry_mpi_ec_sub): New.
+       * src/visibility.h (gcry_mpi_ec_sub): New.
+
+2014-10-08  Werner Koch  <wk@gnupg.org>
+
+       Fix prime test for 2 and lower and add check command to mpicalc.
+       * cipher/primegen.c (check_prime): Return true for the small primes.
+       (_gcry_prime_check): Return correct values for 2 and lower numbers.
+
+       * src/mpicalc.c (do_primecheck): New.
+       (main): Add command 'P'.
+       (main): Allow for larger input data.
+
+2014-10-04  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Add Whirlpool AMD64/SSE2 assembly implementation.
+       * cipher/Makefile.am: Add 'whirlpool-sse2-amd64.S'.
+       * cipher/whirlpool-sse2-amd64.S: New.
+       * cipher/whirlpool.c (USE_AMD64_ASM): New.
+       (whirlpool_tables_s): New.
+       (rc, C0, C1, C2, C3, C4, C5, C6, C7): Combine these tables into single
+       structure and replace old tables with macros of same name.
+       (tab): New structure containing above tables.
+       [USE_AMD64_ASM] (_gcry_whirlpool_transform_amd64)
+       (whirlpool_transform): New.
+       * configure.ac [host=x86_64]: Add 'whirlpool-sse2-amd64.lo'.
+
+2014-10-04  Andrei Scherer  <andsch@inbox.com>
+
+       Improved ripemd160 performance.
+       * cipher/rmd160.c (transform): Interleave the left and right lane
+       rounds to introduce more instruction level parallelism.
+
+2014-10-02  Werner Koch  <wk@gnupg.org>
+
+       build: Document SYSROOT.
+       * configure.ac: Mark SYSROOT as arg var.
+
+       build: Support SYSROOT based config script finding.
+       * src/libgcrypt.m4: Add support for SYSROOT and set
+       gpg_config_script_warn.  Use AC_PATH_PROG instead of AC_PATH_TOOL
+       because the config script is not expected to be installed with a
+       prefix for its name
+       * configure.ac: Print a library mismatch warning.
+       * m4/gpg-error.m4: Update from git master.
+
+2014-09-30  Werner Koch  <wk@gnupg.org>
+
+       mac: Fix gcry_mac_close to allow for a NULL handle.
+       * cipher/mac.c (_gcry_mac_close): Check for NULL.
+
+2014-09-03  Werner Koch  <wk@gnupg.org>
+
+       Add a constant for a forthcoming new RNG.
+       * src/gcrypt.h.in (GCRYCTL_DRBG_REINIT): New constant.
+
+2014-09-02  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Add new Poly1305 MAC test vectors.
+       * tests/basic.c (check_mac): Add new test vectors for Poly1305 MAC.
+
+2014-09-02  Werner Koch  <wk@gnupg.org>
+
+       asm: Allow building x86 and amd64 using old compilers.
+       * src/hwf-x86.c (get_xgetbv): Build only if AVX support is enabled.
+
+2014-08-21  Werner Koch  <wk@gnupg.org>
 
        sexp: Check args of gcry_sexp_build.
        * src/sexp.c (do_vsexp_sscan): Return error for invalid args.
        (generate_using_x): Take care of _gcry_generate_elg_prime return code.
        (elg_generate): Propagate return code from generate.
 
-2014-08-20  Werner Koch  <wk@gnupg.org>
+2014-08-12  NIIBE Yutaka  <gniibe@fsij.org>
+
+       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.
+
+2014-08-09  Werner Koch  <wk@gnupg.org>
+
+       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".
+
+2014-08-08  NIIBE Yutaka  <gniibe@fsij.org>
+
+       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.
+
+2014-08-05  Werner Koch  <wk@gnupg.org>
+
+       mpi: Fix regression for powerpc-apple-darwin detection.
+       * mpi/config.links: Add separate entry for powerpc-apple-darwin.
+
+       Fix bug inhibiting the use of the sentinel attribute.
+       * src/gcrypt.h.in: Fix typo in macro.
+
+       mpi: Use BSD syntax for x86_64-apple-darwin.
+       * mpi/config.links: Add case for x86_64-apple-darwin.
+
+2014-08-05  Kristian Fiskerstrand  <kf@sumptuouscapital.com>
+
+       Fix building for the x32 target without asm modules.
+       * mpi/generic/mpi-asm-defs.h: Use a fixed value for the x32 ABI.
+
+2014-07-25  Werner Koch  <wk@gnupg.org>
 
        ecc: Support the non-standard 0x40 compression flag for EdDSA.
        * cipher/ecc.c (ecc_generate): Check the "comp" flag for EdDSA.
        * mpi/mpicoder.c (do_get_buffer): Add arg EXTRAALLOC.
        (_gcry_mpi_get_buffer_extra): New.
 
-2014-08-05  Werner Koch  <wk@gnupg.org>
+       cipher: Fix compiler warning for chacha20.
+       * cipher/chacha20.c (chacha20_blocks) [!USE_SSE2]: Do not build.
 
-       mpi: Fix regression for powerpc-apple-darwin detection.
-       * mpi/config.links: Add separate entry for powerpc-apple-darwin.
+2014-07-16  NIIBE Yutaka  <gniibe@fsij.org>
 
-       Fix bug inhibiting the use of the sentinel attribute.
-       * src/gcrypt.h.in: Fix typo in macro.
+       mpi: Add mpi_swap_cond.
+       * mpi/mpiutil.c (_gcry_mpi_swap_cond): New.
+       * src/mpi.h (mpi_swap_cond): New.
 
-       mpi: Use BSD syntax for x86_64-apple-darwin.
-       * mpi/config.links: Add case for x86_64-apple-darwin.
+2014-06-29  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
 
-2014-08-05  Kristian Fiskerstrand  <kf@sumptuouscapital.com>
+       Speed-up SHA-1 NEON assembly implementation.
+       * cipher/sha1-armv7-neon.S: Tweak implementation for speed-up.
 
-       Fix building for the x32 target without asm modules.
-       * mpi/generic/mpi-asm-defs.h: Use a fixed value for the x32 ABI.
+2014-06-28  Dmitry Eremin-Solenikov  <dbaryshkov@gmail.com>
+
+       gostr3411_94: rewrite to use u32 mathematic.
+       * cipher/gost28147.c (_gcry_gost_enc_data): New.
+       * cipher/gostr3411-94.c: Rewrite implementation to use u32 mathematic
+         internally.
+       * cipher/gost28147.c (_gcry_gost_enc_one): Remove.
+
+       gost28147: use bufhelp helpers.
+       * cipher/gost28147.c (gost_setkey, gost_encrypt_block, gost_decrypt_block):
+         use buf_get_le32/buf_put_le32 helpers.
+
+       Fixup curve name in the GOST2012 test case.
+       * tests/basic.c (check_pubkey): fixup curve name in public key.
+
+       Update PBKDF2 tests with GOST R 34.11-94 test cases.
+       * tests/t-kdf.c (check_pbkdf2): Add MD_GOSTR3411_CP test cases.
+
+       Add GOST R 34.11-94 variant using id-GostR3411-94-CryptoProParamSet.
+       * src/gcrypt.h.in (GCRY_MD_GOSTR3411_CP): New.
+       * src/cipher.h (_gcry_digest_spec_gost3411_cp): New.
+       * cipher/gost28147.c (_gcry_gost_enc_one): Differentiate between
+         CryptoPro and Test S-Boxes.
+       * cipher/gostr3411-94.c (_gcry_digest_spec_gost3411_cp,
+         gost3411_cp_init): New.
+       * cipher/md.c (md_open): GCRY_MD_GOSTR3411_CP also uses B=32.
+
+       gost28147: support GCRYCTL_SET_SBOX.
+       cipher/gost28147.c (gost_set_extra_info, gost_set_sbox): New.
+
+       Support setting s-box for the ciphers that require it.
+       * src/gcrypt.h.in (GCRYCTL_SET_SBOX, gcry_cipher_set_sbox): New.
+       * cipher/cipher.c (_gcry_cipher_ctl): pass GCRYCTL_SET_SBOX to
+         set_extra_info callback.
+
+       cipher/gost28147: generate optimized s-boxes from compact ones.
+       * cipher/gost-s-box.c: New. Outputs optimized expanded representation of
+         s-boxes (4x256) from compact 16x8 representation.
+       * cipher/Makefile.am: Add gost-sb.h dependency to gost28147.lo
+       * cipher/gost.h: Add sbox to the GOST28147_context structure.
+       * cipher/gost28147.c (gost_setkey): Set default s-box to test s-box from
+         GOST R 34.11 (this was the only one S-box before).
+       * cipher/gost28147.c (gost_val): Use sbox from the context.
+
+       gost28147: add OIDs used to define cipher mode.
+       * cipher/gost28147 (oids_gost28147): Add OID from RFC4357.
+
+       GOST R 34.11-94 add OIDs.
+       * cipher/gostr3411-94.c: Add OIDs for GOST R 34.11-94 from RFC 4357.
+
+2014-05-21  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       tests: add larger test-vectors for hash algorithms.
+       * tests/basic.c (check_digests): Add large test-vectors for MD5, SHA1,
+       SHA224, SHA256, SHA384, RMD160, CRC32, TIGER1, WHIRLPOOL and
+       GOSTR3411_94.
+
+       sha512: fix ARM/NEON implementation.
+       * cipher/sha512-armv7-neon.S
+       (_gcry_sha512_transform_armv7_neon): Byte-swap RW67q and RW1011q
+       correctly in multi-block loop.
+       * tests/basic.c (check_digests): Add large test vector for SHA512.
 
 2014-05-20  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
 
        * cipher/rijndael-arm.S (GET_DATA_POINTER): New.
        (_gcry_aes_arm_encrypt_block, _gcry_aes_arm_decrypt_block): Use
        GET_DATA_POINTER.
+       * cipher/sha1-armv7-neon.S (GET_DATA_POINTER): New.
+       (.LK_VEC): Move from .text to .data section.
+       (_gcry_sha1_transform_armv7_neon): Use GET_DATA_POINTER.
+
+2014-05-17  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Add Poly1305 to documentation.
+       * doc/gcrypt.texi: Add documentation for Poly1305 MACs and AEAD mode.
+
+2014-05-16  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       chacha20: add SSE2/AMD64 optimized implementation.
+       * cipher/Makefile.am: Add 'chacha20-sse2-amd64.S'.
+       * cipher/chacha20-sse2-amd64.S: New.
+       * cipher/chacha20.c (USE_SSE2): New.
+       [USE_SSE2] (_gcry_chacha20_amd64_sse2_blocks): New.
+       (chacha20_do_setkey) [USE_SSE2]: Use SSE2 implementation for blocks
+       function.
+       * configure.ac [host=x86-64]: Add 'chacha20-sse2-amd64.lo'.
+
+       poly1305: add AMD64/AVX2 optimized implementation.
+       * cipher/Makefile.am: Add 'poly1305-avx2-amd64.S'.
+       * cipher/poly1305-avx2-amd64.S: New.
+       * cipher/poly1305-internal.h (POLY1305_USE_AVX2)
+       (POLY1305_AVX2_BLOCKSIZE, POLY1305_AVX2_STATESIZE)
+       (POLY1305_AVX2_ALIGNMENT): New.
+       (POLY1305_LARGEST_BLOCKSIZE, POLY1305_LARGEST_STATESIZE)
+       (POLY1305_STATE_ALIGNMENT): Use AVX2 versions when needed.
+       * cipher/poly1305.c [POLY1305_USE_AVX2]
+       (_gcry_poly1305_amd64_avx2_init_ext)
+       (_gcry_poly1305_amd64_avx2_finish_ext)
+       (_gcry_poly1305_amd64_avx2_blocks, poly1305_amd64_avx2_ops): New.
+       (_gcry_poly1305_init) [POLY1305_USE_AVX2]: Use AVX2 implementation if
+       AVX2 supported by CPU.
+       * configure.ac [host=x86_64]: Add 'poly1305-avx2-amd64.lo'.
+
+2014-05-12  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       poly1305: add AMD64/SSE2 optimized implementation.
+       * cipher/Makefile.am: Add 'poly1305-sse2-amd64.S'.
+       * cipher/poly1305-internal.h (POLY1305_USE_SSE2)
+       (POLY1305_SSE2_BLOCKSIZE, POLY1305_SSE2_STATESIZE)
+       (POLY1305_SSE2_ALIGNMENT): New.
+       (POLY1305_LARGEST_BLOCKSIZE, POLY1305_LARGEST_STATESIZE)
+       (POLY1305_STATE_ALIGNMENT): Use SSE2 versions when needed.
+       * cipher/poly1305-sse2-amd64.S: New.
+       * cipher/poly1305.c [POLY1305_USE_SSE2]
+       (_gcry_poly1305_amd64_sse2_init_ext)
+       (_gcry_poly1305_amd64_sse2_finish_ext)
+       (_gcry_poly1305_amd64_sse2_blocks, poly1305_amd64_sse2_ops): New.
+       (_gcry_polu1305_init) [POLY1305_USE_SSE2]: Use SSE2 version.
+       * configure.ac [host=x86_64]: Add 'poly1305-sse2-amd64.lo'.
+
+       Add Poly1305 based cipher AEAD mode.
+       * cipher/Makefile.am: Add 'cipher-poly1305.c'.
+       * cipher/cipher-internal.h (gcry_cipher_handle): Add 'u_mode.poly1305'.
+       (_gcry_cipher_poly1305_encrypt, _gcry_cipher_poly1305_decrypt)
+       (_gcry_cipher_poly1305_setiv, _gcry_cipher_poly1305_authenticate)
+       (_gcry_cipher_poly1305_get_tag, _gcry_cipher_poly1305_check_tag): New.
+       * cipher/cipher-poly1305.c: New.
+       * cipher/cipher.c (_gcry_cipher_open_internal, cipher_setkey)
+       (cipher_reset, cipher_encrypt, cipher_decrypt, _gcry_cipher_setiv)
+       (_gcry_cipher_authenticate, _gcry_cipher_gettag)
+       (_gcry_cipher_checktag): Handle 'GCRY_CIPHER_MODE_POLY1305'.
+       (cipher_setiv): Move handling of 'GCRY_CIPHER_MODE_GCM' to ...
+       (_gcry_cipher_setiv): ... here, as with other modes.
+       * src/gcrypt.h.in: Add 'GCRY_CIPHER_MODE_POLY1305'.
+       * tests/basic.c (_check_poly1305_cipher, check_poly1305_cipher): New.
+       (check_ciphers): Add Poly1305 check.
+       (check_cipher_modes): Call 'check_poly1305_cipher'.
+       * tests/bench-slope.c (bench_gcm_encrypt_do_bench): Rename to
+       bench_aead_... and take nonce as argument.
+       (bench_gcm_decrypt_do_bench, bench_gcm_authenticate_do_bench): Ditto.
+       (bench_gcm_encrypt_do_bench, bench_gcm_decrypt_do_bench)
+       (bench_gcm_authenticate_do_bench, bench_poly1305_encrypt_do_bench)
+       (bench_poly1305_decrypt_do_bench)
+       (bench_poly1305_authenticate_do_bench, poly1305_encrypt_ops)
+       (poly1305_decrypt_ops, poly1305_authenticate_ops): New.
+       (cipher_modes): Add Poly1305.
+       (cipher_bench_one): Add special handling for Poly1305.
+
+       Add Poly1305-AES (-Camellia, etc) MACs.
+       * cipher/mac-internal.h (_gcry_mac_type_spec_poly1305_aes)
+       (_gcry_mac_type_spec_poly1305_camellia)
+       (_gcry_mac_type_spec_poly1305_twofish)
+       (_gcry_mac_type_spec_poly1305_serpent)
+       (_gcry_mac_type_spec_poly1305_seed): New.
+       * cipher/mac-poly1305.c (poly1305mac_context_s): Add 'hd' and
+       'nonce_set'.
+       (poly1305mac_open, poly1305mac_close, poly1305mac_setkey): Add handling
+       for Poly1305-*** MACs.
+       (poly1305mac_prepare_key, poly1305mac_setiv): New.
+       (poly1305mac_reset, poly1305mac_write, poly1305mac_read): Add handling
+       for 'nonce_set'.
+       (poly1305mac_ops): Add 'poly1305mac_setiv'.
+       (_gcry_mac_type_spec_poly1305_aes)
+       (_gcry_mac_type_spec_poly1305_camellia)
+       (_gcry_mac_type_spec_poly1305_twofish)
+       (_gcry_mac_type_spec_poly1305_serpent)
+       (_gcry_mac_type_spec_poly1305_seed): New.
+       * cipher/mac.c (mac_list): Add Poly1305-AES, Poly1305-Twofish,
+       Poly1305-Serpent, Poly1305-SEED and Poly1305-Camellia.
+       * src/gcrypt.h.in: Add 'GCRY_MAC_POLY1305_AES',
+       'GCRY_MAC_POLY1305_CAMELLIA', 'GCRY_MAC_POLY1305_TWOFISH',
+       'GCRY_MAC_POLY1305_SERPENT' and 'GCRY_MAC_POLY1305_SEED'.
+       * tests/basic.c (check_mac): Add Poly1305-AES test vectors.
+       * tests/bench-slope.c (bench_mac_init): Set IV for Poly1305-*** MACs.
+       * tests/bench-slope.c (mac_bench): Set IV for Poly1305-*** MACs.
+
+       Add Poly1305 MAC.
+       * cipher/Makefile.am: Add 'mac-poly1305.c', 'poly1305.c' and
+       'poly1305-internal.h'.
+       * cipher/mac-internal.h (poly1305mac_context_s): New.
+       (gcry_mac_handle): Add 'u.poly1305mac'.
+       (_gcry_mac_type_spec_poly1305mac): New.
+       * cipher/mac-poly1305.c: New.
+       * cipher/mac.c (mac_list): Add Poly1305.
+       * cipher/poly1305-internal.h: New.
+       * cipher/poly1305.c: New.
+       * src/gcrypt.h.in: Add 'GCRY_MAC_POLY1305'.
+       * tests/basic.c (check_mac): Add Poly1035 test vectors; Allow
+       overriding lengths of data and key buffers.
+       * tests/bench-slope.c (mac_bench): Increase max algo number from 500 to
+       600.
+       * tests/benchmark.c (mac_bench): Ditto.
+
+       chacha20/AVX2: clear upper-halfs of YMM registers on entry.
+       * cipher/chacha20-avx2-amd64.S (_gcry_chacha20_amd64_avx2_blocks): Add
+       'vzeroupper' at beginning.
+
+       chacha20/AVX2: check for ENABLE_AVX2_SUPPORT instead of HAVE_GCC_INLINE_ASM_AVX2
+       * cipher/chacha20.c (USE_AVX2): Enable depending on
+       ENABLE_AVX2_SUPPORT, not HAVE_GCC_INLINE_ASM_AVX2.
+       * cipher/chacha20-avx2-amd64.S: Ditto.
+
+       chacha20/SSSE3: clear XMM registers after use.
+       * cipher/chacha20-ssse3-amd64.S (_gcry_chacha20_amd64_ssse3_blocks): On
+       return, clear XMM registers.
+
+2014-05-11  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       chacha20: add AVX2/AMD64 assembly implementation.
+       * cipher/Makefile.am: Add 'chacha20-avx2-amd64.S'.
+       * cipher/chacha20-avx2-amd64.S: New.
+       * cipher/chacha20.c (USE_AVX2): New macro.
+       [USE_AVX2] (_gcry_chacha20_amd64_avx2_blocks): New.
+       (chacha20_do_setkey): Select AVX2 implementation if there is HW
+       support.
+       (selftest): Increase size of buf by 256.
+       * configure.ac [host=x86-64]: Add 'chacha20-avx2-amd64.lo'.
+
+       chacha20: add SSSE3 assembly implementation.
+       * cipher/Makefile.am: Add 'chacha20-ssse3-amd64.S'.
+       * cipher/chacha20-ssse3-amd64.S: New.
+       * cipher/chacha20.c (USE_SSSE3): New macro.
+       [USE_SSSE3] (_gcry_chacha20_amd64_ssse3_blocks): New.
+       (chacha20_do_setkey): Select SSSE3 implementation if there is HW
+       support.
+       * configure.ac [host=x86-64]: Add 'chacha20-ssse3-amd64.lo'.
+
+       Add ChaCha20 stream cipher.
+       * cipher/Makefile.am: Add 'chacha20.c'.
+       * cipher/chacha20.c: New.
+       * cipher/cipher.c (cipher_list): Add ChaCha20.
+       * configure.ac: Add ChaCha20.
+       * doc/gcrypt.texi: Add ChaCha20.
+       * src/cipher.h (_gcry_cipher_spec_chacha20): New.
+       * src/gcrypt.h.in (GCRY_CIPHER_CHACHA20): Add new algo.
+       * tests/basic.c (MAX_DATA_LEN): Increase to 128 from 100.
+       (check_stream_cipher): Add ChaCha20 test-vectors.
+       (check_ciphers): Add ChaCha20.
 
 2014-05-09  Werner Koch  <wk@gnupg.org>
 
        allocated but not used bits before resizing.
        * tests/t-mpi-bits.c (set_bit_with_resize): New.
 
-2014-04-24  Werner Koch  <wk@gnupg.org>
+2014-05-07  Werner Koch  <wk@gnupg.org>
 
-       Support building using the latest mingw-w64 toolchain.
-       * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Change mingw detection.
-
-       Use internal malloc function in fips.c.
-       * src/fips.c (check_binary_integrity): s/gcry_malloc/xtrymalloc/.
+       Bump LT version.
+       * configure.ac: Bumb LT version to C21/A1/R0.
 
 2014-04-22  Werner Koch  <wk@gnupg.org>
 
 
 2014-04-16  Werner Koch  <wk@gnupg.org>
 
-       pubkey: Re-map all deprecated RSA algo numbers.
+       pubkey: Re-map all depreccated RSA algo numbers.
        * cipher/pubkey.c (map_algo): Mape RSA_E and RSA_S.
 
+2014-04-15  Werner Koch  <wk@gnupg.org>
+
        cipher: Fix possible NULL dereference.
        * cipher/md.c (_gcry_md_selftest): Check for spec being NULL.
 
-2014-02-20  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+2014-03-30  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       3des: add amd64 assembly implementation for 3DES.
+       * cipher/Makefile.am: Add 'des-amd64.S'.
+       * cipher/cipher-selftests.c (_gcry_selftest_helper_cbc)
+       (_gcry_selftest_helper_cfb, _gcry_selftest_helper_ctr): Handle failures
+       from 'setkey' function.
+       * cipher/cipher.c (_gcry_cipher_open_internal) [USE_DES]: Setup bulk
+       functions for 3DES.
+       * cipher/des-amd64.S: New file.
+       * cipher/des.c (USE_AMD64_ASM, ATTR_ALIGNED_16): New macros.
+       [USE_AMD64_ASM] (_gcry_3des_amd64_crypt_block)
+       (_gcry_3des_amd64_ctr_enc), _gcry_3des_amd64_cbc_dec)
+       (_gcry_3des_amd64_cfb_dec): New prototypes.
+       [USE_AMD64_ASM] (tripledes_ecb_crypt): New function.
+       (TRIPLEDES_ECB_BURN_STACK): New macro.
+       (_gcry_3des_ctr_enc, _gcry_3des_cbc_dec, _gcry_3des_cfb_dec)
+       (bulk_selftest_setkey, selftest_ctr, selftest_cbc, selftest_cfb): New
+       functions.
+       (selftest): Add call to CTR, CBC and CFB selftest functions.
+       (do_tripledes_encrypt, do_tripledes_decrypt): Use
+       TRIPLEDES_ECB_BURN_STACK.
+       * configure.ac [host=x86-64]: Add 'des-amd64.lo'.
+       * src/cipher.h (_gcry_3des_ctr_enc, _gcry_3des_cbc_dec)
+       (_gcry_3des_cfb_dec): New prototypes.
+
+2014-03-13  Werner Koch  <wk@gnupg.org>
+
+       tests: Print diagnostics for skipped tests.
+       * tests/basic.c (show_note): New.
+       (show_md_not_available):
+       (show_old_hmac_not_available):
+       (show_mac_not_available):
+       (check_digests): Remove USE_foo cpp tests from the test table.  Call
+       show_md_not_available if algo is not available.
+       (check_hmac): Likewise.
+       (check_mac): Likewise.
+
+2014-03-11  Dmitry Eremin-Solenikov  <dbaryshkov@gmail.com>
+
+       Add MD2 message digest implementation.
+       * cipher/md2.c: New.
+       * cipher/md.c (digest_list): add _gcry_digest_spec_md2.
+       * tests/basic.c (check_digests): add MD2 test vectors.
+       * configure.ac (default_digests): disable md2 by default.
+
+2014-03-04  Dmitry Eremin-Solenikov  <dbaryshkov@gmail.com>
+
+       Add an utility to calculate hashes over a set of files.
+       * tests/gchash.c: New.
+
+       Add a simple (raw) PKCS#1 padding mode.
+       * src/cipher.h (PUBKEY_ENC_PKCS1_RAW): New.
+       * cipher/pubkey-util.c (_gcry_pk_util_parse_flaglist): Handle pkcs1-raw
+         flag.
+       * cipher/pubkey-util.c (_gcry_pk_util_data_to_mpi):
+         Handle s-exp like (data (flags pkcs1-raw) (value xxxxx))
+       * cipher/rsa-common.c (_gcry_rsa_pkcs1_encode_raw_for_sig):
+         PKCS#1-encode data with embedded hash OID for signature verification.
+       * tests/basic.c (check_pubkey_sign): Add tests for s-exps with pkcs1-raw
+         flag.
+
+2014-02-04  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
 
        Fix ARMv6 detection when CFLAGS modify target CPU architecture.
        * configure.ac (gcry_cv_cc_arm_arch_is_v6): Use compiler test instead
        of preprocessor test.
 
-2014-01-31  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
-
-       Parse /proc/cpuinfo for ARM HW features.
-       * src/hwf-arm.c [__linux__] (HAS_PROC_CPUINFO)
-       (detect_arm_proc_cpuinfo): New.
-       (_gcry_hwf_detect_arm) [HAS_PROC_CPUINFO]: Check '/proc/cpuinfo' for
-       HW features.
-
 2014-01-29  Werner Koch  <wk@gnupg.org>
 
-       cipher: Take care of ENABLE_NEON_SUPPORT.
-       * cipher/salsa20.c (USE_ARM_NEON_ASM): Define only if
-       ENABLE_NEON_SUPPORT is defined.
-       * cipher/serpent.c (USE_NEON): Ditto.
-       * cipher/sha512.c (USE_ARM_NEON_ASM): Ditto.
-
-       Release 1.6.1.
-       * configure.ac: Set LT version to C20/A0/R1.
-
        Reserve control code for FIPS extensions.
        * src/gcrypt.h.in (GCRYCTL_INACTIVATE_FIPS_FLAG): New.
        (GCRYCTL_REACTIVATE_FIPS_FLAG): New.
        * src/global.c (_gcry_vcontrol): Add them but return not_implemented.
 
-       (cherry picked from commit aea96a64fbc58a0b6f9f435e97e93294c6eb1052)
-
-       Support non weak symbol pthread platforms.
-       * m4/lock.m4, m4/threadlib.m4: New.  From libgpg-error master.
-       * m4/Makefile.am (EXTRA_DIST): Add them.
-       * configure.ac (HAVE_PTHREAD): Remove test and ac_define.
-       (gl_LOCK): Do not use under Windows.
-       (LIBGCRYPT_CONFIG_LIBS): Add LIBTHREAD to support non-ELF pthread
-       systems.
-       * src/Makefile.am (dumpsexp_LDADD, mpicalc_LDADD, hmac256_LDADD)
-       (gcryptrnd_LDADD): Add LIBTHREAD.
-       * src/ath.c: Include pthread for any pthread version.
-       (ath_init, ath_install, ath_mutex_init, ath_mutex_destroy)
-       (ath_mutex_lock, ath_mutex_unlock): Support non-weak symbol pthread
-       systems.
-       * tests/Makefile.am (LDADD): Add LIBTHREAD.
-       * tests/t-lock.c: Replace HAVE_PTHREAD by USE_POSIX_THREADS
-       (run_test): Run only under W32 or pthread.
-
-       tests: Remove non-portable format specifiers.
-       * tests/basic.c: Replace "%zi" by "%d" and casts.
-
 2014-01-29  NIIBE Yutaka  <gniibe@fsij.org>
 
        Fix RSA Blinding.
        * cipher/rsa.c (rsa_decrypt): Loop to get multiplicative inverse.
 
-       (cherry picked from commit 121a90d8931944974054f7d94f63b7f89df87fa5)
-
 2014-01-28  Werner Koch  <wk@gnupg.org>
 
+       cipher: Take care of ENABLE_NEON_SUPPORT.
+       * cipher/salsa20.c (USE_ARM_NEON_ASM): Define only if
+       ENABLE_NEON_SUPPORT is defined.
+       * cipher/serpent.c (USE_NEON): Ditto.
+       * cipher/sha1.c (USE_NEON): Ditto.
+       * cipher/sha512.c (USE_ARM_NEON_ASM): Ditto.
+
        sexp: Fix broken gcry_sexp_nth.
        * src/sexp.c (_gcry_sexp_nth): Return a valid S-expression for a data
        element.
        (NODE): Remove unused typedef.
        (ST_HINT): Comment unused macro.
 
-       * tests/tsexp.c (bug_1594): New.
+       * tests/t-sexp.c (bug_1594): New.
        (main): Run new test.
 
 2014-01-27  Werner Koch  <wk@gnupg.org>
 
+       tests: Improve t-common.h.
+       * tests/t-common.h: Add couple of macros.  Check that config.h has
+       been included.
+       (show): Rename to info.
+       * tests/t-lock.c, tests/t-sexp.c: Adjust for changes.
+
        mpi: Minor fix for Atari-mint.
        * mpi/config.links [m68k-atari-mint]: Do not assume 68020.  Suggested
        by Alan Hourihane.
 
-2014-01-27  Dmitry Eremin-Solenikov  <dbaryshkov@gmail.com>
+       (cherry picked from commit 420f42a5752e90a8b27d58ffa1ddfe6e4ab341e8)
 
-       tests: Pass -no-install to libtool.
-       * tests/Makefile.am: add AM_LDFLAGS = -no-install
+2014-01-27  Dmitry Eremin-Solenikov  <dbaryshkov@gmail.com>
 
        Fix most of memory leaks in tests code.
        * tests/basic.c (check_ccm_cipher): Close cipher after use.
          path.
        * cipher/ecc.c (_gcry_ecc_get_curve): Release temporary mpi.
 
-2014-01-24  Werner Koch  <wk@gnupg.org>
+       Fix number of blocks passed used in _gcry_rmd160_mixblock.
+       * cipher/rmd160.c (_gcry_rmd160_mixblock): pass 1 to transform
 
-       Check compiler features only for the relevant platform.
-       * mpi/config.links (mpi_cpu_arch): Always set for ARM.  Set for HPPA.
-       Set to "undefined" for unknown platforms.
-       (try_asm_modules): Act upon only after having detected the CPU.
-       * configure.ac: Move the call to config.links before the platform
-       specific compiler checks.  Check platform specific features only if
-       the platform is targeted.
+2014-01-27  Werner Koch  <wk@gnupg.org>
 
-2014-01-24  Dmitry Eremin-Solenikov  <dbaryshkov@gmail.com>
+       Small Windows build tweaks.
+       * configure.ac (HAVE_PTHREAD): Do test when building for Windows.
 
-       Truncate hash values for ECDSA signature scheme.
-       * cipher/dsa-common (_gcry_dsa_normalize_hash): New. Truncate opaque
-         mpis as required for DSA and ECDSA signature schemas.
-       * cipher/dsa.c (verify): Return gpg_err_code_t value from verify() to
-         behave like the rest of internal sign/verify functions.
-       * cipher/dsa.c (sign, verify, dsa_verify): Factor out hash truncation.
-       * cipher/ecc-ecdsa.c (_gcry_ecc_ecdsa_sign): Factor out hash truncation.
-       * cipher/ecc-ecdsa.c (_gcry_ecc_ecdsa_verify):
-         as required by ECDSA scheme, truncate hash values to bitlength of
-         used curve.
-       * tests/pubkey.c (check_ecc_sample_key): add a testcase for hash
-         truncation.
+       * tests/basic.c: Replace "%zi" by "%z" and a cast to make it work
+       under Windows.
+
+       Update gpg-error autoconf macros to fix threading problems.
+       * m4/gpg-error.m4: Update to version 2014-01-24.
+       * tests/Makefile.am (t_lock_LDADD): Use MT Libs.
 
-       (cherry picked from commit 9edcf1090e0485f9f383b6c54b18ea8ca3d4a225)
+2014-01-24  Dmitry Eremin-Solenikov  <dbaryshkov@gmail.com>
+
+       tests: Pass -no-install to libtool.
+       * tests/Makefile.am: add AM_LDFLAGS = -no-install
 
 2014-01-24  Werner Koch  <wk@gnupg.org>
 
-       Support locking under Windows.
-       * src/ath.c: Add support for Windows.
+       tests: Add a test for the internal locking.
        * src/global.c (external_lock_test): New.
        (_gcry_vcontrol): Call new function with formerly reserved code 61.
 
        (default_ldadd): new.
        (t_lock_LDADD): New.
 
+       Check compiler features only for the relevant platform.
+       * mpi/config.links (mpi_cpu_arch): Always set for ARM.  Set for HPPA.
+       Set to "undefined" for unknown platforms.
+       (try_asm_modules): Act upon only after having detected the CPU.
+       * configure.ac: Move the call to config.links before the platform
+       specific compiler checks.  Check platform specific features only if
+       the platform is targeted.
+
+2014-01-23  Werner Koch  <wk@gnupg.org>
+
+       Support building using the latest mingw-w64 toolchain.
+       * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Change mingw detection.
+
 2014-01-20  Werner Koch  <wk@gnupg.org>
 
-       cipher: Fix commit 77f28793.
+       cipher: Fix commit 94030e44.
        * cipher/tiger.c (tiger_init): Add arg FLAGS.
        (tiger1_init, tiger2_init): Ditto.
 
-       (cherry picked from commit dad06e4d1b835bac778b87090b1d3894b7535b14)
+       tests: Rename tsexp.c.
+       * tests/tsexp.c: Rename to t-sexp.c
+
+2014-01-19  Werner Koch  <wk@gnupg.org>
 
        md: Add Whirlpool bug emulation feature.
        * src/gcrypt.h.in (GCRY_MD_FLAG_BUGEMU1): New.
        (md_enable): Pass bugemu1 flag to the hash init function.
        (_gcry_md_reset): Ditto.
 
+2014-01-17  Werner Koch  <wk@gnupg.org>
+
+       Actually check for uint64_t.
+       * configure.ac: Check size of uint64_t and the UINT64_C macro.
+
+2014-01-16  Werner Koch  <wk@gnupg.org>
+
+       Replace ath based mutexes by gpgrt based locks.
+       * configure.ac (NEED_GPG_ERROR_VERSION): Require 1.13.
+       (gl_LOCK): Remove.
+       * src/ath.c, src/ath.h: Remove.  Remove from all files.  Replace all
+       mutexes by gpgrt based statically initialized locks.
+       * src/global.c (global_init): Remove ath_init.
+       (_gcry_vcontrol): Make ath install a dummy function.
+       (print_config): Remove threads info line.
+
+       * doc/gcrypt.texi: Simplify the multi-thread related documentation.
+
+2014-01-15  NIIBE Yutaka  <gniibe@fsij.org>
+
+       ecc: Fix _gcry_mpi_ec_p_new to allow secp256k1.
+       * mpi/ec.c (_gcry_mpi_ec_p_new): Remove checking a!=0.
+       * tests/t-mpi-point.c (context_alloc): Remove two spurious tests.
+
 2014-01-14  Milan Broz  <gmazyland@gmail.com>
 
        PBKDF2: Use gcry_md_reset to speed up calculation.
        * cipher/bithelp.h (bswap32): Rename to _gcry_bswap32.
        (bswap64): Rename to _gcry_bswap64.
 
+       Use internal malloc function in fips.c.
+       * src/fips.c (check_binary_integrity): s/gcry_malloc/xtrymalloc/.
+
 2014-01-13  Dmitry Eremin-Solenikov  <dbaryshkov@gmail.com>
 
+       Truncate hash values for ECDSA signature scheme.
+       * cipher/dsa-common (_gcry_dsa_normalize_hash): New. Truncate opaque
+         mpis as required for DSA and ECDSA signature schemas.
+       * cipher/dsa.c (verify): Return gpg_err_code_t value from verify() to
+         behave like the rest of internal sign/verify functions.
+       * cipher/dsa.c (sign, verify, dsa_verify): Factor out hash truncation.
+       * cipher/ecc-ecdsa.c (_gcry_ecc_ecdsa_sign): Factor out hash truncation.
+       * cipher/ecc-ecdsa.c (_gcry_ecc_ecdsa_verify):
+         as required by ECDSA scheme, truncate hash values to bitlength of
+         used curve.
+       * tests/pubkey.c (check_ecc_sample_key): add a testcase for hash
+         truncation.
+
+       Add GOST R 34.10-2012 curves proposed by TC26.
+       * cipher/ecc-curves.c (domain_parmss): Add two GOST R 34.10-2012 curves
+         proposed/pending to standardization by TC26 (Russian cryptography
+         technical comitee).
+       * cipher/ecc-curves.c (curve_alias): Add OID aliases.
+       * tests/curves.c: Increase N_CURVES.
+
+       Add GOST R 34.10-2001 curves per RFC4357.
+       * cipher/ecc-curves.c (domain_parms): Add 3 curves defined in rfc4357.
+       * cipher/ecc-curves.c (curve_aliases): Add OID and Xch aliases for GOST
+         curves.
+       * tests/curves.c (N_CURVES): Update value.
+
        Fix typo in search_oid.
        * cipher/md.c (search_oid): Invert condition on oid comparison.
 
+       Add MD2-HMAC calculation support.
+       * src/gcrypt.h.in (GCRY_MAC_HMAC_MD2): New.
+       * cipher/mac-hmac.c: Support GCRY_MAC_HMAC_MD2.
+
+       Add a function to retrieve algorithm used by MAC handler.
+       * cipher/mac.c (_gcry_mac_get_algo): New function, returns used algo.
+       * src/visibility.c (gcry_mac_get_algo): New wrapper.
+       * src/visibility.h: Hanlde gcry_mac_get_algo.
+       * src/gcrypt-int.h (_gcry_mac_get_algo): New.
+       * src/gcrypt.h.in (gcry_mac_get_algo): New.
+       * src/libgcrypt.def (gcry_mac_get_algo): New.
+       * src/libgcrypt.vers (gcry_mac_get_algo): New.
+       * doc/gcrypt.texi: Document gcry_mac_get_algo.
+       * tests/basic.c (check_one_mac): Verify gcry_mac_get_algo.
+
        Correct formatting of gcry_mac_get_algo_keylen documentation.
        * doc/gcrypt.texi: add braces near gcry_mac_get_algo_keylen
          documentation.
        documentation, otherwise texinfo breaks that and uses 'int' as a
        function definition.
 
+2014-01-13  Werner Koch  <wk@gnupg.org>
+
+       ecc: Make a macro shorter.
+       * src/mpi.h (MPI_EC_TWISTEDEDWARDS): Rename to MPI_EC_EDWARDS.  CHnage
+       all users.
+       * cipher/ecc-curves.c (domain_parms): Add parameters for Curve3617 as
+       comment.
+       * mpi/ec.c (dup_point_twistededwards): Rename to dup_point_edwards.
+       (add_points_twistededwards): Rename to add_points_edwards.
+
 2014-01-12  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
 
-       * cipher/Makefile.am: Add 'blowfish-arm.S' and 'serpent-armv7-neon.S'. --
-       Fix for bug https://bugs.g10code.com/gnupg/issue1584
+       Fix assembly division check.
+       * configure.ac (gcry_cv_gcc_as_const_division_ok): Correct variable
+       name mismatch at '--Wa,--divide' workaround check.
 
-       (cherry picked from commit 7fef7f481c0a1542be34d1dc831f58d41846ac29)
+2014-01-12  NIIBE Yutaka  <gniibe@fsij.org>
 
-       Fix buggy/incomplete detection of AVX/AVX2 support.
-       * configure.ac: Also check for 'xgetbv' instruction in AVX and AVX2
-       inline assembly checks.
-       * src/hwf-x86.c [__i386__] (get_xgetbv): New function.
-       [__x86_64__] (get_xgetbv): New function.
-       [HAS_X86_CPUID] (detect_x86_gnuc): Check for OSXSAVE and OS support for
-       XMM&YMM registers and enable AVX/AVX2 only if XMM&YMM registers are
-       supported by OS.
+       Add secp256k1 curve.
+       * cipher/ecc-curves.c (curve_aliases): Add secp256k1 and its OID.
+       (domain_parms): Add secp256k1's domain paramerter.
+
+       * tests/basic.c (check_pubkey): Add a key of secp256k1.
+
+       * tests/curves.c (N_CURVES): Updated.
+
+2014-01-12  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Fix constant division for AMD64 assembly on Solaris/x86.
+       * configure.ac (gcry_cv_gcc_as_const_division_ok): Add new check for
+       constant division in assembly and test for "-Wa,--divide" workaround.
+       (gcry_cv_gcc_amd64_platform_as_ok): Check for also constant division.
 
 2014-01-10  Werner Koch  <wk@gnupg.org>
 
        * Makefile.am (EXTRA_DIST): Add it.
        * autogen.sh: Update from current GnuPG.
 
-       (cherry picked from commit b0ac1f9b143aa15855914ba93fef900288d45c9c)
-
        Move all helper scripts to build-aux/
        * scripts/: Rename to build-aux/.
        * compile, config.guess, config.rpath, config.sub
        * configure.ac (AC_CONFIG_AUX_DIR): New.
        (AM_SILENT_RULES): New.
 
-       (cherry picked from commit df9b4eabf52faee6f289a4bc62219684442ae383)
+2013-12-30  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Add blowfish/serpent ARM assembly files to Makefile.am.
+       * cipher/Makefile.am: Add 'blowfish-arm.S' and 'serpent-armv7-neon.S'.
+
+       Add AMD64 assembly implementation for arcfour.
+       * cipher/Makefile.am: Add 'arcfour-amd64.S'.
+       * cipher/arcfour-amd64.S: New.
+       * cipher/arcfour.c (USE_AMD64_ASM): New.
+       [USE_AMD64_ASM] (ARCFOUR_context, _gcry_arcfour_amd64)
+       (encrypt_stream): New.
+       * configure.ac [host=x86_64]: Add 'arcfour-amd64.lo'.
+
+       Parse /proc/cpuinfo for ARM HW features.
+       * src/hwf-arm.c [__linux__] (HAS_PROC_CPUINFO)
+       (detect_arm_proc_cpuinfo): New.
+       (_gcry_hwf_detect_arm) [HAS_PROC_CPUINFO]: Check '/proc/cpuinfo' for
+       HW features.
+
+       Fix buggy/incomplete detection of AVX/AVX2 support.
+       * configure.ac: Also check for 'xgetbv' instruction in AVX and AVX2
+       inline assembly checks.
+       * src/hwf-x86.c [__i386__] (get_xgetbv): New function.
+       [__x86_64__] (get_xgetbv): New function.
+       [HAS_X86_CPUID] (detect_x86_gnuc): Check for OSXSAVE and OS support for
+       XMM&YMM registers and enable AVX/AVX2 only if XMM&YMM registers are
+       supported by OS.
+
+2013-12-18  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Change utf-8 copyright characters to '(C)'
+       cipher/blowfish-amd64.S: Change utf-8 encoded copyright character to
+       '(C)'.
+       cipher/blowfish-arm.S: Ditto.
+       cipher/bufhelp.h: Ditto.
+       cipher/camellia-aesni-avx-amd64.S: Ditto.
+       cipher/camellia-aesni-avx2-amd64.S: Ditto.
+       cipher/camellia-arm.S: Ditto.
+       cipher/cast5-amd64.S: Ditto.
+       cipher/cast5-arm.S: Ditto.
+       cipher/cipher-ccm.c: Ditto.
+       cipher/cipher-cmac.c: Ditto.
+       cipher/cipher-gcm.c: Ditto.
+       cipher/cipher-selftest.c: Ditto.
+       cipher/cipher-selftest.h: Ditto.
+       cipher/mac-cmac.c: Ditto.
+       cipher/mac-gmac.c: Ditto.
+       cipher/mac-hmac.c: Ditto.
+       cipher/mac-internal.h: Ditto.
+       cipher/mac.c: Ditto.
+       cipher/rijndael-amd64.S: Ditto.
+       cipher/rijndael-arm.S: Ditto.
+       cipher/salsa20-amd64.S: Ditto.
+       cipher/salsa20-armv7-neon.S: Ditto.
+       cipher/serpent-armv7-neon.S: Ditto.
+       cipher/serpent-avx2-amd64.S: Ditto.
+       cipher/serpent-sse2-amd64.S: Ditto.
+
+       Add ARM/NEON implementation for SHA-1.
+       * cipher/Makefile.am: Add 'sha1-armv7-neon.S'.
+       * cipher/sha1-armv7-neon.S: New.
+       * cipher/sha1.c (USE_NEON): New.
+       (SHA1_CONTEXT, sha1_init) [USE_NEON]: Add and initialize 'use_neon'.
+       [USE_NEON] (_gcry_sha1_transform_armv7_neon): New.
+       (transform) [USE_NEON]: Use ARM/NEON assembly if enabled.
+       * configure.ac: Add 'sha1-armv7-neon.lo'.
+
+       Improve performance of SHA-512/ARM/NEON implementation.
+       * cipher/sha512-armv7-neon.S (RT01q, RT23q, RT45q, RT67q): New.
+       (round_0_63, round_64_79): Remove.
+       (rounds2_0_63, rounds2_64_79): New.
+       (_gcry_sha512_transform_armv7_neon): Add 'nblks' input; Handle multiple
+       input blocks; Use new round macros.
+       * cipher/sha512.c [USE_ARM_NEON_ASM]
+       (_gcry_sha512_transform_armv7_neon): Add 'num_blks'.
+       (transform) [USE_ARM_NEON_ASM]: Pass nblks to assembly.
+
+       Add AVX and AVX2/BMI implementations for SHA-256.
+       * LICENSES: Add 'cipher/sha256-avx-amd64.S' and
+       'cipher/sha256-avx2-bmi2-amd64.S'.
+       * cipher/Makefile.am: Add 'sha256-avx-amd64.S' and
+       'sha256-avx2-bmi2-amd64.S'.
+       * cipher/sha256-avx-amd64.S: New.
+       * cipher/sha256-avx2-bmi2-amd64.S: New.
+       * cipher/sha256-ssse3-amd64.S: Use 'lea' instead of 'add' in few
+       places for tiny speed improvement.
+       * cipher/sha256.c (USE_AVX, USE_AVX2): New.
+       (SHA256_CONTEXT) [USE_AVX, USE_AVX2]: Add 'use_avx' and 'use_avx2'.
+       (sha256_init, sha224_init) [USE_AVX, USE_AVX2]: Initialize above
+       new context members.
+       [USE_AVX] (_gcry_sha256_transform_amd64_avx): New.
+       [USE_AVX2] (_gcry_sha256_transform_amd64_avx2): New.
+       (transform) [USE_AVX2]: Use AVX2 assembly if enabled.
+       (transform) [USE_AVX]: Use AVX assembly if enabled.
+       * configure.ac: Add 'sha256-avx-amd64.lo' and
+       'sha256-avx2-bmi2-amd64.lo'.
+
+2013-12-17  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Add AVX and AVX/BMI2 implementations for SHA-1.
+       * cipher/Makefile.am: Add 'sha1-avx-amd64.S' and
+       'sha1-avx-bmi2-amd64.S'.
+       * cipher/sha1-avx-amd64.S: New.
+       * cipher/sha1-avx-bmi2-amd64.S: New.
+       * cipher/sha1.c (USE_AVX, USE_BMI2): New.
+       (SHA1_CONTEXT) [USE_AVX]: Add 'use_avx'.
+       (SHA1_CONTEXT) [USE_BMI2]: Add 'use_bmi2'.
+       (sha1_init): Initialize 'use_avx' and 'use_bmi2'.
+       [USE_AVX] (_gcry_sha1_transform_amd64_avx): New.
+       [USE_BMI2] (_gcry_sha1_transform_amd64_bmi2): New.
+       (transform) [USE_BMI2]: Use BMI2 assembly if enabled.
+       (transform) [USE_AVX]: Use AVX assembly if enabled.
+       * configure.ac: Add 'sha1-avx-amd64.lo' and 'sha1-avx-bmi2-amd64.lo'.
+
+       SHA-1/SSSE3: Improve performance on large buffers.
+       * cipher/sha1-ssse3-amd64.S (RNBLKS): New.
+       (_gcry_sha1_transform_amd64_ssse3): Handle multiple input blocks, with
+       software pipelining of next data block processing.
+       * cipher/sha1.c [USE_SSSE3] (_gcry_sha1_transform_amd64_ssse3): Add
+       'nblks'.
+       (transform) [USE_SSSE3]: Pass nblks to assembly function.
+
+       Add bulk processing for hash transform functions.
+       * cipher/hash-common.c (_gcry_md_block_write): Preload 'hd->blocksize'
+       to stack, pass number of blocks to 'hd->bwrite'.
+       * cipher/hash-common.c (_gcry_md_block_write_t): Add 'nblks'.
+       * cipher/gostr3411-94.c: Rename 'transform' function to
+       'transform_blk', add new 'transform' function with 'nblks' as
+       additional input.
+       * cipher/md4.c: Ditto.
+       * cipher/md5.c: Ditto.
+       * cipher/md4.c: Ditto.
+       * cipher/rmd160.c: Ditto.
+       * cipher/sha1.c: Ditto.
+       * cipher/sha256.c: Ditto.
+       * cipher/sha512.c: Ditto.
+       * cipher/stribog.c: Ditto.
+       * cipher/tiger.c: Ditto.
+       * cipher/whirlpool.c: Ditto.
 
 2013-12-16  Werner Koch  <wk@gnupg.org>
 
index 8594cfd..ebc18b3 100644 (file)
--- a/LICENSES
+++ b/LICENSES
@@ -12,6 +12,8 @@ with any binary distributions derived from the GNU C Library.
 * BSD_3Clause
 
   For files:
+  - cipher/sha256-avx-amd64.S
+  - cipher/sha256-avx2-bmi2-amd64.S
   - cipher/sha256-ssse3-amd64.S
   - cipher/sha512-avx-amd64.S
   - cipher/sha512-avx2-bmi2-amd64.S
@@ -52,56 +54,6 @@ with any binary distributions derived from the GNU C Library.
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #+end_quote
 
-* Simple permissive licenses
-
-  For files:
-  - cipher/crc.c
-
-#+begin_quote
-  Copyright (c) 1996 L. Peter Deutsch
-
-  Permission is granted to copy and distribute this document for
-  any purpose and without charge, including translations into
-  other languages and incorporation into compilations, provided
-  that the copyright notice and this notice are preserved, and
-  that any substantive changes or deletions from the original are
-  clearly marked.
-#+end_quote
-
-* IETF permissive licenses
-
-  For files:
-  - cipher/crc.c
-
-#+begin_quote
-  Copyright (C) The Internet Society (1998).  All Rights Reserved.
-
-  This document and translations of it may be copied and furnished
-  to others, and derivative works that comment on or otherwise
-  explain it or assist in its implementation may be prepared,
-  copied, published and distributed, in whole or in part, without
-  restriction of any kind, provided that the above copyright notice
-  and this paragraph are included on all such copies and derivative
-  works.  However, this document itself may not be modified in any
-  way, such as by removing the copyright notice or references to
-  the Internet Society or other Internet organizations, except as
-  needed for the purpose of developing Internet standards in which
-  case the procedures for copyrights defined in the Internet
-  Standards process must be followed, or as required to translate
-  it into languages other than English.
-
-  The limited permissions granted above are perpetual and will not be
-  revoked by the Internet Society or its successors or assigns.
-
-  This document and the information contained herein is provided on
-  an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET
-  ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR
-  IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE
-  OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY
-  IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
-  PURPOSE.
-#+end_quote
-
 * X License
 
   For files:
@@ -132,3 +84,110 @@ with any binary distributions derived from the GNU C Library.
   ings in this Software without prior written authorization from the X Consor-
   tium.
 #+end_quote
+
+* Public domain
+
+  For files:
+  - cipher/arcfour-amd64.S
+
+#+begin_quote
+ Author: Marc Bevand <bevand_m (at) epita.fr>
+ Licence: I hereby disclaim the copyright on this code and place it
+ in the public domain.
+#+end_quote
+
+* OCB license 1
+
+  For files:
+  - cipher/cipher-ocb.c
+
+#+begin_quote
+  OCB is covered by several patents but may be used freely by most
+  software.  See http://web.cs.ucdavis.edu/~rogaway/ocb/license.htm .
+  In particular license 1 is suitable for Libgcrypt: See
+  http://web.cs.ucdavis.edu/~rogaway/ocb/license1.pdf for the full
+  license document; it basically says:
+
+    License 1 — License for Open-Source Software Implementations of OCB
+                (Jan 9, 2013)
+
+    Under this license, you are authorized to make, use, and
+    distribute open-source software implementations of OCB. This
+    license terminates for you if you sue someone over their
+    open-source software implementation of OCB claiming that you have
+    a patent covering their implementation.
+
+
+
+ License for Open Source Software Implementations of OCB
+ January 9, 2013
+
+ 1 Definitions
+
+ 1.1 “Licensor” means Phillip Rogaway.
+
+ 1.2 “Licensed Patents” means any patent that claims priority to United
+ States Patent Application No. 09/918,615 entitled “Method and Apparatus
+ for Facilitating Efficient Authenticated Encryption,” and any utility,
+ divisional, provisional, continuation, continuations-in-part, reexamination,
+ reissue, or foreign counterpart patents that may issue with respect to the
+ aforesaid patent application. This includes, but is not limited to, United
+ States Patent No. 7,046,802; United States Patent No. 7,200,227; United
+ States Patent No. 7,949,129; United States Patent No. 8,321,675 ; and any
+ patent that issues out of United States Patent Application No. 13/669,114.
+
+ 1.3 “Use” means any practice of any invention claimed in the Licensed Patents.
+
+ 1.4 “Software Implementation” means any practice of any invention
+ claimed in the Licensed Patents that takes the form of software executing on
+ a user-programmable, general-purpose computer or that takes the form of a
+ computer-readable medium storing such software. Software Implementation does
+ not include, for example, application-specific integrated circuits (ASICs),
+ field-programmable gate arrays (FPGAs), embedded systems, or IP cores.
+
+ 1.5 “Open Source Software” means software whose source code is published
+ and made available for inspection and use by anyone because either (a) the
+ source code is subject to a license that permits recipients to copy, modify,
+ and distribute the source code without payment of fees or royalties, or
+ (b) the source code is in the public domain, including code released for
+ public use through a CC0 waiver. All licenses certified by the Open Source
+ Initiative at opensource.org as of January 9, 2013 and all Creative Commons
+ licenses identified on the creativecommons.org website as of January 9,
+ 2013, including the Public License Fallback of the CC0 waiver, satisfy these
+ requirements for the purposes of this license.
+
+ 1.6 “Open Source Software Implementation” means a Software
+ Implementation in which the software implicating the Licensed Patents is
+ Open Source Software. Open Source Software Implementation does not include
+ any Software Implementation in which the software implicating the Licensed
+ Patents is combined, so as to form a larger program, with software that is
+ not Open Source Software.
+
+ 2 License Grant
+
+ 2.1 License. Subject to your compliance with the term s of this license,
+ including the restriction set forth in Section 2.2, Licensor hereby
+ grants to you a perpetual, worldwide, non-exclusive, non-transferable,
+ non-sublicenseable, no-charge, royalty-free, irrevocable license to practice
+ any invention claimed in the Licensed Patents in any Open Source Software
+ Implementation.
+
+ 2.2 Restriction. If you or your affiliates institute patent litigation
+ (including, but not limited to, a cross-claim or counterclaim in a lawsuit)
+ against any entity alleging that any Use authorized by this license
+ infringes another patent, then any rights granted to you under this license
+ automatically terminate as of the date such litigation is filed.
+
+ 3 Disclaimer
+ YOUR USE OF THE LICENSED PATENTS IS AT YOUR OWN RISK AND UNLESS REQUIRED
+ BY APPLICABLE LAW, LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY
+ KIND CONCERNING THE LICENSED PATENTS OR ANY PRODUCT EMBODYING ANY LICENSED
+ PATENT, EXPRESS OR IMPLIED, STATUT ORY OR OTHERWISE, INCLUDING, WITHOUT
+ LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR
+ PURPOSE, OR NONINFRINGEMENT. IN NO EVENT WILL LICENSOR BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM OR RELATED TO ANY USE OF THE LICENSED PATENTS, INCLUDING,
+ WITHOUT LIMITATION, DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, PUNITIVE
+ OR SPECIAL DAMAGES, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGES PRIOR TO SUCH AN OCCURRENCE.
+#+end_quote
index 937bdaf..2e7abc4 100644 (file)
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
 ACLOCAL_AMFLAGS = -I m4
-AUTOMAKE_OPTIONS = dist-bzip2
-DISTCHECK_CONFIGURE_FLAGS = --disable-random-daemon \
-  --enable-ciphers=arcfour:blowfish:cast5:des:aes:twofish:serpent:rfc2268:seed:camellia
+DISTCHECK_CONFIGURE_FLAGS = --disable-random-daemon --enable-doc \
+                            --enable-random=auto
 
 # (A suitable gitlog-to-changelog script can be found in GnuPG master.)
 GITLOG_TO_CHANGELOG=gitlog-to-changelog
 
+if BUILD_DOC
+doc = doc
+else
+doc =
+endif
+
+
 DIST_SUBDIRS = m4 compat mpi cipher random src doc tests
-SUBDIRS =         compat mpi cipher random src doc tests
+SUBDIRS =         compat mpi cipher random src $(doc) tests
 
 EXTRA_DIST = autogen.sh autogen.rc README.GIT LICENSES                    \
              ChangeLog-2011 build-aux/ChangeLog-2011 doc/ChangeLog-2011    \
index 605bf5b..3e1010c 100644 (file)
@@ -1,9 +1,8 @@
-# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
-# Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 # License along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 VPATH = @srcdir@
-am__make_dryrun = \
-  { \
-    am__dry=no; \
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
     case $$MAKEFLAGS in \
       *\\[\ \  ]*) \
-        echo 'am--echo: ; @echo "AM"  OK' | $(MAKE) -f - 2>/dev/null \
-          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
-      *) \
-        for am__flg in $$MAKEFLAGS; do \
-          case $$am__flg in \
-            *=*|--*) ;; \
-            *n*) am__dry=yes; break;; \
-          esac; \
-        done;; \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs  ]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
     esac; \
-    test $$am__dry = yes; \
-  }
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -69,23 +96,28 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = .
-DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
-       $(srcdir)/Makefile.in $(srcdir)/config.h.in \
-       $(top_srcdir)/configure AUTHORS COPYING COPYING.LIB ChangeLog \
-       INSTALL NEWS THANKS TODO build-aux/compile \
-       build-aux/config.guess build-aux/config.rpath \
-       build-aux/config.sub build-aux/depcomp build-aux/install-sh \
-       build-aux/ltmain.sh build-aux/mdate-sh build-aux/missing \
-       build-aux/texinfo.tex mkinstalldirs
+DIST_COMMON = INSTALL NEWS README AUTHORS ChangeLog \
+       $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+       $(top_srcdir)/configure $(am__configure_deps) \
+       $(srcdir)/config.h.in COPYING COPYING.LIB THANKS TODO \
+       build-aux/compile build-aux/config.guess \
+       build-aux/config.rpath build-aux/config.sub build-aux/depcomp \
+       build-aux/install-sh build-aux/mdate-sh build-aux/missing \
+       mkinstalldirs build-aux/texinfo.tex build-aux/ltmain.sh \
+       $(top_srcdir)/build-aux/compile \
+       $(top_srcdir)/build-aux/config.guess \
+       $(top_srcdir)/build-aux/config.sub \
+       $(top_srcdir)/build-aux/install-sh \
+       $(top_srcdir)/build-aux/ltmain.sh \
+       $(top_srcdir)/build-aux/missing
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/gpg-error.m4 \
-       $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/lock.m4 \
-       $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
-       $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+       $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+       $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+       $(top_srcdir)/m4/lt~obsolete.m4 \
        $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \
        $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
-       $(top_srcdir)/m4/threadlib.m4 $(top_srcdir)/acinclude.m4 \
-       $(top_srcdir)/configure.ac
+       $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
@@ -94,21 +126,28 @@ mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
 AM_V_GEN = $(am__v_GEN_@AM_V@)
 am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
-am__v_GEN_0 = @echo "  GEN   " $@;
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
 AM_V_at = $(am__v_at_@AM_V@)
 am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
 am__v_at_0 = @
+am__v_at_1 = 
 SOURCES =
 DIST_SOURCES =
-RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
-       html-recursive info-recursive install-data-recursive \
-       install-dvi-recursive install-exec-recursive \
-       install-html-recursive install-info-recursive \
-       install-pdf-recursive install-ps-recursive install-recursive \
-       installcheck-recursive installdirs-recursive pdf-recursive \
-       ps-recursive uninstall-recursive
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+       ctags-recursive dvi-recursive html-recursive info-recursive \
+       install-data-recursive install-dvi-recursive \
+       install-exec-recursive install-html-recursive \
+       install-info-recursive install-pdf-recursive \
+       install-ps-recursive install-recursive installcheck-recursive \
+       installdirs-recursive pdf-recursive ps-recursive \
+       tags-recursive uninstall-recursive
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -116,11 +155,33 @@ am__can_run_installinfo = \
   esac
 RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive        \
   distclean-recursive maintainer-clean-recursive
-AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
-       $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
-       distdir dist dist-all distcheck
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+       cscope distdir dist dist-all distcheck
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
+       $(LISP)config.h.in
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
 ETAGS = etags
 CTAGS = ctags
+CSCOPE = cscope
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 distdir = $(PACKAGE)-$(VERSION)
 top_distdir = $(distdir)
@@ -130,6 +191,7 @@ am__remove_distdir = \
       && rm -rf "$(distdir)" \
       || { sleep 5 && rm -rf "$(distdir)"; }; \
   else :; fi
+am__post_remove_distdir = $(am__remove_distdir)
 am__relativize = \
   dir0=`pwd`; \
   sed_first='s,^\([^/]*\)/.*$$,\1,'; \
@@ -157,6 +219,7 @@ am__relativize = \
   reldir="$$dir2"
 DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2
 GZIP_ENV = --best
+DIST_TARGETS = dist-bzip2 dist-gzip
 distuninstallcheck_listfiles = find . -type f -print
 am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
   | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
@@ -205,6 +268,8 @@ GCRYPT_RANDOM = @GCRYPT_RANDOM@
 GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
 GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
 GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GPG_ERROR_MT_CFLAGS = @GPG_ERROR_MT_CFLAGS@
+GPG_ERROR_MT_LIBS = @GPG_ERROR_MT_LIBS@
 GREP = @GREP@
 INSERT_SYS_SELECT_H = @INSERT_SYS_SELECT_H@
 INSTALL = @INSTALL@
@@ -225,16 +290,12 @@ LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@
 LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@
 LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@
 LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@
-LIBMULTITHREAD = @LIBMULTITHREAD@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
-LIBTHREAD = @LIBTHREAD@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
-LTLIBMULTITHREAD = @LTLIBMULTITHREAD@
 LTLIBOBJS = @LTLIBOBJS@
-LTLIBTHREAD = @LTLIBTHREAD@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
@@ -265,6 +326,7 @@ SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
+SYSROOT = @SYSROOT@
 SYS_SOCKET_H = @SYS_SOCKET_H@
 VERSION = @VERSION@
 VERSION_NUMBER = @VERSION_NUMBER@
@@ -324,15 +386,16 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 ACLOCAL_AMFLAGS = -I m4
-AUTOMAKE_OPTIONS = dist-bzip2
-DISTCHECK_CONFIGURE_FLAGS = --disable-random-daemon \
-  --enable-ciphers=arcfour:blowfish:cast5:des:aes:twofish:serpent:rfc2268:seed:camellia
+DISTCHECK_CONFIGURE_FLAGS = --disable-random-daemon --enable-doc \
+                            --enable-random=auto
 
 
 # (A suitable gitlog-to-changelog script can be found in GnuPG master.)
 GITLOG_TO_CHANGELOG = gitlog-to-changelog
+@BUILD_DOC_FALSE@doc = 
+@BUILD_DOC_TRUE@doc = doc
 DIST_SUBDIRS = m4 compat mpi cipher random src doc tests
-SUBDIRS = compat mpi cipher random src doc tests
+SUBDIRS = compat mpi cipher random src $(doc) tests
 EXTRA_DIST = autogen.sh autogen.rc README.GIT LICENSES                    \
              ChangeLog-2011 build-aux/ChangeLog-2011 doc/ChangeLog-2011    \
              m4/ChangeLog-2011 cipher/ChangeLog-2011 src/ChangeLog-2011    \
@@ -381,8 +444,8 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
 $(am__aclocal_m4_deps):
 
 config.h: stamp-h1
-       @if test ! -f $@; then rm -f stamp-h1; else :; fi
-       @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi
+       @test -f $@ || rm -f stamp-h1
+       @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
 
 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
        @rm -f stamp-h1
@@ -405,22 +468,25 @@ distclean-libtool:
        -rm -f libtool config.lt
 
 # This directory's subdirectories are mostly independent; you can cd
-# into them and run `make' without going through this Makefile.
-# To change the values of `make' variables: instead of editing Makefiles,
-# (1) if the variable is set in `config.status', edit `config.status'
-#     (which will cause the Makefiles to be regenerated when you run `make');
-# (2) otherwise, pass the desired values on the `make' command line.
-$(RECURSIVE_TARGETS):
-       @fail= failcom='exit 1'; \
-       for f in x $$MAKEFLAGS; do \
-         case $$f in \
-           *=* | --[!k]*);; \
-           *k*) failcom='fail=yes';; \
-         esac; \
-       done; \
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+#     (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+       @fail=; \
+       if $(am__make_keepgoing); then \
+         failcom='fail=yes'; \
+       else \
+         failcom='exit 1'; \
+       fi; \
        dot_seen=no; \
        target=`echo $@ | sed s/-recursive//`; \
-       list='$(SUBDIRS)'; for subdir in $$list; do \
+       case "$@" in \
+         distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+         *) list='$(SUBDIRS)' ;; \
+       esac; \
+       for subdir in $$list; do \
          echo "Making $$target in $$subdir"; \
          if test "$$subdir" = "."; then \
            dot_seen=yes; \
@@ -435,57 +501,12 @@ $(RECURSIVE_TARGETS):
          $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
        fi; test -z "$$fail"
 
-$(RECURSIVE_CLEAN_TARGETS):
-       @fail= failcom='exit 1'; \
-       for f in x $$MAKEFLAGS; do \
-         case $$f in \
-           *=* | --[!k]*);; \
-           *k*) failcom='fail=yes';; \
-         esac; \
-       done; \
-       dot_seen=no; \
-       case "$@" in \
-         distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
-         *) list='$(SUBDIRS)' ;; \
-       esac; \
-       rev=''; for subdir in $$list; do \
-         if test "$$subdir" = "."; then :; else \
-           rev="$$subdir $$rev"; \
-         fi; \
-       done; \
-       rev="$$rev ."; \
-       target=`echo $@ | sed s/-recursive//`; \
-       for subdir in $$rev; do \
-         echo "Making $$target in $$subdir"; \
-         if test "$$subdir" = "."; then \
-           local_target="$$target-am"; \
-         else \
-           local_target="$$target"; \
-         fi; \
-         ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
-         || eval $$failcom; \
-       done && test -z "$$fail"
-tags-recursive:
-       list='$(SUBDIRS)'; for subdir in $$list; do \
-         test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
-       done
-ctags-recursive:
-       list='$(SUBDIRS)'; for subdir in $$list; do \
-         test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
-       done
+ID: $(am__tagged_files)
+       $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
 
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
-       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
-       unique=`for i in $$list; do \
-           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-         done | \
-         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-             END { if (nonempty) { for (i in files) print i; }; }'`; \
-       mkid -fID $$unique
-tags: TAGS
-
-TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
-               $(TAGS_FILES) $(LISP)
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
        set x; \
        here=`pwd`; \
        if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
@@ -501,12 +522,7 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
              set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
          fi; \
        done; \
-       list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
-       unique=`for i in $$list; do \
-           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-         done | \
-         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-             END { if (nonempty) { for (i in files) print i; }; }'`; \
+       $(am__define_uniq_tagged_files); \
        shift; \
        if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
@@ -518,15 +534,11 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
              $$unique; \
          fi; \
        fi
-ctags: CTAGS
-CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
-               $(TAGS_FILES) $(LISP)
-       list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
-       unique=`for i in $$list; do \
-           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-         done | \
-         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-             END { if (nonempty) { for (i in files) print i; }; }'`; \
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+       $(am__define_uniq_tagged_files); \
        test -z "$(CTAGS_ARGS)$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$unique
@@ -535,9 +547,31 @@ GTAGS:
        here=`$(am__cd) $(top_builddir) && pwd` \
          && $(am__cd) $(top_srcdir) \
          && gtags -i $(GTAGS_ARGS) "$$here"
+cscope: cscope.files
+       test ! -s cscope.files \
+         || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
+clean-cscope:
+       -rm -f cscope.files
+cscope.files: clean-cscope cscopelist
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+       list='$(am__tagged_files)'; \
+       case "$(srcdir)" in \
+         [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+         *) sdir=$(subdir)/$(srcdir) ;; \
+       esac; \
+       for i in $$list; do \
+         if test -f "$$i"; then \
+           echo "$(subdir)/$$i"; \
+         else \
+           echo "$$sdir/$$i"; \
+         fi; \
+       done >> $(top_builddir)/cscope.files
 
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+       -rm -f cscope.out cscope.in.out cscope.po.out cscope.files
 
 distdir: $(DISTFILES)
        $(am__remove_distdir)
@@ -608,40 +642,41 @@ distdir: $(DISTFILES)
        || chmod -R a+r "$(distdir)"
 dist-gzip: distdir
        tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
-       $(am__remove_distdir)
+       $(am__post_remove_distdir)
 dist-bzip2: distdir
        tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
-       $(am__remove_distdir)
+       $(am__post_remove_distdir)
 
 dist-lzip: distdir
        tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
-       $(am__remove_distdir)
-
-dist-lzma: distdir
-       tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
-       $(am__remove_distdir)
+       $(am__post_remove_distdir)
 
 dist-xz: distdir
        tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
-       $(am__remove_distdir)
+       $(am__post_remove_distdir)
 
 dist-tarZ: distdir
+       @echo WARNING: "Support for shar distribution archives is" \
+                      "deprecated." >&2
+       @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
        tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
-       $(am__remove_distdir)
+       $(am__post_remove_distdir)
 
 dist-shar: distdir
+       @echo WARNING: "Support for distribution archives compressed with" \
+                      "legacy program 'compress' is deprecated." >&2
+       @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
        shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
-       $(am__remove_distdir)
+       $(am__post_remove_distdir)
 
 dist-zip: distdir
        -rm -f $(distdir).zip
        zip -rq $(distdir).zip $(distdir)
-       $(am__remove_distdir)
+       $(am__post_remove_distdir)
 
-dist dist-all: distdir
-       tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
-       tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
-       $(am__remove_distdir)
+dist dist-all:
+       $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
+       $(am__post_remove_distdir)
 
 # This target untars the dist file and tries a VPATH configuration.  Then
 # it guarantees that the distribution is self-contained by making another
@@ -652,8 +687,6 @@ distcheck: dist
          GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
        *.tar.bz2*) \
          bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
-       *.tar.lzma*) \
-         lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
        *.tar.lz*) \
          lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
        *.tar.xz*) \
@@ -665,18 +698,19 @@ distcheck: dist
        *.zip*) \
          unzip $(distdir).zip ;;\
        esac
-       chmod -R a-w $(distdir); chmod u+w $(distdir)
-       mkdir $(distdir)/_build
-       mkdir $(distdir)/_inst
+       chmod -R a-w $(distdir)
+       chmod u+w $(distdir)
+       mkdir $(distdir)/_build $(distdir)/_inst
        chmod a-w $(distdir)
        test -d $(distdir)/_build || exit 0; \
        dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
          && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
          && am__cwd=`pwd` \
          && $(am__cd) $(distdir)/_build \
-         && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+         && ../configure \
            $(AM_DISTCHECK_CONFIGURE_FLAGS) \
            $(DISTCHECK_CONFIGURE_FLAGS) \
+           --srcdir=.. --prefix="$$dc_install_base" \
          && $(MAKE) $(AM_MAKEFLAGS) \
          && $(MAKE) $(AM_MAKEFLAGS) dvi \
          && $(MAKE) $(AM_MAKEFLAGS) check \
@@ -699,7 +733,7 @@ distcheck: dist
          && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
          && cd "$$am__cwd" \
          || exit 1
-       $(am__remove_distdir)
+       $(am__post_remove_distdir)
        @(echo "$(distdir) archives ready for distribution: "; \
          list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
          sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
@@ -835,25 +869,24 @@ ps-am:
 
 uninstall-am:
 
-.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \
-       ctags-recursive install-am install-strip tags-recursive
-
-.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
-       all all-am am--refresh check check-am clean clean-generic \
-       clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \
-       dist-gzip dist-hook dist-lzip dist-lzma dist-shar dist-tarZ \
-       dist-xz dist-zip distcheck distclean distclean-generic \
-       distclean-hdr distclean-libtool distclean-tags distcleancheck \
-       distdir distuninstallcheck dvi dvi-am html html-am info \
-       info-am install install-am install-data install-data-am \
-       install-dvi install-dvi-am install-exec install-exec-am \
-       install-html install-html-am install-info install-info-am \
-       install-man install-pdf install-pdf-am install-ps \
-       install-ps-am install-strip installcheck installcheck-am \
-       installdirs installdirs-am maintainer-clean \
-       maintainer-clean-generic mostlyclean mostlyclean-generic \
-       mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
-       uninstall uninstall-am
+.MAKE: $(am__recursive_targets) all install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
+       am--refresh check check-am clean clean-cscope clean-generic \
+       clean-libtool cscope cscopelist-am ctags ctags-am dist \
+       dist-all dist-bzip2 dist-gzip dist-hook dist-lzip dist-shar \
+       dist-tarZ dist-xz dist-zip distcheck distclean \
+       distclean-generic distclean-hdr distclean-libtool \
+       distclean-tags distcleancheck distdir distuninstallcheck dvi \
+       dvi-am html html-am info info-am install install-am \
+       install-data install-data-am install-dvi install-dvi-am \
+       install-exec install-exec-am install-html install-html-am \
+       install-info install-info-am install-man install-pdf \
+       install-pdf-am install-ps install-ps-am install-strip \
+       installcheck installcheck-am installdirs installdirs-am \
+       maintainer-clean maintainer-clean-generic mostlyclean \
+       mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+       tags tags-am uninstall uninstall-am
 
 
 # Add all the files listed in "distfiles" files to the distribution,
diff --git a/NEWS b/NEWS
index e6027f4..e0113fc 100644 (file)
--- a/NEWS
+++ b/NEWS
-Noteworthy changes in version 1.6.2 (2014-08-21) [C20/A0/R2]
+Noteworthy changes in version 1.7.1 (2016-06-15)  [C21/A1/R1]
 ------------------------------------------------
 
- * Map deprecated RSA algo number to the RSA algo number for better
-   backward compatibility.
+ * Bug fixes:
 
* Support a 0x40 compression prefix for EdDSA.
  - Fix ecc_verify for cofactor support.
 
* Improve ARM hardware feature detection and building.
  - Fix portability bug when using gcc with Solaris 9 SPARC.
 
- * Fix powerpc-apple-darwin detection
+   - Build fix for OpenBSD/amd64
 
* Fix building for the x32 ABI platform.
  - Add OIDs to the Serpent ciphers.
 
- * Support building using the latest mingw-w64 toolchain.
+ * Internal changes:
 
* Fix some possible NULL deref bugs.
  - Use getrandom system call on Linux if available.
 
+   - Blinding is now also used for RSA signature creation.
 
-Noteworthy changes in version 1.6.1 (2014-01-29) [C20/A0/R1]
+   - Changed names of debug envvars
+
+
+Noteworthy changes in version 1.7.0 (2016-04-15)  [C21/A1/R0]
 ------------------------------------------------
 
- * Added emulation for broken Whirlpool code prior to 1.6.0.
+ * New algorithms and modes:
+
+   - SHA3-224, SHA3-256, SHA3-384, SHA3-512, and MD2 hash algorithms.
+
+   - SHAKE128 and SHAKE256 extendable-output hash algorithms.
+
+   - ChaCha20 stream cipher.
+
+   - Poly1305 message authentication algorithm
+
+   - ChaCha20-Poly1305 Authenticated Encryption with Associated Data
+     mode.
+
+   - OCB mode.
+
+   - HMAC-MD2 for use by legacy applications.
+
+ * New curves for ECC:
+
+   - Curve25519.
+
+   - sec256k1.
+
+   - GOST R 34.10-2001 and GOST R 34.10-2012.
+
+ * Performance:
+
+   - Improved performance of KDF functions.
+
+   - Assembler optimized implementations of Blowfish and Serpent on
+     ARM.
+
+   - Assembler optimized implementation of 3DES on x86.
+
+   - Improved AES using the SSSE3 based vector permutation method by
+     Mike Hamburg.
+
+   - AVX/BMI is used for SHA-1 and SHA-256 on x86.  This is for SHA-1
+     about 20% faster than SSSE3 and more than 100% faster than the
+     generic C implementation.
+
+   - 40% speedup for SHA-512 and 72% for SHA-1 on ARM Cortex-A8.
+
+   - 60-90% speedup for Whirlpool on x86.
+
+   - 300% speedup for RIPE MD-160.
 
* Improved performance of KDF functions.
  - Up to 11 times speedup for CRC functions on x86.
 
- * Improved ECDSA compliance.
+ * Other features:
 
- * Fixed locking for Windows and non-ELF Pthread systems (regression
-   in 1.6.0)
+   - Improved ECDSA and FIPS 186-4 compliance.
 
* Fixed message digest lookup by OID (regression in 1.6.0).
  - Support for Montgomery curves.
 
- * Fixed a build problem on NetBSD.
+   - gcry_cipher_set_sbox to tweak S-boxes of the gost28147 cipher
+     algorithm.
 
* Fixed memory leaks in ECC code.
  - gcry_mpi_ec_sub to subtract two points on a curve.
 
- * Fixed some asm build problems and feature detection bugs.
+   - gcry_mpi_ec_decode_point to decode an MPI into a point object.
+
+   - Emulation for broken Whirlpool code prior to 1.6.0.  [from 1.6.1]
+
+   - Flag "pkcs1-raw" to enable PCKS#1 padding with a user supplied
+     hash part.
+
+   - Parameter "saltlen" to set a non-default salt length for RSA PSS.
+
+   - A SP800-90A conforming DRNG replaces the former X9.31 alternative
+     random number generator.
+
+   - Map deprecated RSA algo number to the RSA algo number for better
+     backward compatibility. [from 1.6.2]
+
+   - Use ciphertext blinding for Elgamal decryption [CVE-2014-3591].
+     See http://www.cs.tau.ac.il/~tromer/radioexp/ for details.
+     [from 1.6.3]
+
+   - Fixed data-dependent timing variations in modular exponentiation
+     [related to CVE-2015-0837, Last-Level Cache Side-Channel Attacks
+      are Practical]. [from 1.6.3]
+
+   - Flag "no-keytest" for ECC key generation.  Due to a bug in
+     the parser that flag will also be accepted but ignored by older
+     version of Libgcrypt. [from 1.6.4]
+
+   - Speed up the random number generator by requiring less extra
+     seeding. [from 1.6.4]
+
+   - Always verify a created RSA signature to avoid private key leaks
+     due to hardware failures. [from 1.6.4]
+
+   - Mitigate side-channel attack on ECDH with Weierstrass curves
+     [CVE-2015-7511].  See http://www.cs.tau.ac.IL/~tromer/ecdh/ for
+     details. [from 1.6.5]
+
+ * Internal changes:
+
+   - Moved locking out to libgpg-error.
+
+   - Support of the SYSROOT envvar in the build system.
+
+   - Refactor some code.
+
+   - The availability of a 64 bit integer type is now mandatory.
+
+ * Bug fixes:
+
+   - Fixed message digest lookup by OID (regression in 1.6.0).
+
+   - Fixed a build problem on NetBSD
+
+   - Fixed memory leaks in ECC code.
+
+   - Fixed some asm build problems and feature detection bugs.
 
  * Interface changes relative to the 1.6.0 release:
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- GCRY_MD_FLAG_BUGEMU1            NEW (minor API change).
+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+   gcry_cipher_final               NEW macro.
+   GCRY_CIPHER_MODE_CFB8           NEW constant.
+   GCRY_CIPHER_MODE_OCB            NEW.
+   GCRY_CIPHER_MODE_POLY1305       NEW.
+   gcry_cipher_set_sbox            NEW macro.
+   gcry_mac_get_algo               NEW.
+   GCRY_MAC_HMAC_MD2               NEW.
+   GCRY_MAC_HMAC_SHA3_224          NEW.
+   GCRY_MAC_HMAC_SHA3_256          NEW.
+   GCRY_MAC_HMAC_SHA3_384          NEW.
+   GCRY_MAC_HMAC_SHA3_512          NEW.
+   GCRY_MAC_POLY1305               NEW.
+   GCRY_MAC_POLY1305_AES           NEW.
+   GCRY_MAC_POLY1305_CAMELLIA      NEW.
+   GCRY_MAC_POLY1305_SEED          NEW.
+   GCRY_MAC_POLY1305_SERPENT       NEW.
+   GCRY_MAC_POLY1305_TWOFISH       NEW.
+   gcry_md_extract                 NEW.
+   GCRY_MD_FLAG_BUGEMU1            NEW [from 1.6.1].
+   GCRY_MD_GOSTR3411_CP            NEW.
+   GCRY_MD_SHA3_224                NEW.
+   GCRY_MD_SHA3_256                NEW.
+   GCRY_MD_SHA3_384                NEW.
+   GCRY_MD_SHA3_512                NEW.
+   GCRY_MD_SHAKE128                NEW.
+   GCRY_MD_SHAKE256                NEW.
+   gcry_mpi_ec_decode_point        NEW.
+   gcry_mpi_ec_sub                 NEW.
+   GCRY_PK_EDDSA                   NEW constant.
+   GCRYCTL_GET_TAGLEN              NEW.
+   GCRYCTL_SET_SBOX                NEW.
+   GCRYCTL_SET_TAGLEN              NEW.
+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+Version 1.6.5 (2016-02-09) [C20/A0/R5]
+Version 1.6.4 (2015-09-08) [C20/A0/R4]
+Version 1.6.3 (2015-02-27) [C20/A0/R3]
+Version 1.6.2 (2014-08-21) [C20/A0/R2]
+Version 1.6.1 (2014-01-29) [C20/A0/R1]
 
 
 Noteworthy changes in version 1.6.0 (2013-12-16) [C20/A0/R0]
@@ -76,7 +218,7 @@ Noteworthy changes in version 1.6.0 (2013-12-16) [C20/A0/R0]
  * Mitigated the Yarom/Falkner flush+reload side-channel attack on RSA
    secret keys.  See <http://eprint.iacr.org/2013/448> [CVE-2013-4242].
 
- * Added support for Deterministic DSA as per RFC-6969.
+ * Added support for Deterministic DSA as per RFC-6979.
 
  * Added support for curve Ed25519.
 
diff --git a/README b/README
index 25ed18a..1148a24 100644 (file)
--- a/README
+++ b/README
@@ -1,10 +1,10 @@
                    Libgcrypt - The GNU Crypto Library
                   ------------------------------------
-                             Version 1.6
+                             Version 1.7
 
-       Copyright (C) 1989,1991-2012 Free Software Foundation, Inc.
-       Copyright (C) 2012-2014 g10 Code GmbH
-       Copyright (C) 2013-2014 Jussi Kivilinna
+       Copyright (C) 1989,1991-2016 Free Software Foundation, Inc.
+       Copyright (C) 2012-2016 g10 Code GmbH
+       Copyright (C) 2013-2016 Jussi Kivilinna
 
     Libgcrypt is free software.  See the file AUTHORS for full copying
     notices, and LICENSES for notices about contributions that require
     The download canonical location for libgcrypt is:
 
       ftp://ftp.gnupg.org/gcrypt/libgcrypt/
+    or
+      https://gnupg.org/ftp/gcrypt/libgcrypt/
 
     To build libgcrypt you need libgpg-error:
 
       ftp://ftp.gnupg.org/gcrypt/libgpg-error/
+    or
+      https://gnupg.org/ftp/gcrypt/libgpg-error/
 
     You should get the latest versions of course.
 
@@ -74,7 +78,7 @@
     You may want to join the developer's mailing list
     gcrypt-devel@gnupg.org by sending mail with a subject of
     "subscribe" to gcrypt-devel-request@gnupg.org.  An archive of this
-    list is available at http://lists.gnupg.org .
+    list is available at https://lists.gnupg.org .
 
 
     Configure options
 
     The library is distributed under the terms of the GNU Lesser
     General Public License (LGPL); see the file COPYING.LIB for the
-    actual terms.  The helper programs (e.g. gcryptrnd and getrandom)
-    as well as the documentation are distributed under the terms of
-    the GNU General Public License (GPL); see the file COPYING for the
-    actual terms.  The file LICENSES has notices about contributions
-    that require these additional notices are distributed.
-
-    This library used to be available under the GPL - this was changed
-    with version 1.1.7 with the rationale that there are now many free
-    crypto libraries available and many of them come with capabilities
-    similar to Libcrypt.  We decided that to foster the use of
-    cryptography in Free Software an LGPLed library would make more
-    sense because it avoids problems due to license incompatibilities
-    between some Free Software licenses and the GPL.
-
-    Please note that in many cases it is better for a library to be
-    licensed under the GPL, so that it provides an advantage for free
-    software projects.  The Lesser GPL is so named because it does
-    less to protect the freedom of the users of the code that it
-    covers.  See http://www.gnu.org/philosophy/why-not-lgpl.html for
-    more explanation.
+    actual terms.
+
+    The helper programs as well as the documentation are distributed
+    under the terms of the GNU General Public License (GPL); see the
+    file COPYING for the actual terms.
+
+    The file LICENSES has notices about contributions that require
+    that these additional notices are distributed.
 
 
     Contact
 
     See the file AUTHORS.
 
-    Commercial grade support for Libgcrypt is available; please see
-    http://www.gnupg.org/service.html .
-
     Commercial grade support for Libgcrypt is available; for a listing
-    of offers see http://www.gnupg.org/service.html .  The driving
-    force behind the development of Libgcrypt is the company of its
-    principal author, Werner Koch.  Maintenance and improvement of
-    Libgcrypt takes up a lot resources.  To allow him to continue his
-    work, he asks to either purchase a support contract, engage them
-    for custom enhancements, or to donate money.  See http://g10code.com .
+    of offers see https://www.gnupg.org/service.html .
+
+    Maintenance and development of Libgcrypt is mostly financed by
+    donations.  We currently employ 3 full-time developers, one
+    part-timer, and one contractor.  They all work on GnuPG and
+    closely related software like Libgcrypt.  Please visit
+    https://gnupg.org/donate/ to see out how you can help.
 
 
   This file is Free Software; as a special exception the authors gives
diff --git a/VERSION b/VERSION
index fdd3be6..943f9cb 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.6.2
+1.7.1
index 0791b84..96be833 100644 (file)
@@ -101,9 +101,12 @@ AC_DEFUN([GNUPG_CHECK_GNUMAKE],
 AC_DEFUN([GNUPG_SYS_SYMBOL_UNDERSCORE],
 [tmp_do_check="no"
 case "${host}" in
-    *-mingw32*)
+    i?86-mingw32* | i?86-*-mingw32*)
         ac_cv_sys_symbol_underscore=yes
         ;;
+    x86_64-*-mingw32*)
+        ac_cv_sys_symbol_underscore=no
+        ;;
     i386-emx-os2 | i[3456]86-pc-os2*emx | i386-pc-msdosdjgpp)
         ac_cv_sys_symbol_underscore=yes
         ;;
index 1ef2244..73804e9 100644 (file)
@@ -1,8 +1,7 @@
-# generated automatically by aclocal 1.11.6 -*- Autoconf -*-
+# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
 
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
-# Inc.
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 # PARTICULAR PURPOSE.
 
+m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
 [m4_warning([this file was generated for autoconf 2.69.
 You have another version of autoconf.  It may work, but is not guaranteed to.
 If you have problems, you may need to regenerate the build system entirely.
-To do so, use the procedure documented by the package, typically `autoreconf'.])])
+To do so, use the procedure documented by the package, typically 'autoreconf'.])])
 
-# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software
-# Foundation, Inc.
+# Copyright (C) 2002-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 1
-
 # AM_AUTOMAKE_VERSION(VERSION)
 # ----------------------------
 # Automake X.Y traces this macro to ensure aclocal.m4 has been
 # generated from the m4 files accompanying Automake X.Y.
 # (This private macro should not be called outside this file.)
 AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.11'
+[am__api_version='1.14'
 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
 dnl require some minimum version.  Point them to the right macro.
-m4_if([$1], [1.11.6], [],
+m4_if([$1], [1.14.1], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -54,21 +51,19 @@ m4_define([_AM_AUTOCONF_VERSION], [])
 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.11.6])dnl
+[AM_AUTOMAKE_VERSION([1.14.1])dnl
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 
 # Figure out how to run the assembler.                      -*- Autoconf -*-
 
-# Copyright (C) 2001, 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 5
-
 # AM_PROG_AS
 # ----------
 AC_DEFUN([AM_PROG_AS],
@@ -83,17 +78,15 @@ _AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES([CCAS])])dnl
 
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
-# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 1
-
 # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
-# $ac_aux_dir to `$srcdir/foo'.  In other projects, it is set to
-# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+# $ac_aux_dir to '$srcdir/foo'.  In other projects, it is set to
+# '$srcdir', '$srcdir/..', or '$srcdir/../..'.
 #
 # Of course, Automake must honor this variable whenever it calls a
 # tool from the auxiliary directory.  The problem is that $srcdir (and
@@ -112,7 +105,7 @@ _AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES([CCAS])])dnl
 #
 # The reason of the latter failure is that $top_srcdir and $ac_aux_dir
 # are both prefixed by $srcdir.  In an in-source build this is usually
-# harmless because $srcdir is `.', but things will broke when you
+# harmless because $srcdir is '.', but things will broke when you
 # start a VPATH build or use an absolute $srcdir.
 #
 # So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
@@ -130,30 +123,26 @@ _AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES([CCAS])])dnl
 # configured tree to be moved without reconfiguration.
 
 AC_DEFUN([AM_AUX_DIR_EXPAND],
-[dnl Rely on autoconf to set up CDPATH properly.
-AC_PREREQ([2.50])dnl
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
+[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
 ])
 
 # AM_CONDITIONAL                                            -*- Autoconf -*-
 
-# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
-# Free Software Foundation, Inc.
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 9
-
 # AM_CONDITIONAL(NAME, SHELL-CONDITION)
 # -------------------------------------
 # Define a conditional.
 AC_DEFUN([AM_CONDITIONAL],
-[AC_PREREQ(2.52)dnl
ifelse([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],
-       [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+[AC_PREREQ([2.52])dnl
m4_if([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],
+       [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
 AC_SUBST([$1_TRUE])dnl
 AC_SUBST([$1_FALSE])dnl
 _AM_SUBST_NOTMAKE([$1_TRUE])dnl
@@ -172,16 +161,14 @@ AC_CONFIG_COMMANDS_PRE(
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009,
-# 2010, 2011 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 12
 
-# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be
 # written in clear, in which case automake, when reading aclocal.m4,
 # will think it sees a *use*, and therefore will trigger all it's
 # C support machinery.  Also note that it means that autoscan, seeing
@@ -191,7 +178,7 @@ fi])])
 # _AM_DEPENDENCIES(NAME)
 # ----------------------
 # See how the compiler implements dependency checking.
-# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC".
 # We try a few techniques and use that to set a single cache variable.
 #
 # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
@@ -204,12 +191,13 @@ AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
 AC_REQUIRE([AM_MAKE_INCLUDE])dnl
 AC_REQUIRE([AM_DEP_TRACK])dnl
 
-ifelse([$1], CC,   [depcc="$CC"   am_compiler_list=],
-       [$1], CXX,  [depcc="$CXX"  am_compiler_list=],
-       [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
-       [$1], UPC,  [depcc="$UPC"  am_compiler_list=],
-       [$1], GCJ,  [depcc="$GCJ"  am_compiler_list='gcc3 gcc'],
-                   [depcc="$$1"   am_compiler_list=])
+m4_if([$1], [CC],   [depcc="$CC"   am_compiler_list=],
+      [$1], [CXX],  [depcc="$CXX"  am_compiler_list=],
+      [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+      [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'],
+      [$1], [UPC],  [depcc="$UPC"  am_compiler_list=],
+      [$1], [GCJ],  [depcc="$GCJ"  am_compiler_list='gcc3 gcc'],
+                    [depcc="$$1"   am_compiler_list=])
 
 AC_CACHE_CHECK([dependency style of $depcc],
                [am_cv_$1_dependencies_compiler_type],
@@ -217,8 +205,8 @@ AC_CACHE_CHECK([dependency style of $depcc],
   # We make a subdir and do the tests there.  Otherwise we can end up
   # making bogus files that we don't know about and never remove.  For
   # instance it was reported that on HP-UX the gcc test will end up
-  # making a dummy file named `D' -- because `-MD' means `put the output
-  # in D'.
+  # making a dummy file named 'D' -- because '-MD' means "put the output
+  # in D".
   rm -rf conftest.dir
   mkdir conftest.dir
   # Copy depcomp to subdir because otherwise we won't find it if we're
@@ -258,16 +246,16 @@ AC_CACHE_CHECK([dependency style of $depcc],
     : > sub/conftest.c
     for i in 1 2 3 4 5 6; do
       echo '#include "conftst'$i'.h"' >> sub/conftest.c
-      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
-      # Solaris 8's {/usr,}/bin/sh.
-      touch sub/conftst$i.h
+      # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+      # Solaris 10 /bin/sh.
+      echo '/* dummy */' > sub/conftst$i.h
     done
     echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
 
-    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # We check with '-c' and '-o' for the sake of the "dashmstdout"
     # mode.  It turns out that the SunPro C++ compiler does not properly
-    # handle `-M -o', and we need to detect this.  Also, some Intel
-    # versions had trouble with output in subdirs
+    # handle '-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs.
     am__obj=sub/conftest.${OBJEXT-o}
     am__minus_obj="-o $am__obj"
     case $depmode in
@@ -276,8 +264,8 @@ AC_CACHE_CHECK([dependency style of $depcc],
       test "$am__universal" = false || continue
       ;;
     nosideeffect)
-      # after this tag, mechanisms are not by side-effect, so they'll
-      # only be used when explicitly requested
+      # After this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested.
       if test "x$enable_dependency_tracking" = xyes; then
        continue
       else
@@ -285,7 +273,7 @@ AC_CACHE_CHECK([dependency style of $depcc],
       fi
       ;;
     msvc7 | msvc7msys | msvisualcpp | msvcmsys)
-      # This compiler won't grok `-c -o', but also, the minuso test has
+      # This compiler won't grok '-c -o', but also, the minuso test has
       # not run yet.  These depmodes are late enough in the game, and
       # so weak that their functioning should not be impacted.
       am__obj=conftest.${OBJEXT-o}
@@ -333,7 +321,7 @@ AM_CONDITIONAL([am__fastdep$1], [
 # AM_SET_DEPDIR
 # -------------
 # Choose a directory name for dependency files.
-# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES.
 AC_DEFUN([AM_SET_DEPDIR],
 [AC_REQUIRE([AM_SET_LEADING_DOT])dnl
 AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
@@ -343,9 +331,13 @@ AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
 # AM_DEP_TRACK
 # ------------
 AC_DEFUN([AM_DEP_TRACK],
-[AC_ARG_ENABLE(dependency-tracking,
-[  --disable-dependency-tracking  speeds up one-time build
-  --enable-dependency-tracking   do not reject slow dependency extractors])
+[AC_ARG_ENABLE([dependency-tracking], [dnl
+AS_HELP_STRING(
+  [--enable-dependency-tracking],
+  [do not reject slow dependency extractors])
+AS_HELP_STRING(
+  [--disable-dependency-tracking],
+  [speeds up one-time build])])
 if test "x$enable_dependency_tracking" != xno; then
   am_depcomp="$ac_aux_dir/depcomp"
   AMDEPBACKSLASH='\'
@@ -360,20 +352,18 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
 
 # Generate code to set up dependency tracking.              -*- Autoconf -*-
 
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-#serial 5
 
 # _AM_OUTPUT_DEPENDENCY_COMMANDS
 # ------------------------------
 AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
 [{
-  # Autoconf 2.62 quotes --file arguments for eval, but not when files
+  # Older Autoconf quotes --file arguments for eval, but not when files
   # are listed without --file.  Let's play safe and only enable the eval
   # if we detect the quoting.
   case $CONFIG_FILES in
@@ -386,7 +376,7 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
     # Strip MF so we end up with the name of the file.
     mf=`echo "$mf" | sed -e 's/:.*$//'`
     # Check whether this is an Automake generated Makefile or not.
-    # We used to match only the files named `Makefile.in', but
+    # We used to match only the files named 'Makefile.in', but
     # some people rename them; so instead we look at the file content.
     # Grep'ing the first line is not enough: some people post-process
     # each Makefile.in and add a new line on top of each file to say so.
@@ -398,21 +388,19 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
       continue
     fi
     # Extract the definition of DEPDIR, am__include, and am__quote
-    # from the Makefile without running `make'.
+    # from the Makefile without running 'make'.
     DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
     test -z "$DEPDIR" && continue
     am__include=`sed -n 's/^am__include = //p' < "$mf"`
-    test -z "am__include" && continue
+    test -z "$am__include" && continue
     am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
-    # When using ansi2knr, U may be empty or an underscore; expand it
-    U=`sed -n 's/^U = //p' < "$mf"`
     # Find all dependency output files, they are included files with
     # $(DEPDIR) in their names.  We invoke sed twice because it is the
     # simplest approach to changing $(DEPDIR) to its actual value in the
     # expansion.
     for file in `sed -n "
       s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
-        sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+        sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
       # Make sure the directory exists.
       test -f "$dirpart/$file" && continue
       fdir=`AS_DIRNAME(["$file"])`
@@ -430,7 +418,7 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
 # This macro should only be invoked once -- use via AC_REQUIRE.
 #
 # This code is only required when automatic dependency tracking
-# is enabled.  FIXME.  This creates each `.P' file that we will
+# is enabled.  FIXME.  This creates each '.P' file that we will
 # need in order to bootstrap the dependency handling code.
 AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
 [AC_CONFIG_COMMANDS([depfiles],
@@ -440,18 +428,21 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
 
 # Do all the work for Automake.                             -*- Autoconf -*-
 
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 16
-
 # This macro actually does too much.  Some checks are only needed if
 # your package does certain things.  But this isn't really a big deal.
 
+dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
+m4_define([AC_PROG_CC],
+m4_defn([AC_PROG_CC])
+[_AM_PROG_CC_C_O
+])
+
 # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
 # AM_INIT_AUTOMAKE([OPTIONS])
 # -----------------------------------------------
@@ -464,7 +455,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
 # arguments mandatory, and then we can depend on a new Autoconf
 # release and drop the old call support.
 AC_DEFUN([AM_INIT_AUTOMAKE],
-[AC_PREREQ([2.62])dnl
+[AC_PREREQ([2.65])dnl
 dnl Autoconf wants to disallow AM_ names.  We explicitly allow
 dnl the ones we care about.
 m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
@@ -493,31 +484,40 @@ AC_SUBST([CYGPATH_W])
 # Define the identity of the package.
 dnl Distinguish between old-style and new-style calls.
 m4_ifval([$2],
-[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+[AC_DIAGNOSE([obsolete],
+             [$0: two- and three-arguments forms are deprecated.])
+m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
  AC_SUBST([PACKAGE], [$1])dnl
  AC_SUBST([VERSION], [$2])],
 [_AM_SET_OPTIONS([$1])dnl
 dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
-m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
+m4_if(
+  m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+  [ok:ok],,
   [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
  AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
  AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
 
 _AM_IF_OPTION([no-define],,
-[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
- AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
+ AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl
 
 # Some tools Automake needs.
 AC_REQUIRE([AM_SANITY_CHECK])dnl
 AC_REQUIRE([AC_ARG_PROGRAM])dnl
-AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
-AM_MISSING_PROG(AUTOCONF, autoconf)
-AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
-AM_MISSING_PROG(AUTOHEADER, autoheader)
-AM_MISSING_PROG(MAKEINFO, makeinfo)
+AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}])
+AM_MISSING_PROG([AUTOCONF], [autoconf])
+AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}])
+AM_MISSING_PROG([AUTOHEADER], [autoheader])
+AM_MISSING_PROG([MAKEINFO], [makeinfo])
 AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
 AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
-AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+# For better backward compatibility.  To be removed once Automake 1.9.x
+# dies out for good.  For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
 # We need awk for the "check" target.  The system "awk" is bad on
 # some platforms.
 AC_REQUIRE([AC_PROG_AWK])dnl
@@ -528,34 +528,79 @@ _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
                             [_AM_PROG_TAR([v7])])])
 _AM_IF_OPTION([no-dependencies],,
 [AC_PROVIDE_IFELSE([AC_PROG_CC],
-                 [_AM_DEPENDENCIES(CC)],
-                 [define([AC_PROG_CC],
-                         defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+                 [_AM_DEPENDENCIES([CC])],
+                 [m4_define([AC_PROG_CC],
+                            m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
 AC_PROVIDE_IFELSE([AC_PROG_CXX],
-                 [_AM_DEPENDENCIES(CXX)],
-                 [define([AC_PROG_CXX],
-                         defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+                 [_AM_DEPENDENCIES([CXX])],
+                 [m4_define([AC_PROG_CXX],
+                            m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
 AC_PROVIDE_IFELSE([AC_PROG_OBJC],
-                 [_AM_DEPENDENCIES(OBJC)],
-                 [define([AC_PROG_OBJC],
-                         defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
+                 [_AM_DEPENDENCIES([OBJC])],
+                 [m4_define([AC_PROG_OBJC],
+                            m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+                 [_AM_DEPENDENCIES([OBJCXX])],
+                 [m4_define([AC_PROG_OBJCXX],
+                            m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
 ])
-_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
-dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
-dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This macro
-dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_REQUIRE([AM_SILENT_RULES])dnl
+dnl The testsuite driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This
+dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
 AC_CONFIG_COMMANDS_PRE(dnl
 [m4_provide_if([_AM_COMPILER_EXEEXT],
   [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes.  So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+  cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present.  This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message.  This
+can help us improve future automake versions.
+
+END
+  if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+    echo 'Configuration will proceed anyway, since you have set the' >&2
+    echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+    echo >&2
+  else
+    cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+    AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
+  fi
+fi
 ])
 
-dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion.  Do not
+dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion.  Do not
 dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
 dnl mangled by Autoconf and run in a shell conditional statement.
 m4_define([_AC_COMPILER_EXEEXT],
 m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
 
-
 # When config.status generates a header, we must update the stamp-h file.
 # This file resides in the same directory as the config header
 # that is generated.  The stamp files are numbered to have different names.
@@ -577,15 +622,12 @@ for _am_header in $config_headers :; do
 done
 echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
 
-# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation,
-# Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 1
-
 # AM_PROG_INSTALL_SH
 # ------------------
 # Define $install_sh.
@@ -599,16 +641,14 @@ if test x"${install_sh}" != xset; then
     install_sh="\${SHELL} $am_aux_dir/install-sh"
   esac
 fi
-AC_SUBST(install_sh)])
+AC_SUBST([install_sh])])
 
-# Copyright (C) 2003, 2005  Free Software Foundation, Inc.
+# Copyright (C) 2003-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 2
-
 # Check whether the underlying file-system supports filenames
 # with a leading dot.  For instance MS-DOS doesn't.
 AC_DEFUN([AM_SET_LEADING_DOT],
@@ -625,20 +665,17 @@ AC_SUBST([am__leading_dot])])
 # Add --enable-maintainer-mode option to configure.         -*- Autoconf -*-
 # From Jim Meyering
 
-# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008,
-# 2011 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 5
-
 # AM_MAINTAINER_MODE([DEFAULT-MODE])
 # ----------------------------------
 # Control maintainer-specific portions of Makefiles.
-# Default is to disable them, unless `enable' is passed literally.
-# For symmetry, `disable' may be passed as well.  Anyway, the user
+# Default is to disable them, unless 'enable' is passed literally.
+# For symmetry, 'disable' may be passed as well.  Anyway, the user
 # can override the default with the --enable/--disable switch.
 AC_DEFUN([AM_MAINTAINER_MODE],
 [m4_case(m4_default([$1], [disable]),
@@ -649,10 +686,11 @@ AC_DEFUN([AM_MAINTAINER_MODE],
 AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
   dnl maintainer-mode's default is 'disable' unless 'enable' is passed
   AC_ARG_ENABLE([maintainer-mode],
-[  --][am_maintainer_other][-maintainer-mode  am_maintainer_other make rules and dependencies not useful
-                         (and sometimes confusing) to the casual installer],
-      [USE_MAINTAINER_MODE=$enableval],
-      [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
+    [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode],
+      am_maintainer_other[ make rules and dependencies not useful
+      (and sometimes confusing) to the casual installer])],
+    [USE_MAINTAINER_MODE=$enableval],
+    [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
   AC_MSG_RESULT([$USE_MAINTAINER_MODE])
   AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
   MAINT=$MAINTAINER_MODE_TRUE
@@ -660,18 +698,14 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
 ]
 )
 
-AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
-
 # Check to see how 'make' treats includes.                 -*- Autoconf -*-
 
-# Copyright (C) 2001, 2002, 2003, 2005, 2009  Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 4
-
 # AM_MAKE_INCLUDE()
 # -----------------
 # Check to see how make treats includes.
@@ -689,7 +723,7 @@ am__quote=
 _am_result=none
 # First try GNU make style include.
 echo "include confinc" > confmf
-# Ignore all kinds of additional output from `make'.
+# Ignore all kinds of additional output from 'make'.
 case `$am_make -s -f confmf 2> /dev/null` in #(
 *the\ am__doit\ target*)
   am__include=include
@@ -714,52 +748,14 @@ AC_MSG_RESULT([$_am_result])
 rm -f confinc confmf
 ])
 
-# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 6
-
-# AM_PROG_CC_C_O
-# --------------
-# Like AC_PROG_CC_C_O, but changed for automake.
-AC_DEFUN([AM_PROG_CC_C_O],
-[AC_REQUIRE([AC_PROG_CC_C_O])dnl
-AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-AC_REQUIRE_AUX_FILE([compile])dnl
-# FIXME: we rely on the cache variable name because
-# there is no other way.
-set dummy $CC
-am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
-eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
-if test "$am_t" != yes; then
-   # Losing compiler, so override with the script.
-   # FIXME: It is wrong to rewrite CC.
-   # But if we don't then we get into trouble of one sort or another.
-   # A longer-term fix would be to have automake use am__CC in this case,
-   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
-   CC="$am_aux_dir/compile $CC"
-fi
-dnl Make sure AC_PROG_CC is never called again, or it will override our
-dnl setting of CC.
-m4_define([AC_PROG_CC],
-          [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])])
-])
-
 # Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
 
-# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 6
-
 # AM_MISSING_PROG(NAME, PROGRAM)
 # ------------------------------
 AC_DEFUN([AM_MISSING_PROG],
@@ -767,11 +763,10 @@ AC_DEFUN([AM_MISSING_PROG],
 $1=${$1-"${am_missing_run}$2"}
 AC_SUBST($1)])
 
-
 # AM_MISSING_HAS_RUN
 # ------------------
-# Define MISSING if not defined so far and test if it supports --run.
-# If it does, set am_missing_run to use it, otherwise, to nothing.
+# Define MISSING if not defined so far and test if it is modern enough.
+# If it is, set am_missing_run to use it, otherwise, to nothing.
 AC_DEFUN([AM_MISSING_HAS_RUN],
 [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
 AC_REQUIRE_AUX_FILE([missing])dnl
@@ -784,54 +779,22 @@ if test x"${MISSING+set}" != xset; then
   esac
 fi
 # Use eval to expand $SHELL
-if eval "$MISSING --run true"; then
-  am_missing_run="$MISSING --run "
+if eval "$MISSING --is-lightweight"; then
+  am_missing_run="$MISSING "
 else
   am_missing_run=
-  AC_MSG_WARN([`missing' script is too old or missing])
+  AC_MSG_WARN(['missing' script is too old or missing])
 fi
 ])
 
-# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation,
-# Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 1
-
-# AM_PROG_MKDIR_P
-# ---------------
-# Check for `mkdir -p'.
-AC_DEFUN([AM_PROG_MKDIR_P],
-[AC_PREREQ([2.60])dnl
-AC_REQUIRE([AC_PROG_MKDIR_P])dnl
-dnl Automake 1.8 to 1.9.6 used to define mkdir_p.  We now use MKDIR_P,
-dnl while keeping a definition of mkdir_p for backward compatibility.
-dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
-dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
-dnl Makefile.ins that do not define MKDIR_P, so we do our own
-dnl adjustment using top_builddir (which is defined more often than
-dnl MKDIR_P).
-AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
-case $mkdir_p in
-  [[\\/$]]* | ?:[[\\/]]*) ;;
-  */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
-esac
-])
-
 # Helper functions for option handling.                     -*- Autoconf -*-
 
-# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software
-# Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 5
-
 # _AM_MANGLE_OPTION(NAME)
 # -----------------------
 AC_DEFUN([_AM_MANGLE_OPTION],
@@ -841,7 +804,7 @@ AC_DEFUN([_AM_MANGLE_OPTION],
 # --------------------
 # Set option NAME.  Presently that only means defining a flag for this option.
 AC_DEFUN([_AM_SET_OPTION],
-[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+[m4_define(_AM_MANGLE_OPTION([$1]), [1])])
 
 # _AM_SET_OPTIONS(OPTIONS)
 # ------------------------
@@ -855,24 +818,82 @@ AC_DEFUN([_AM_SET_OPTIONS],
 AC_DEFUN([_AM_IF_OPTION],
 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
 
-# Check to make sure that the build environment is sane.    -*- Autoconf -*-
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_CC_C_O
+# ---------------
+# Like AC_PROG_CC_C_O, but changed for automake.  We rewrite AC_PROG_CC
+# to automatically call this.
+AC_DEFUN([_AM_PROG_CC_C_O],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+AC_LANG_PUSH([C])dnl
+AC_CACHE_CHECK(
+  [whether $CC understands -c and -o together],
+  [am_cv_prog_cc_c_o],
+  [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
+  # Make sure it works both with $CC and with simple cc.
+  # Following AC_PROG_CC_C_O, we do the test twice because some
+  # compilers refuse to overwrite an existing .o file with -o,
+  # though they will create one.
+  am_cv_prog_cc_c_o=yes
+  for am_i in 1 2; do
+    if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
+         && test -f conftest2.$ac_objext; then
+      : OK
+    else
+      am_cv_prog_cc_c_o=no
+      break
+    fi
+  done
+  rm -f core conftest*
+  unset am_i])
+if test "$am_cv_prog_cc_c_o" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+AC_LANG_POP([C])])
 
-# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
-# Free Software Foundation, Inc.
+# For backward compatibility.
+AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 5
+# AM_RUN_LOG(COMMAND)
+# -------------------
+# Run COMMAND, save the exit status in ac_status, and log it.
+# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
+AC_DEFUN([AM_RUN_LOG],
+[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
+   ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   (exit $ac_status); }])
+
+# Check to make sure that the build environment is sane.    -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
 
 # AM_SANITY_CHECK
 # ---------------
 AC_DEFUN([AM_SANITY_CHECK],
 [AC_MSG_CHECKING([whether build environment is sane])
-# Just in case
-sleep 1
-echo timestamp > conftest.file
 # Reject unsafe characters in $srcdir or the absolute working directory
 # name.  Accept space and tab only in the latter.
 am_lf='
@@ -883,32 +904,40 @@ case `pwd` in
 esac
 case $srcdir in
   *[[\\\"\#\$\&\'\`$am_lf\ \   ]]*)
-    AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
+    AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);;
 esac
 
-# Do `set' in a subshell so we don't clobber the current shell's
+# Do 'set' in a subshell so we don't clobber the current shell's
 # arguments.  Must try -L first in case configure is actually a
 # symlink; some systems play weird games with the mod time of symlinks
 # (eg FreeBSD returns the mod time of the symlink's containing
 # directory).
 if (
-   set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
-   if test "$[*]" = "X"; then
-      # -L didn't work.
-      set X `ls -t "$srcdir/configure" conftest.file`
-   fi
-   rm -f conftest.file
-   if test "$[*]" != "X $srcdir/configure conftest.file" \
-      && test "$[*]" != "X conftest.file $srcdir/configure"; then
-
-      # If neither matched, then we have a broken ls.  This can happen
-      # if, for instance, CONFIG_SHELL is bash and it inherits a
-      # broken ls alias from the environment.  This has actually
-      # happened.  Such a system could not be considered "sane".
-      AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
-alias in your environment])
-   fi
-
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+     if test "$[*]" = "X"; then
+       # -L didn't work.
+       set X `ls -t "$srcdir/configure" conftest.file`
+     fi
+     if test "$[*]" != "X $srcdir/configure conftest.file" \
+       && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+       # If neither matched, then we have a broken ls.  This can happen
+       # if, for instance, CONFIG_SHELL is bash and it inherits a
+       # broken ls alias from the environment.  This has actually
+       # happened.  Such a system could not be considered "sane".
+       AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
+  alias in your environment])
+     fi
+     if test "$[2]" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
    test "$[2]" = conftest.file
    )
 then
@@ -918,31 +947,50 @@ else
    AC_MSG_ERROR([newly created file is older than distributed files!
 Check your system clock])
 fi
-AC_MSG_RESULT(yes)])
+AC_MSG_RESULT([yes])
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+AC_CONFIG_COMMANDS_PRE(
+  [AC_MSG_CHECKING([that generated files are newer than configure])
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   AC_MSG_RESULT([done])])
+rm -f conftest.file
+])
 
-# Copyright (C) 2009, 2011  Free Software Foundation, Inc.
+# Copyright (C) 2009-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 2
-
 # AM_SILENT_RULES([DEFAULT])
 # --------------------------
 # Enable less verbose build rules; with the default set to DEFAULT
-# (`yes' being less verbose, `no' or empty being verbose).
+# ("yes" being less verbose, "no" or empty being verbose).
 AC_DEFUN([AM_SILENT_RULES],
-[AC_ARG_ENABLE([silent-rules],
-[  --enable-silent-rules          less verbose build output (undo: `make V=1')
-  --disable-silent-rules         verbose build output (undo: `make V=0')])
-case $enable_silent_rules in
-yes) AM_DEFAULT_VERBOSITY=0;;
-no)  AM_DEFAULT_VERBOSITY=1;;
-*)   AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+[AC_ARG_ENABLE([silent-rules], [dnl
+AS_HELP_STRING(
+  [--enable-silent-rules],
+  [less verbose build output (undo: "make V=1")])
+AS_HELP_STRING(
+  [--disable-silent-rules],
+  [verbose build output (undo: "make V=0")])dnl
+])
+case $enable_silent_rules in @%:@ (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
 esac
 dnl
-dnl A few `make' implementations (e.g., NonStop OS and NextStep)
+dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
 dnl do not support nested variable expansions.
 dnl See automake bug#9928 and bug#10237.
 am_make=${MAKE-make}
@@ -960,7 +1008,7 @@ else
   am_cv_make_support_nested_variables=no
 fi])
 if test $am_cv_make_support_nested_variables = yes; then
-  dnl Using `$V' instead of `$(V)' breaks IRIX make.
+  dnl Using '$V' instead of '$(V)' breaks IRIX make.
   AM_V='$(V)'
   AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
 else
@@ -977,44 +1025,40 @@ AC_SUBST([AM_BACKSLASH])dnl
 _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
 ])
 
-# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 1
-
 # AM_PROG_INSTALL_STRIP
 # ---------------------
-# One issue with vendor `install' (even GNU) is that you can't
+# One issue with vendor 'install' (even GNU) is that you can't
 # specify the program used to strip binaries.  This is especially
 # annoying in cross-compiling environments, where the build's strip
 # is unlikely to handle the host's binaries.
 # Fortunately install-sh will honor a STRIPPROG variable, so we
-# always use install-sh in `make install-strip', and initialize
+# always use install-sh in "make install-strip", and initialize
 # STRIPPROG with the value of the STRIP variable (set by the user).
 AC_DEFUN([AM_PROG_INSTALL_STRIP],
 [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
-# Installed binaries are usually stripped using `strip' when the user
-# run `make install-strip'.  However `strip' might not be the right
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip".  However 'strip' might not be the right
 # tool to use in cross-compilation environments, therefore Automake
-# will honor the `STRIP' environment variable to overrule this program.
-dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+# will honor the 'STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be 'maybe'.
 if test "$cross_compiling" != no; then
   AC_CHECK_TOOL([STRIP], [strip], :)
 fi
 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
-# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc.
+# Copyright (C) 2006-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 3
-
 # _AM_SUBST_NOTMAKE(VARIABLE)
 # ---------------------------
 # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
@@ -1028,18 +1072,16 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
 
 # Check how to create a tarball.                            -*- Autoconf -*-
 
-# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc.
+# Copyright (C) 2004-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 2
-
 # _AM_PROG_TAR(FORMAT)
 # --------------------
 # Check how to create a tarball in format FORMAT.
-# FORMAT should be one of `v7', `ustar', or `pax'.
+# FORMAT should be one of 'v7', 'ustar', or 'pax'.
 #
 # Substitute a variable $(am__tar) that is a command
 # writing to stdout a FORMAT-tarball containing the directory
@@ -1049,83 +1091,120 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
 # Substitute a variable $(am__untar) that extract such
 # a tarball read from stdin.
 #     $(am__untar) < result.tar
+#
 AC_DEFUN([_AM_PROG_TAR],
 [# Always define AMTAR for backward compatibility.  Yes, it's still used
 # in the wild :-(  We should find a proper way to deprecate it ...
 AC_SUBST([AMTAR], ['$${TAR-tar}'])
-m4_if([$1], [v7],
-     [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
-     [m4_case([$1], [ustar],, [pax],,
-              [m4_fatal([Unknown tar format])])
-AC_MSG_CHECKING([how to create a $1 tar archive])
-# Loop over all known methods to create a tar archive until one works.
+
+# We'll loop over all known methods to create a tar archive until one works.
 _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
-_am_tools=${am_cv_prog_tar_$1-$_am_tools}
-# Do not fold the above two line into one, because Tru64 sh and
-# Solaris sh will not grok spaces in the rhs of `-'.
-for _am_tool in $_am_tools
-do
-  case $_am_tool in
-  gnutar)
-    for _am_tar in tar gnutar gtar;
-    do
-      AM_RUN_LOG([$_am_tar --version]) && break
-    done
-    am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
-    am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
-    am__untar="$_am_tar -xf -"
-    ;;
-  plaintar)
-    # Must skip GNU tar: if it does not support --format= it doesn't create
-    # ustar tarball either.
-    (tar --version) >/dev/null 2>&1 && continue
-    am__tar='tar chf - "$$tardir"'
-    am__tar_='tar chf - "$tardir"'
-    am__untar='tar xf -'
-    ;;
-  pax)
-    am__tar='pax -L -x $1 -w "$$tardir"'
-    am__tar_='pax -L -x $1 -w "$tardir"'
-    am__untar='pax -r'
-    ;;
-  cpio)
-    am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
-    am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
-    am__untar='cpio -i -H $1 -d'
-    ;;
-  none)
-    am__tar=false
-    am__tar_=false
-    am__untar=false
-    ;;
-  esac
 
-  # If the value was cached, stop now.  We just wanted to have am__tar
-  # and am__untar set.
-  test -n "${am_cv_prog_tar_$1}" && break
+m4_if([$1], [v7],
+  [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+
+  [m4_case([$1],
+    [ustar],
+     [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+      # There is notably a 21 bits limit for the UID and the GID.  In fact,
+      # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+      # and bug#13588).
+      am_max_uid=2097151 # 2^21 - 1
+      am_max_gid=$am_max_uid
+      # The $UID and $GID variables are not portable, so we need to resort
+      # to the POSIX-mandated id(1) utility.  Errors in the 'id' calls
+      # below are definitely unexpected, so allow the users to see them
+      # (that is, avoid stderr redirection).
+      am_uid=`id -u || echo unknown`
+      am_gid=`id -g || echo unknown`
+      AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+      if test $am_uid -le $am_max_uid; then
+         AC_MSG_RESULT([yes])
+      else
+         AC_MSG_RESULT([no])
+         _am_tools=none
+      fi
+      AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+      if test $am_gid -le $am_max_gid; then
+         AC_MSG_RESULT([yes])
+      else
+        AC_MSG_RESULT([no])
+        _am_tools=none
+      fi],
+
+  [pax],
+    [],
+
+  [m4_fatal([Unknown tar format])])
+
+  AC_MSG_CHECKING([how to create a $1 tar archive])
+
+  # Go ahead even if we have the value already cached.  We do so because we
+  # need to set the values for the 'am__tar' and 'am__untar' variables.
+  _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+  for _am_tool in $_am_tools; do
+    case $_am_tool in
+    gnutar)
+      for _am_tar in tar gnutar gtar; do
+        AM_RUN_LOG([$_am_tar --version]) && break
+      done
+      am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+      am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+      am__untar="$_am_tar -xf -"
+      ;;
+    plaintar)
+      # Must skip GNU tar: if it does not support --format= it doesn't create
+      # ustar tarball either.
+      (tar --version) >/dev/null 2>&1 && continue
+      am__tar='tar chf - "$$tardir"'
+      am__tar_='tar chf - "$tardir"'
+      am__untar='tar xf -'
+      ;;
+    pax)
+      am__tar='pax -L -x $1 -w "$$tardir"'
+      am__tar_='pax -L -x $1 -w "$tardir"'
+      am__untar='pax -r'
+      ;;
+    cpio)
+      am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+      am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+      am__untar='cpio -i -H $1 -d'
+      ;;
+    none)
+      am__tar=false
+      am__tar_=false
+      am__untar=false
+      ;;
+    esac
 
-  # tar/untar a dummy directory, and stop if the command works
-  rm -rf conftest.dir
-  mkdir conftest.dir
-  echo GrepMe > conftest.dir/file
-  AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+    # If the value was cached, stop now.  We just wanted to have am__tar
+    # and am__untar set.
+    test -n "${am_cv_prog_tar_$1}" && break
+
+    # tar/untar a dummy directory, and stop if the command works.
+    rm -rf conftest.dir
+    mkdir conftest.dir
+    echo GrepMe > conftest.dir/file
+    AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+    rm -rf conftest.dir
+    if test -s conftest.tar; then
+      AM_RUN_LOG([$am__untar <conftest.tar])
+      AM_RUN_LOG([cat conftest.dir/file])
+      grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+    fi
+  done
   rm -rf conftest.dir
-  if test -s conftest.tar; then
-    AM_RUN_LOG([$am__untar <conftest.tar])
-    grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
-  fi
-done
-rm -rf conftest.dir
 
-AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
-AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+  AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+  AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+
 AC_SUBST([am__tar])
 AC_SUBST([am__untar])
 ]) # _AM_PROG_TAR
 
 m4_include([m4/gpg-error.m4])
 m4_include([m4/libtool.m4])
-m4_include([m4/lock.m4])
 m4_include([m4/ltoptions.m4])
 m4_include([m4/ltsugar.m4])
 m4_include([m4/ltversion.m4])
@@ -1134,5 +1213,4 @@ m4_include([m4/noexecstack.m4])
 m4_include([m4/onceonly.m4])
 m4_include([m4/socklen.m4])
 m4_include([m4/sys_socket_h.m4])
-m4_include([m4/threadlib.m4])
 m4_include([acinclude.m4])
index 1b1d232..531136b 100755 (executable)
@@ -1,9 +1,9 @@
 #! /bin/sh
-# Wrapper for compilers which do not understand `-c -o'.
+# Wrapper for compilers which do not understand '-c -o'.
 
-scriptversion=2005-05-14.22
+scriptversion=2012-10-14.11; # UTC
 
-# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
 # Written by Tom Tromey <tromey@cygnus.com>.
 #
 # This program is free software; you can redistribute it and/or modify
@@ -17,8 +17,7 @@ scriptversion=2005-05-14.22
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -29,21 +28,224 @@ scriptversion=2005-05-14.22
 # bugs to <bug-automake@gnu.org> or send patches to
 # <automake-patches@gnu.org>.
 
+nl='
+'
+
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent tools from complaining about whitespace usage.
+IFS=" ""       $nl"
+
+file_conv=
+
+# func_file_conv build_file lazy
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts. If the determined conversion
+# type is listed in (the comma separated) LAZY, no conversion will
+# take place.
+func_file_conv ()
+{
+  file=$1
+  case $file in
+    / | /[!/]*) # absolute file, and not a UNC file
+      if test -z "$file_conv"; then
+       # lazily determine how to convert abs files
+       case `uname -s` in
+         MINGW*)
+           file_conv=mingw
+           ;;
+         CYGWIN*)
+           file_conv=cygwin
+           ;;
+         *)
+           file_conv=wine
+           ;;
+       esac
+      fi
+      case $file_conv/,$2, in
+       *,$file_conv,*)
+         ;;
+       mingw/*)
+         file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+         ;;
+       cygwin/*)
+         file=`cygpath -m "$file" || echo "$file"`
+         ;;
+       wine/*)
+         file=`winepath -w "$file" || echo "$file"`
+         ;;
+      esac
+      ;;
+  esac
+}
+
+# func_cl_dashL linkdir
+# Make cl look for libraries in LINKDIR
+func_cl_dashL ()
+{
+  func_file_conv "$1"
+  if test -z "$lib_path"; then
+    lib_path=$file
+  else
+    lib_path="$lib_path;$file"
+  fi
+  linker_opts="$linker_opts -LIBPATH:$file"
+}
+
+# func_cl_dashl library
+# Do a library search-path lookup for cl
+func_cl_dashl ()
+{
+  lib=$1
+  found=no
+  save_IFS=$IFS
+  IFS=';'
+  for dir in $lib_path $LIB
+  do
+    IFS=$save_IFS
+    if $shared && test -f "$dir/$lib.dll.lib"; then
+      found=yes
+      lib=$dir/$lib.dll.lib
+      break
+    fi
+    if test -f "$dir/$lib.lib"; then
+      found=yes
+      lib=$dir/$lib.lib
+      break
+    fi
+    if test -f "$dir/lib$lib.a"; then
+      found=yes
+      lib=$dir/lib$lib.a
+      break
+    fi
+  done
+  IFS=$save_IFS
+
+  if test "$found" != yes; then
+    lib=$lib.lib
+  fi
+}
+
+# func_cl_wrapper cl arg...
+# Adjust compile command to suit cl
+func_cl_wrapper ()
+{
+  # Assume a capable shell
+  lib_path=
+  shared=:
+  linker_opts=
+  for arg
+  do
+    if test -n "$eat"; then
+      eat=
+    else
+      case $1 in
+       -o)
+         # configure might choose to run compile as 'compile cc -o foo foo.c'.
+         eat=1
+         case $2 in
+           *.o | *.[oO][bB][jJ])
+             func_file_conv "$2"
+             set x "$@" -Fo"$file"
+             shift
+             ;;
+           *)
+             func_file_conv "$2"
+             set x "$@" -Fe"$file"
+             shift
+             ;;
+         esac
+         ;;
+       -I)
+         eat=1
+         func_file_conv "$2" mingw
+         set x "$@" -I"$file"
+         shift
+         ;;
+       -I*)
+         func_file_conv "${1#-I}" mingw
+         set x "$@" -I"$file"
+         shift
+         ;;
+       -l)
+         eat=1
+         func_cl_dashl "$2"
+         set x "$@" "$lib"
+         shift
+         ;;
+       -l*)
+         func_cl_dashl "${1#-l}"
+         set x "$@" "$lib"
+         shift
+         ;;
+       -L)
+         eat=1
+         func_cl_dashL "$2"
+         ;;
+       -L*)
+         func_cl_dashL "${1#-L}"
+         ;;
+       -static)
+         shared=false
+         ;;
+       -Wl,*)
+         arg=${1#-Wl,}
+         save_ifs="$IFS"; IFS=','
+         for flag in $arg; do
+           IFS="$save_ifs"
+           linker_opts="$linker_opts $flag"
+         done
+         IFS="$save_ifs"
+         ;;
+       -Xlinker)
+         eat=1
+         linker_opts="$linker_opts $2"
+         ;;
+       -*)
+         set x "$@" "$1"
+         shift
+         ;;
+       *.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
+         func_file_conv "$1"
+         set x "$@" -Tp"$file"
+         shift
+         ;;
+       *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
+         func_file_conv "$1" mingw
+         set x "$@" "$file"
+         shift
+         ;;
+       *)
+         set x "$@" "$1"
+         shift
+         ;;
+      esac
+    fi
+    shift
+  done
+  if test -n "$linker_opts"; then
+    linker_opts="-link$linker_opts"
+  fi
+  exec "$@" $linker_opts
+  exit 1
+}
+
+eat=
+
 case $1 in
   '')
-     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
+     echo "$0: No command.  Try '$0 --help' for more information." 1>&2
      exit 1;
      ;;
   -h | --h*)
     cat <<\EOF
 Usage: compile [--help] [--version] PROGRAM [ARGS]
 
-Wrapper for compilers which do not understand `-c -o'.
-Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
+Wrapper for compilers which do not understand '-c -o'.
+Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
 arguments, and rename the output as expected.
 
 If you are trying to build a whole package this is not the
-right script to run: please start by reading the file `INSTALL'.
+right script to run: please start by reading the file 'INSTALL'.
 
 Report bugs to <bug-automake@gnu.org>.
 EOF
@@ -53,11 +255,13 @@ EOF
     echo "compile $scriptversion"
     exit $?
     ;;
+  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+    func_cl_wrapper "$@"      # Doesn't return...
+    ;;
 esac
 
 ofile=
 cfile=
-eat=
 
 for arg
 do
@@ -66,8 +270,8 @@ do
   else
     case $1 in
       -o)
-       # configure might choose to run compile as `compile cc -o foo foo.c'.
-       # So we strip `-o arg' only if arg is an object.
+       # configure might choose to run compile as 'compile cc -o foo foo.c'.
+       # So we strip '-o arg' only if arg is an object.
        eat=1
        case $2 in
          *.o | *.obj)
@@ -94,22 +298,22 @@ do
 done
 
 if test -z "$ofile" || test -z "$cfile"; then
-  # If no `-o' option was seen then we might have been invoked from a
+  # If no '-o' option was seen then we might have been invoked from a
   # pattern rule where we don't need one.  That is ok -- this is a
   # normal compilation that the losing compiler can handle.  If no
-  # `.c' file was seen then we are probably linking.  That is also
+  # '.c' file was seen then we are probably linking.  That is also
   # ok.
   exec "$@"
 fi
 
 # Name of file we expect compiler to create.
-cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
+cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
 
 # Create the lock directory.
-# Note: use `[/.-]' here to ensure that we don't use the same name
+# Note: use '[/\\:.-]' here to ensure that we don't use the same name
 # that we are using for the .o file.  Also, base the name on the expected
 # object file name, since that is what matters with a parallel build.
-lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d
+lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
 while true; do
   if mkdir "$lockdir" >/dev/null 2>&1; then
     break
@@ -124,9 +328,9 @@ trap "rmdir '$lockdir'; exit 1" 1 2 15
 ret=$?
 
 if test -f "$cofile"; then
-  mv "$cofile" "$ofile"
+  test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
 elif test -f "${cofile}bj"; then
-  mv "${cofile}bj" "$ofile"
+  test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
 fi
 
 rmdir "$lockdir"
@@ -138,5 +342,6 @@ exit $ret
 # eval: (add-hook 'write-file-hooks 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
 # End:
index 9afd676..dbfb978 100755 (executable)
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
-#   Copyright 1992-2013 Free Software Foundation, Inc.
+#   Copyright 1992-2015 Free Software Foundation, Inc.
 
-timestamp='2013-11-29'
+timestamp='2015-01-01'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -24,12 +24,12 @@ timestamp='2013-11-29'
 # program.  This Exception is an additional permission under section 7
 # of the GNU General Public License, version 3 ("GPLv3").
 #
-# Originally written by Per Bothner.
+# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
 #
 # You can get the latest version of this script from:
 # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
 #
-# Please send patches with a ChangeLog entry to config-patches@gnu.org.
+# Please send patches to <config-patches@gnu.org>.
 
 
 me=`echo "$0" | sed -e 's,.*/,,'`
@@ -50,7 +50,7 @@ version="\
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright 1992-2013 Free Software Foundation, Inc.
+Copyright 1992-2015 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -149,7 +149,7 @@ Linux|GNU|GNU/*)
        LIBC=gnu
        #endif
        EOF
-       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
        ;;
 esac
 
@@ -579,8 +579,9 @@ EOF
        else
                IBM_ARCH=powerpc
        fi
-       if [ -x /usr/bin/oslevel ] ; then
-               IBM_REV=`/usr/bin/oslevel`
+       if [ -x /usr/bin/lslpp ] ; then
+               IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
+                          awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
        else
                IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
        fi
@@ -826,7 +827,7 @@ EOF
     *:MINGW*:*)
        echo ${UNAME_MACHINE}-pc-mingw32
        exit ;;
-    i*:MSYS*:*)
+    *:MSYS*:*)
        echo ${UNAME_MACHINE}-pc-msys
        exit ;;
     i*:windows32*:*)
@@ -969,10 +970,10 @@ EOF
        eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
        test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
        ;;
-    or1k:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+    openrisc*:Linux:*:*)
+       echo or1k-unknown-linux-${LIBC}
        exit ;;
-    or32:Linux:*:*)
+    or32:Linux:*:* | or1k*:Linux:*:*)
        echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
        exit ;;
     padre:Linux:*:*)
@@ -1371,154 +1372,6 @@ EOF
        exit ;;
 esac
 
-eval $set_cc_for_build
-cat >$dummy.c <<EOF
-#ifdef _SEQUENT_
-# include <sys/types.h>
-# include <sys/utsname.h>
-#endif
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
-  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
-     I don't know....  */
-  printf ("mips-sony-bsd\n"); exit (0);
-#else
-#include <sys/param.h>
-  printf ("m68k-sony-newsos%s\n",
-#ifdef NEWSOS4
-       "4"
-#else
-       ""
-#endif
-       ); exit (0);
-#endif
-#endif
-
-#if defined (__arm) && defined (__acorn) && defined (__unix)
-  printf ("arm-acorn-riscix\n"); exit (0);
-#endif
-
-#if defined (hp300) && !defined (hpux)
-  printf ("m68k-hp-bsd\n"); exit (0);
-#endif
-
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
-#define __ARCHITECTURE__ "m68k"
-#endif
-  int version;
-  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
-  if (version < 4)
-    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
-  else
-    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
-  exit (0);
-#endif
-
-#if defined (MULTIMAX) || defined (n16)
-#if defined (UMAXV)
-  printf ("ns32k-encore-sysv\n"); exit (0);
-#else
-#if defined (CMU)
-  printf ("ns32k-encore-mach\n"); exit (0);
-#else
-  printf ("ns32k-encore-bsd\n"); exit (0);
-#endif
-#endif
-#endif
-
-#if defined (__386BSD__)
-  printf ("i386-pc-bsd\n"); exit (0);
-#endif
-
-#if defined (sequent)
-#if defined (i386)
-  printf ("i386-sequent-dynix\n"); exit (0);
-#endif
-#if defined (ns32000)
-  printf ("ns32k-sequent-dynix\n"); exit (0);
-#endif
-#endif
-
-#if defined (_SEQUENT_)
-    struct utsname un;
-
-    uname(&un);
-
-    if (strncmp(un.version, "V2", 2) == 0) {
-       printf ("i386-sequent-ptx2\n"); exit (0);
-    }
-    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
-       printf ("i386-sequent-ptx1\n"); exit (0);
-    }
-    printf ("i386-sequent-ptx\n"); exit (0);
-
-#endif
-
-#if defined (vax)
-# if !defined (ultrix)
-#  include <sys/param.h>
-#  if defined (BSD)
-#   if BSD == 43
-      printf ("vax-dec-bsd4.3\n"); exit (0);
-#   else
-#    if BSD == 199006
-      printf ("vax-dec-bsd4.3reno\n"); exit (0);
-#    else
-      printf ("vax-dec-bsd\n"); exit (0);
-#    endif
-#   endif
-#  else
-    printf ("vax-dec-bsd\n"); exit (0);
-#  endif
-# else
-    printf ("vax-dec-ultrix\n"); exit (0);
-# endif
-#endif
-
-#if defined (alliant) && defined (i860)
-  printf ("i860-alliant-bsd\n"); exit (0);
-#endif
-
-  exit (1);
-}
-EOF
-
-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
-       { echo "$SYSTEM_NAME"; exit; }
-
-# Apollos put the system type in the environment.
-
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
-
-# Convex versions that predate uname can use getsysinfo(1)
-
-if [ -x /usr/convex/getsysinfo ]
-then
-    case `getsysinfo -f cpu_type` in
-    c1*)
-       echo c1-convex-bsd
-       exit ;;
-    c2*)
-       if getsysinfo -f scalar_acc
-       then echo c32-convex-bsd
-       else echo c2-convex-bsd
-       fi
-       exit ;;
-    c34*)
-       echo c34-convex-bsd
-       exit ;;
-    c38*)
-       echo c38-convex-bsd
-       exit ;;
-    c4*)
-       echo c4-convex-bsd
-       exit ;;
-    esac
-fi
-
 cat >&2 <<EOF
 $0: unable to guess system type
 
index c547c68..c38b914 100755 (executable)
@@ -2,7 +2,7 @@
 # Output a system dependent set of variables, describing how to set the
 # run time search path of shared libraries in an executable.
 #
-#   Copyright 1996-2007 Free Software Foundation, Inc.
+#   Copyright 1996-2013 Free Software Foundation, Inc.
 #   Taken from GNU libtool, 2001
 #   Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
 #
@@ -25,7 +25,7 @@
 #   known workaround is to choose shorter directory names for the build
 #   directory and/or the installation directory.
 
-# All known linkers require a `.a' archive for static linking (except MSVC,
+# All known linkers require a '.a' archive for static linking (except MSVC,
 # which needs '.lib').
 libext=a
 shrext=.so
@@ -47,7 +47,7 @@ for cc_temp in $CC""; do
 done
 cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
 
-# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC.
+# Code taken from libtool.m4's _LT_COMPILER_PIC.
 
 wl=
 if test "$GCC" = yes; then
@@ -57,14 +57,7 @@ else
     aix*)
       wl='-Wl,'
       ;;
-    darwin*)
-      case $cc_basename in
-        xlc*)
-          wl='-Wl,'
-          ;;
-      esac
-      ;;
-    mingw* | cygwin* | pw32* | os2*)
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
       ;;
     hpux9* | hpux10* | hpux11*)
       wl='-Wl,'
@@ -72,24 +65,37 @@ else
     irix5* | irix6* | nonstopux*)
       wl='-Wl,'
       ;;
-    newsos6)
-      ;;
-    linux* | k*bsd*-gnu)
+    linux* | k*bsd*-gnu | kopensolaris*-gnu)
       case $cc_basename in
-        icc* | ecc*)
+        ecc*)
           wl='-Wl,'
           ;;
-        pgcc | pgf77 | pgf90)
+        icc* | ifort*)
+          wl='-Wl,'
+          ;;
+        lf95*)
+          wl='-Wl,'
+          ;;
+        nagfor*)
+          wl='-Wl,-Wl,,'
+          ;;
+        pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
           wl='-Wl,'
           ;;
         ccc*)
           wl='-Wl,'
           ;;
+        xl* | bgxl* | bgf* | mpixl*)
+          wl='-Wl,'
+          ;;
         como)
           wl='-lopt='
           ;;
         *)
           case `$CC -V 2>&1 | sed 5q` in
+            *Sun\ F* | *Sun*Fortran*)
+              wl=
+              ;;
             *Sun\ C*)
               wl='-Wl,'
               ;;
@@ -97,13 +103,24 @@ else
           ;;
       esac
       ;;
+    newsos6)
+      ;;
+    *nto* | *qnx*)
+      ;;
     osf3* | osf4* | osf5*)
       wl='-Wl,'
       ;;
     rdos*)
       ;;
     solaris*)
-      wl='-Wl,'
+      case $cc_basename in
+        f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+          wl='-Qoption ld '
+          ;;
+        *)
+          wl='-Wl,'
+          ;;
+      esac
       ;;
     sunos4*)
       wl='-Qoption ld '
@@ -124,7 +141,7 @@ else
   esac
 fi
 
-# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS.
+# Code taken from libtool.m4's _LT_LINKER_SHLIBS.
 
 hardcode_libdir_flag_spec=
 hardcode_libdir_separator=
@@ -132,7 +149,7 @@ hardcode_direct=no
 hardcode_minus_L=no
 
 case "$host_os" in
-  cygwin* | mingw* | pw32*)
+  cygwin* | mingw* | pw32* | cegcc*)
     # FIXME: the MSVC++ port hasn't been tested in a loooong time
     # When not using gcc, we currently assume that we are using
     # Microsoft Visual C++.
@@ -158,22 +175,21 @@ if test "$with_gnu_ld" = yes; then
   # option of GNU ld is called -rpath, not --rpath.
   hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
   case "$host_os" in
-    aix3* | aix4* | aix5*)
+    aix[3-9]*)
       # On AIX/PPC, the GNU linker is very broken
       if test "$host_cpu" != ia64; then
         ld_shlibs=no
       fi
       ;;
     amigaos*)
-      hardcode_libdir_flag_spec='-L$libdir'
-      hardcode_minus_L=yes
-      # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
-      # that the semantics of dynamic libraries on AmigaOS, at least up
-      # to version 4, is to share data among multiple programs linked
-      # with the same dynamic library.  Since this doesn't match the
-      # behavior of shared libraries on other platforms, we cannot use
-      # them.
-      ld_shlibs=no
+      case "$host_cpu" in
+        powerpc)
+          ;;
+        m68k)
+          hardcode_libdir_flag_spec='-L$libdir'
+          hardcode_minus_L=yes
+          ;;
+      esac
       ;;
     beos*)
       if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
@@ -182,7 +198,7 @@ if test "$with_gnu_ld" = yes; then
         ld_shlibs=no
       fi
       ;;
-    cygwin* | mingw* | pw32*)
+    cygwin* | mingw* | pw32* | cegcc*)
       # hardcode_libdir_flag_spec is actually meaningless, as there is
       # no search path for DLLs.
       hardcode_libdir_flag_spec='-L$libdir'
@@ -192,11 +208,13 @@ if test "$with_gnu_ld" = yes; then
         ld_shlibs=no
       fi
       ;;
+    haiku*)
+      ;;
     interix[3-9]*)
       hardcode_direct=no
       hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
       ;;
-    gnu* | linux* | k*bsd*-gnu)
+    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
       if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
         :
       else
@@ -254,7 +272,7 @@ else
         hardcode_direct=unsupported
       fi
       ;;
-    aix4* | aix5*)
+    aix[4-9]*)
       if test "$host_cpu" = ia64; then
         # On IA64, the linker does run time linking by default, so we don't
         # have to do anything special.
@@ -264,7 +282,7 @@ else
         # Test if we are trying to use run time linking or normal
         # AIX style linking. If -brtl is somewhere in LDFLAGS, we
         # need to do runtime linking.
-        case $host_os in aix4.[23]|aix4.[23].*|aix5*)
+        case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
           for ld_flag in $LDFLAGS; do
             if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
               aix_use_runtimelinking=yes
@@ -319,14 +337,18 @@ else
       fi
       ;;
     amigaos*)
-      hardcode_libdir_flag_spec='-L$libdir'
-      hardcode_minus_L=yes
-      # see comment about different semantics on the GNU ld section
-      ld_shlibs=no
+      case "$host_cpu" in
+        powerpc)
+          ;;
+        m68k)
+          hardcode_libdir_flag_spec='-L$libdir'
+          hardcode_minus_L=yes
+          ;;
+      esac
       ;;
     bsdi[45]*)
       ;;
-    cygwin* | mingw* | pw32*)
+    cygwin* | mingw* | pw32* | cegcc*)
       # When not using gcc, we currently assume that we are using
       # Microsoft Visual C++.
       # hardcode_libdir_flag_spec is actually meaningless, as there is
@@ -336,24 +358,15 @@ else
       ;;
     darwin* | rhapsody*)
       hardcode_direct=no
-      if test "$GCC" = yes ; then
+      if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then
         :
       else
-        case $cc_basename in
-          xlc*)
-            ;;
-          *)
-            ld_shlibs=no
-            ;;
-        esac
+        ld_shlibs=no
       fi
       ;;
     dgux*)
       hardcode_libdir_flag_spec='-L$libdir'
       ;;
-    freebsd1*)
-      ld_shlibs=no
-      ;;
     freebsd2.2*)
       hardcode_libdir_flag_spec='-R$libdir'
       hardcode_direct=yes
@@ -414,6 +427,8 @@ else
       hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
       hardcode_libdir_separator=:
       ;;
+    *nto* | *qnx*)
+      ;;
     openbsd*)
       if test -f /usr/libexec/ld.so; then
         hardcode_direct=yes
@@ -494,7 +509,7 @@ else
 fi
 
 # Check dynamic linker characteristics
-# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER.
+# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER.
 # Unlike libtool.m4, here we don't care about _all_ names of the library, but
 # only about the one the linker finds when passed -lNAME. This is the last
 # element of library_names_spec in libtool.m4, or possibly two of them if the
@@ -505,11 +520,16 @@ case "$host_os" in
   aix3*)
     library_names_spec='$libname.a'
     ;;
-  aix4* | aix5*)
+  aix[4-9]*)
     library_names_spec='$libname$shrext'
     ;;
   amigaos*)
-    library_names_spec='$libname.a'
+    case "$host_cpu" in
+      powerpc*)
+        library_names_spec='$libname$shrext' ;;
+      m68k)
+        library_names_spec='$libname.a' ;;
+    esac
     ;;
   beos*)
     library_names_spec='$libname$shrext'
@@ -517,7 +537,7 @@ case "$host_os" in
   bsdi[45]*)
     library_names_spec='$libname$shrext'
     ;;
-  cygwin* | mingw* | pw32*)
+  cygwin* | mingw* | pw32* | cegcc*)
     shrext=.dll
     library_names_spec='$libname.dll.a $libname.lib'
     ;;
@@ -528,8 +548,6 @@ case "$host_os" in
   dgux*)
     library_names_spec='$libname$shrext'
     ;;
-  freebsd1*)
-    ;;
   freebsd* | dragonfly*)
     case "$host_os" in
       freebsd[123]*)
@@ -541,6 +559,9 @@ case "$host_os" in
   gnu*)
     library_names_spec='$libname$shrext'
     ;;
+  haiku*)
+    library_names_spec='$libname$shrext'
+    ;;
   hpux9* | hpux10* | hpux11*)
     case $host_cpu in
       ia64*)
@@ -576,7 +597,7 @@ case "$host_os" in
     ;;
   linux*oldld* | linux*aout* | linux*coff*)
     ;;
-  linux* | k*bsd*-gnu)
+  linux* | k*bsd*-gnu | kopensolaris*-gnu)
     library_names_spec='$libname$shrext'
     ;;
   knetbsd*-gnu)
@@ -588,7 +609,7 @@ case "$host_os" in
   newsos6)
     library_names_spec='$libname$shrext'
     ;;
-  nto-qnx*)
+  *nto* | *qnx*)
     library_names_spec='$libname$shrext'
     ;;
   openbsd*)
@@ -619,6 +640,9 @@ case "$host_os" in
   sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
     library_names_spec='$libname$shrext'
     ;;
+  tpf*)
+    library_names_spec='$libname$shrext'
+    ;;
   uts4*)
     library_names_spec='$libname$shrext'
     ;;
index 61cb4bc..6d2e94c 100755 (executable)
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Configuration validation subroutine script.
-#   Copyright 1992-2013 Free Software Foundation, Inc.
+#   Copyright 1992-2015 Free Software Foundation, Inc.
 
-timestamp='2013-10-01'
+timestamp='2015-01-01'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -25,7 +25,7 @@ timestamp='2013-10-01'
 # of the GNU General Public License, version 3 ("GPLv3").
 
 
-# Please send patches with a ChangeLog entry to config-patches@gnu.org.
+# Please send patches to <config-patches@gnu.org>.
 #
 # Configuration subroutine to validate and canonicalize a configuration type.
 # Supply the specified configuration type as an argument.
@@ -68,7 +68,7 @@ Report bugs and patches to <config-patches@gnu.org>."
 version="\
 GNU config.sub ($timestamp)
 
-Copyright 1992-2013 Free Software Foundation, Inc.
+Copyright 1992-2015 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -260,7 +260,7 @@ case $basic_machine in
        | c4x | c8051 | clipper \
        | d10v | d30v | dlx | dsp16xx \
        | epiphany \
-       | fido | fr30 | frv \
+       | fido | fr30 | frv | ft32 \
        | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
        | hexagon \
        | i370 | i860 | i960 | ia64 \
@@ -283,8 +283,10 @@ case $basic_machine in
        | mips64vr5900 | mips64vr5900el \
        | mipsisa32 | mipsisa32el \
        | mipsisa32r2 | mipsisa32r2el \
+       | mipsisa32r6 | mipsisa32r6el \
        | mipsisa64 | mipsisa64el \
        | mipsisa64r2 | mipsisa64r2el \
+       | mipsisa64r6 | mipsisa64r6el \
        | mipsisa64sb1 | mipsisa64sb1el \
        | mipsisa64sr71k | mipsisa64sr71kel \
        | mipsr5900 | mipsr5900el \
@@ -296,11 +298,11 @@ case $basic_machine in
        | nds32 | nds32le | nds32be \
        | nios | nios2 | nios2eb | nios2el \
        | ns16k | ns32k \
-       | open8 \
-       | or1k | or32 \
+       | open8 | or1k | or1knd | or32 \
        | pdp10 | pdp11 | pj | pjl \
        | powerpc | powerpc64 | powerpc64le | powerpcle \
        | pyramid \
+       | riscv32 | riscv64 \
        | rl78 | rx \
        | score \
        | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
@@ -311,6 +313,7 @@ case $basic_machine in
        | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
        | ubicom32 \
        | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+       | visium \
        | we32k \
        | x86 | xc16x | xstormy16 | xtensa \
        | z8k | z80)
@@ -325,6 +328,9 @@ case $basic_machine in
        c6x)
                basic_machine=tic6x-unknown
                ;;
+       leon|leon[3-9])
+               basic_machine=sparc-$basic_machine
+               ;;
        m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
                basic_machine=$basic_machine-unknown
                os=-none
@@ -402,8 +408,10 @@ case $basic_machine in
        | mips64vr5900-* | mips64vr5900el-* \
        | mipsisa32-* | mipsisa32el-* \
        | mipsisa32r2-* | mipsisa32r2el-* \
+       | mipsisa32r6-* | mipsisa32r6el-* \
        | mipsisa64-* | mipsisa64el-* \
        | mipsisa64r2-* | mipsisa64r2el-* \
+       | mipsisa64r6-* | mipsisa64r6el-* \
        | mipsisa64sb1-* | mipsisa64sb1el-* \
        | mipsisa64sr71k-* | mipsisa64sr71kel-* \
        | mipsr5900-* | mipsr5900el-* \
@@ -415,6 +423,7 @@ case $basic_machine in
        | nios-* | nios2-* | nios2eb-* | nios2el-* \
        | none-* | np1-* | ns16k-* | ns32k-* \
        | open8-* \
+       | or1k*-* \
        | orion-* \
        | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
        | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
@@ -432,6 +441,7 @@ case $basic_machine in
        | ubicom32-* \
        | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
        | vax-* \
+       | visium-* \
        | we32k-* \
        | x86-* | x86_64-* | xc16x-* | xps100-* \
        | xstormy16-* | xtensa*-* \
@@ -769,6 +779,9 @@ case $basic_machine in
                basic_machine=m68k-isi
                os=-sysv
                ;;
+       leon-*|leon[3-9]-*)
+               basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
+               ;;
        m68knommu)
                basic_machine=m68k-unknown
                os=-linux
@@ -824,6 +837,10 @@ case $basic_machine in
                basic_machine=powerpc-unknown
                os=-morphos
                ;;
+       moxiebox)
+               basic_machine=moxie-unknown
+               os=-moxiebox
+               ;;
        msdos)
                basic_machine=i386-pc
                os=-msdos
@@ -1369,14 +1386,14 @@ case $os in
              | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
              | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
              | -linux-newlib* | -linux-musl* | -linux-uclibc* \
-             | -uxpv* | -beos* | -mpeix* | -udk* \
+             | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
              | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
              | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
              | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
              | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
              | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
              | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-             | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+             | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
        # Remember, each alternative MUST END IN *, to match a version number.
                ;;
        -qnx*)
@@ -1594,9 +1611,6 @@ case $basic_machine in
        mips*-*)
                os=-elf
                ;;
-       or1k-*)
-               os=-elf
-               ;;
        or32-*)
                os=-coff
                ;;
index ca5ea4e..4ebd5b3 100755 (executable)
@@ -1,10 +1,9 @@
 #! /bin/sh
 # depcomp - compile a program generating dependencies as side-effects
 
-scriptversion=2006-10-15.18
+scriptversion=2013-05-30.07; # UTC
 
-# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006 Free Software
-# Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -17,9 +16,7 @@ scriptversion=2006-10-15.18
 # GNU General Public License for more details.
 
 # You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -30,9 +27,9 @@ scriptversion=2006-10-15.18
 
 case $1 in
   '')
-     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
-     exit 1;
-     ;;
+    echo "$0: No command.  Try '$0 --help' for more information." 1>&2
+    exit 1;
+    ;;
   -h | --h*)
     cat <<\EOF
 Usage: depcomp [--help] [--version] PROGRAM [ARGS]
@@ -42,11 +39,11 @@ as side-effects.
 
 Environment variables:
   depmode     Dependency tracking mode.
-  source      Source file read by `PROGRAMS ARGS'.
-  object      Object file output by `PROGRAMS ARGS'.
+  source      Source file read by 'PROGRAMS ARGS'.
+  object      Object file output by 'PROGRAMS ARGS'.
   DEPDIR      directory where to store dependencies.
   depfile     Dependency file to output.
-  tmpdepfile  Temporary file to use when outputing dependencies.
+  tmpdepfile  Temporary file to use when outputting dependencies.
   libtool     Whether libtool is used (yes/no).
 
 Report bugs to <bug-automake@gnu.org>.
@@ -59,6 +56,66 @@ EOF
     ;;
 esac
 
+# Get the directory component of the given path, and save it in the
+# global variables '$dir'.  Note that this directory component will
+# be either empty or ending with a '/' character.  This is deliberate.
+set_dir_from ()
+{
+  case $1 in
+    */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
+      *) dir=;;
+  esac
+}
+
+# Get the suffix-stripped basename of the given path, and save it the
+# global variable '$base'.
+set_base_from ()
+{
+  base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
+}
+
+# If no dependency file was actually created by the compiler invocation,
+# we still have to create a dummy depfile, to avoid errors with the
+# Makefile "include basename.Plo" scheme.
+make_dummy_depfile ()
+{
+  echo "#dummy" > "$depfile"
+}
+
+# Factor out some common post-processing of the generated depfile.
+# Requires the auxiliary global variable '$tmpdepfile' to be set.
+aix_post_process_depfile ()
+{
+  # If the compiler actually managed to produce a dependency file,
+  # post-process it.
+  if test -f "$tmpdepfile"; then
+    # Each line is of the form 'foo.o: dependency.h'.
+    # Do two passes, one to just change these to
+    #   $object: dependency.h
+    # and one to simply output
+    #   dependency.h:
+    # which is needed to avoid the deleted-header problem.
+    { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
+      sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
+    } > "$depfile"
+    rm -f "$tmpdepfile"
+  else
+    make_dummy_depfile
+  fi
+}
+
+# A tabulation character.
+tab='  '
+# A newline character.
+nl='
+'
+# Character ranges might be problematic outside the C locale.
+# These definitions help.
+upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
+lower=abcdefghijklmnopqrstuvwxyz
+digits=0123456789
+alpha=${upper}${lower}
+
 if test -z "$depmode" || test -z "$source" || test -z "$object"; then
   echo "depcomp: Variables source, object and depmode must be set" 1>&2
   exit 1
@@ -71,6 +128,9 @@ tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
 
 rm -f "$tmpdepfile"
 
+# Avoid interferences from the environment.
+gccflag= dashmflag=
+
 # Some modes work just like other modes, but use different flags.  We
 # parameterize here, but still list the modes in the big case below,
 # to make depend.m4 easier to write.  Note that we *cannot* use a case
@@ -82,9 +142,32 @@ if test "$depmode" = hp; then
 fi
 
 if test "$depmode" = dashXmstdout; then
-   # This is just like dashmstdout with a different argument.
-   dashmflag=-xM
-   depmode=dashmstdout
+  # This is just like dashmstdout with a different argument.
+  dashmflag=-xM
+  depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+  # This is just like msvisualcpp but w/o cygpath translation.
+  # Just convert the backslash-escaped backslashes to single forward
+  # slashes to satisfy depend.m4
+  cygpath_u='sed s,\\\\,/,g'
+  depmode=msvisualcpp
+fi
+
+if test "$depmode" = msvc7msys; then
+  # This is just like msvc7 but w/o cygpath translation.
+  # Just convert the backslash-escaped backslashes to single forward
+  # slashes to satisfy depend.m4
+  cygpath_u='sed s,\\\\,/,g'
+  depmode=msvc7
+fi
+
+if test "$depmode" = xlc; then
+  # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
+  gccflag=-qmakedep=gcc,-MF
+  depmode=gcc
 fi
 
 case "$depmode" in
@@ -107,8 +190,7 @@ gcc3)
   done
   "$@"
   stat=$?
-  if test $stat -eq 0; then :
-  else
+  if test $stat -ne 0; then
     rm -f "$tmpdepfile"
     exit $stat
   fi
@@ -116,13 +198,17 @@ gcc3)
   ;;
 
 gcc)
+## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
+## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
+## (see the conditional assignment to $gccflag above).
 ## There are various ways to get dependency output from gcc.  Here's
 ## why we pick this rather obscure method:
 ## - Don't want to use -MD because we'd like the dependencies to end
 ##   up in a subdir.  Having to rename by hand is ugly.
 ##   (We might end up doing this anyway to support other compilers.)
 ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
-##   -MM, not -M (despite what the docs say).
+##   -MM, not -M (despite what the docs say).  Also, it might not be
+##   supported by the other compilers which use the 'gcc' depmode.
 ## - Using -M directly means running the compiler twice (even worse
 ##   than renaming).
   if test -z "$gccflag"; then
@@ -130,31 +216,31 @@ gcc)
   fi
   "$@" -Wp,"$gccflag$tmpdepfile"
   stat=$?
-  if test $stat -eq 0; then :
-  else
+  if test $stat -ne 0; then
     rm -f "$tmpdepfile"
     exit $stat
   fi
   rm -f "$depfile"
   echo "$object : \\" > "$depfile"
-  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
-## The second -e expression handles DOS-style file names with drive letters.
+  # The second -e expression handles DOS-style file names with drive
+  # letters.
   sed -e 's/^[^:]*: / /' \
       -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
-## This next piece of magic avoids the `deleted header file' problem.
+## This next piece of magic avoids the "deleted header file" problem.
 ## The problem is that when a header file which appears in a .P file
 ## is deleted, the dependency causes make to die (because there is
 ## typically no way to rebuild the header).  We avoid this by adding
 ## dummy dependencies for each header file.  Too bad gcc doesn't do
 ## this for us directly.
-  tr ' ' '
-' < "$tmpdepfile" |
-## Some versions of gcc put a space before the `:'.  On the theory
+## Some versions of gcc put a space before the ':'.  On the theory
 ## that the space means something, we add a space to the output as
-## well.
+## well.  hp depmode also adds that space, but also prefixes the VPATH
+## to the object.  Take care to not repeat it in the output.
 ## Some versions of the HPUX 10.20 sed can't process this invocation
 ## correctly.  Breaking it into two sed invocations is a workaround.
-    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  tr ' ' "$nl" < "$tmpdepfile" \
+    | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
+    | sed -e 's/$/ :/' >> "$depfile"
   rm -f "$tmpdepfile"
   ;;
 
@@ -172,8 +258,7 @@ sgi)
     "$@" -MDupdate "$tmpdepfile"
   fi
   stat=$?
-  if test $stat -eq 0; then :
-  else
+  if test $stat -ne 0; then
     rm -f "$tmpdepfile"
     exit $stat
   fi
@@ -181,99 +266,156 @@ sgi)
 
   if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
     echo "$object : \\" > "$depfile"
-
     # Clip off the initial element (the dependent).  Don't try to be
     # clever and replace this with sed code, as IRIX sed won't handle
     # lines with more than a fixed number of characters (4096 in
     # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
-    # the IRIX cc adds comments like `#:fec' to the end of the
+    # the IRIX cc adds comments like '#:fec' to the end of the
     # dependency line.
-    tr ' ' '
-' < "$tmpdepfile" \
-    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
-    tr '
-' ' ' >> $depfile
-    echo >> $depfile
-
+    tr ' ' "$nl" < "$tmpdepfile" \
+      | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
+      | tr "$nl" ' ' >> "$depfile"
+    echo >> "$depfile"
     # The second pass generates a dummy entry for each header file.
-    tr ' ' '
-' < "$tmpdepfile" \
-   | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
-   >> $depfile
+    tr ' ' "$nl" < "$tmpdepfile" \
+      | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+      >> "$depfile"
   else
-    # The sourcefile does not contain any dependencies, so just
-    # store a dummy comment line, to avoid errors with the Makefile
-    # "include basename.Plo" scheme.
-    echo "#dummy" > "$depfile"
+    make_dummy_depfile
   fi
   rm -f "$tmpdepfile"
   ;;
 
+xlc)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
 aix)
   # The C for AIX Compiler uses -M and outputs the dependencies
   # in a .u file.  In older versions, this file always lives in the
-  # current directory.  Also, the AIX compiler puts `$object:' at the
+  # current directory.  Also, the AIX compiler puts '$object:' at the
   # start of each line; $object doesn't have directory information.
   # Version 6 uses the directory in both cases.
-  stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
-  tmpdepfile="$stripped.u"
+  set_dir_from "$object"
+  set_base_from "$object"
   if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$base.u
+    tmpdepfile3=$dir.libs/$base.u
     "$@" -Wc,-M
   else
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$dir$base.u
+    tmpdepfile3=$dir$base.u
     "$@" -M
   fi
   stat=$?
-
-  if test -f "$tmpdepfile"; then :
-  else
-    stripped=`echo "$stripped" | sed 's,^.*/,,'`
-    tmpdepfile="$stripped.u"
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+    exit $stat
   fi
 
-  if test $stat -eq 0; then :
-  else
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  aix_post_process_depfile
+  ;;
+
+tcc)
+  # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
+  # FIXME: That version still under development at the moment of writing.
+  #        Make that this statement remains true also for stable, released
+  #        versions.
+  # It will wrap lines (doesn't matter whether long or short) with a
+  # trailing '\', as in:
+  #
+  #   foo.o : \
+  #    foo.c \
+  #    foo.h \
+  #
+  # It will put a trailing '\' even on the last line, and will use leading
+  # spaces rather than leading tabs (at least since its commit 0394caf7
+  # "Emit spaces for -MD").
+  "$@" -MD -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -ne 0; then
     rm -f "$tmpdepfile"
     exit $stat
   fi
-
-  if test -f "$tmpdepfile"; then
-    outname="$stripped.o"
-    # Each line is of the form `foo.o: dependent.h'.
-    # Do two passes, one to just change these to
-    # `$object: dependent.h' and one to simply `dependent.h:'.
-    sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
-    sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
-  else
-    # The sourcefile does not contain any dependencies, so just
-    # store a dummy comment line, to avoid errors with the Makefile
-    # "include basename.Plo" scheme.
-    echo "#dummy" > "$depfile"
-  fi
+  rm -f "$depfile"
+  # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
+  # We have to change lines of the first kind to '$object: \'.
+  sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
+  # And for each line of the second kind, we have to emit a 'dep.h:'
+  # dummy dependency, to avoid the deleted-header problem.
+  sed -n -e 's|^  *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
   rm -f "$tmpdepfile"
   ;;
 
-icc)
-  # Intel's C compiler understands `-MD -MF file'.  However on
-  #    icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
-  # ICC 7.0 will fill foo.d with something like
-  #    foo.o: sub/foo.c
-  #    foo.o: sub/foo.h
-  # which is wrong.  We want:
-  #    sub/foo.o: sub/foo.c
-  #    sub/foo.o: sub/foo.h
-  #    sub/foo.c:
-  #    sub/foo.h:
-  # ICC 7.1 will output
+## The order of this option in the case statement is important, since the
+## shell code in configure will try each of these formats in the order
+## listed in this file.  A plain '-MD' option would be understood by many
+## compilers, so we must ensure this comes after the gcc and icc options.
+pgcc)
+  # Portland's C compiler understands '-MD'.
+  # Will always output deps to 'file.d' where file is the root name of the
+  # source file under compilation, even if file resides in a subdirectory.
+  # The object file name does not affect the name of the '.d' file.
+  # pgcc 10.2 will output
   #    foo.o: sub/foo.c sub/foo.h
-  # and will wrap long lines using \ :
+  # and will wrap long lines using '\' :
   #    foo.o: sub/foo.c ... \
   #     sub/foo.h ... \
   #     ...
+  set_dir_from "$object"
+  # Use the source, not the object, to determine the base name, since
+  # that's sadly what pgcc will do too.
+  set_base_from "$source"
+  tmpdepfile=$base.d
+
+  # For projects that build the same source file twice into different object
+  # files, the pgcc approach of using the *source* file root name can cause
+  # problems in parallel builds.  Use a locking strategy to avoid stomping on
+  # the same $tmpdepfile.
+  lockdir=$base.d-lock
+  trap "
+    echo '$0: caught signal, cleaning up...' >&2
+    rmdir '$lockdir'
+    exit 1
+  " 1 2 13 15
+  numtries=100
+  i=$numtries
+  while test $i -gt 0; do
+    # mkdir is a portable test-and-set.
+    if mkdir "$lockdir" 2>/dev/null; then
+      # This process acquired the lock.
+      "$@" -MD
+      stat=$?
+      # Release the lock.
+      rmdir "$lockdir"
+      break
+    else
+      # If the lock is being held by a different process, wait
+      # until the winning process is done or we timeout.
+      while test -d "$lockdir" && test $i -gt 0; do
+        sleep 1
+        i=`expr $i - 1`
+      done
+    fi
+    i=`expr $i - 1`
+  done
+  trap - 1 2 13 15
+  if test $i -le 0; then
+    echo "$0: failed to acquire lock after $numtries attempts" >&2
+    echo "$0: check lockdir '$lockdir'" >&2
+    exit 1
+  fi
 
-  "$@" -MD -MF "$tmpdepfile"
-  stat=$?
-  if test $stat -eq 0; then :
-  else
+  if test $stat -ne 0; then
     rm -f "$tmpdepfile"
     exit $stat
   fi
@@ -285,8 +427,8 @@ icc)
   sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
   # Some versions of the HPUX 10.20 sed can't process this invocation
   # correctly.  Breaking it into two sed invocations is a workaround.
-  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
-    sed -e 's/$/ :/' >> "$depfile"
+  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
+    sed -e 's/$/ :/' >> "$depfile"
   rm -f "$tmpdepfile"
   ;;
 
@@ -297,9 +439,8 @@ hp2)
   # 'foo.d', which lands next to the object file, wherever that
   # happens to be.
   # Much of this is similar to the tru64 case; see comments there.
-  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
-  test "x$dir" = "x$object" && dir=
-  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+  set_dir_from  "$object"
+  set_base_from "$object"
   if test "$libtool" = yes; then
     tmpdepfile1=$dir$base.d
     tmpdepfile2=$dir.libs/$base.d
@@ -310,8 +451,7 @@ hp2)
     "$@" +Maked
   fi
   stat=$?
-  if test $stat -eq 0; then :
-  else
+  if test $stat -ne 0; then
      rm -f "$tmpdepfile1" "$tmpdepfile2"
      exit $stat
   fi
@@ -321,72 +461,107 @@ hp2)
     test -f "$tmpdepfile" && break
   done
   if test -f "$tmpdepfile"; then
-    sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
-    # Add `dependent.h:' lines.
-    sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile"
+    sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
+    # Add 'dependent.h:' lines.
+    sed -ne '2,${
+               s/^ *//
+               s/ \\*$//
+               s/$/:/
+               p
+             }' "$tmpdepfile" >> "$depfile"
   else
-    echo "#dummy" > "$depfile"
+    make_dummy_depfile
   fi
   rm -f "$tmpdepfile" "$tmpdepfile2"
   ;;
 
 tru64)
-   # The Tru64 compiler uses -MD to generate dependencies as a side
-   # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
-   # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
-   # dependencies in `foo.d' instead, so we check for that too.
-   # Subdirectories are respected.
-   dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
-   test "x$dir" = "x$object" && dir=
-   base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
-
-   if test "$libtool" = yes; then
-      # With Tru64 cc, shared objects can also be used to make a
-      # static library.  This mechanism is used in libtool 1.4 series to
-      # handle both shared and static libraries in a single compilation.
-      # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
-      #
-      # With libtool 1.5 this exception was removed, and libtool now
-      # generates 2 separate objects for the 2 libraries.  These two
-      # compilations output dependencies in $dir.libs/$base.o.d and
-      # in $dir$base.o.d.  We have to check for both files, because
-      # one of the two compilations can be disabled.  We should prefer
-      # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
-      # automatically cleaned when .libs/ is deleted, while ignoring
-      # the former would cause a distcleancheck panic.
-      tmpdepfile1=$dir.libs/$base.lo.d   # libtool 1.4
-      tmpdepfile2=$dir$base.o.d          # libtool 1.5
-      tmpdepfile3=$dir.libs/$base.o.d    # libtool 1.5
-      tmpdepfile4=$dir.libs/$base.d      # Compaq CCC V6.2-504
-      "$@" -Wc,-MD
-   else
-      tmpdepfile1=$dir$base.o.d
-      tmpdepfile2=$dir$base.d
-      tmpdepfile3=$dir$base.d
-      tmpdepfile4=$dir$base.d
-      "$@" -MD
-   fi
-
-   stat=$?
-   if test $stat -eq 0; then :
-   else
-      rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
-      exit $stat
-   fi
-
-   for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
-   do
-     test -f "$tmpdepfile" && break
-   done
-   if test -f "$tmpdepfile"; then
-      sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
-      # That's a tab and a space in the [].
-      sed -e 's,^.*\.[a-z]*:[   ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
-   else
-      echo "#dummy" > "$depfile"
-   fi
-   rm -f "$tmpdepfile"
-   ;;
+  # The Tru64 compiler uses -MD to generate dependencies as a side
+  # effect.  'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
+  # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+  # dependencies in 'foo.d' instead, so we check for that too.
+  # Subdirectories are respected.
+  set_dir_from  "$object"
+  set_base_from "$object"
+
+  if test "$libtool" = yes; then
+    # Libtool generates 2 separate objects for the 2 libraries.  These
+    # two compilations output dependencies in $dir.libs/$base.o.d and
+    # in $dir$base.o.d.  We have to check for both files, because
+    # one of the two compilations can be disabled.  We should prefer
+    # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+    # automatically cleaned when .libs/ is deleted, while ignoring
+    # the former would cause a distcleancheck panic.
+    tmpdepfile1=$dir$base.o.d          # libtool 1.5
+    tmpdepfile2=$dir.libs/$base.o.d    # Likewise.
+    tmpdepfile3=$dir.libs/$base.d      # Compaq CCC V6.2-504
+    "$@" -Wc,-MD
+  else
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir$base.d
+    tmpdepfile3=$dir$base.d
+    "$@" -MD
+  fi
+
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+    exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  # Same post-processing that is required for AIX mode.
+  aix_post_process_depfile
+  ;;
+
+msvc7)
+  if test "$libtool" = yes; then
+    showIncludes=-Wc,-showIncludes
+  else
+    showIncludes=-showIncludes
+  fi
+  "$@" $showIncludes > "$tmpdepfile"
+  stat=$?
+  grep -v '^Note: including file: ' "$tmpdepfile"
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  # The first sed program below extracts the file names and escapes
+  # backslashes for cygpath.  The second sed program outputs the file
+  # name when reading, but also accumulates all include files in the
+  # hold buffer in order to output them again at the end.  This only
+  # works with sed implementations that can handle large buffers.
+  sed < "$tmpdepfile" -n '
+/^Note: including file:  *\(.*\)/ {
+  s//\1/
+  s/\\/\\\\/g
+  p
+}' | $cygpath_u | sort -u | sed -n '
+s/ /\\ /g
+s/\(.*\)/'"$tab"'\1 \\/p
+s/.\(.*\) \\/\1:/
+H
+$ {
+  s/.*/'"$tab"'/
+  G
+  p
+}' >> "$depfile"
+  echo >> "$depfile" # make sure the fragment doesn't end with a backslash
+  rm -f "$tmpdepfile"
+  ;;
+
+msvc7msys)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
 
 #nosideeffect)
   # This comment above is used by automake to tell side-effect
@@ -399,13 +574,13 @@ dashmstdout)
 
   # Remove the call to Libtool.
   if test "$libtool" = yes; then
-    while test $1 != '--mode=compile'; do
+    while test "X$1" != 'X--mode=compile'; do
       shift
     done
     shift
   fi
 
-  # Remove `-o $object'.
+  # Remove '-o $object'.
   IFS=" "
   for arg
   do
@@ -425,18 +600,18 @@ dashmstdout)
   done
 
   test -z "$dashmflag" && dashmflag=-M
-  # Require at least two characters before searching for `:'
+  # Require at least two characters before searching for ':'
   # in the target name.  This is to cope with DOS-style filenames:
-  # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+  # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
   "$@" $dashmflag |
-    sed 's:^[  ]*[^: ][^:][^:]*\:[    ]*:'"$object"'\: :' > "$tmpdepfile"
+    sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
   rm -f "$depfile"
   cat < "$tmpdepfile" > "$depfile"
-  tr ' ' '
-' < "$tmpdepfile" | \
-## Some versions of the HPUX 10.20 sed can't process this invocation
-## correctly.  Breaking it into two sed invocations is a workaround.
-    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this sed invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  tr ' ' "$nl" < "$tmpdepfile" \
+    | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+    | sed -e 's/$/ :/' >> "$depfile"
   rm -f "$tmpdepfile"
   ;;
 
@@ -450,41 +625,51 @@ makedepend)
   "$@" || exit $?
   # Remove any Libtool call
   if test "$libtool" = yes; then
-    while test $1 != '--mode=compile'; do
+    while test "X$1" != 'X--mode=compile'; do
       shift
     done
     shift
   fi
   # X makedepend
   shift
-  cleared=no
-  for arg in "$@"; do
+  cleared=no eat=no
+  for arg
+  do
     case $cleared in
     no)
       set ""; shift
       cleared=yes ;;
     esac
+    if test $eat = yes; then
+      eat=no
+      continue
+    fi
     case "$arg" in
     -D*|-I*)
       set fnord "$@" "$arg"; shift ;;
     # Strip any option that makedepend may not understand.  Remove
     # the object too, otherwise makedepend will parse it as a source file.
+    -arch)
+      eat=yes ;;
     -*|$object)
       ;;
     *)
       set fnord "$@" "$arg"; shift ;;
     esac
   done
-  obj_suffix="`echo $object | sed 's/^.*\././'`"
+  obj_suffix=`echo "$object" | sed 's/^.*\././'`
   touch "$tmpdepfile"
   ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
   rm -f "$depfile"
-  cat < "$tmpdepfile" > "$depfile"
-  sed '1,2d' "$tmpdepfile" | tr ' ' '
-' | \
-## Some versions of the HPUX 10.20 sed can't process this invocation
-## correctly.  Breaking it into two sed invocations is a workaround.
-    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  # makedepend may prepend the VPATH from the source file name to the object.
+  # No need to regex-escape $object, excess matching of '.' is harmless.
+  sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process the last invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed '1,2d' "$tmpdepfile" \
+    | tr ' ' "$nl" \
+    | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+    | sed -e 's/$/ :/' >> "$depfile"
   rm -f "$tmpdepfile" "$tmpdepfile".bak
   ;;
 
@@ -495,13 +680,13 @@ cpp)
 
   # Remove the call to Libtool.
   if test "$libtool" = yes; then
-    while test $1 != '--mode=compile'; do
+    while test "X$1" != 'X--mode=compile'; do
       shift
     done
     shift
   fi
 
-  # Remove `-o $object'.
+  # Remove '-o $object'.
   IFS=" "
   for arg
   do
@@ -520,10 +705,10 @@ cpp)
     esac
   done
 
-  "$@" -E |
-    sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-       -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
-    sed '$ s: \\$::' > "$tmpdepfile"
+  "$@" -E \
+    sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+             -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+    sed '$ s: \\$::' > "$tmpdepfile"
   rm -f "$depfile"
   echo "$object : \\" > "$depfile"
   cat < "$tmpdepfile" >> "$depfile"
@@ -533,35 +718,56 @@ cpp)
 
 msvisualcpp)
   # Important note: in order to support this mode, a compiler *must*
-  # always write the preprocessed file to stdout, regardless of -o,
-  # because we must use -o when running libtool.
+  # always write the preprocessed file to stdout.
   "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
   IFS=" "
   for arg
   do
     case "$arg" in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
     "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
-       set fnord "$@"
-       shift
-       shift
-       ;;
+        set fnord "$@"
+        shift
+        shift
+        ;;
     *)
-       set fnord "$@" "$arg"
-       shift
-       shift
-       ;;
+        set fnord "$@" "$arg"
+        shift
+        shift
+        ;;
     esac
   done
-  "$@" -E |
-  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+  "$@" -E 2>/dev/null |
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
   rm -f "$depfile"
   echo "$object : \\" > "$depfile"
-  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::   \1 \\:p' >> "$depfile"
-  echo "       " >> "$depfile"
-  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
+  echo "$tab" >> "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
   rm -f "$tmpdepfile"
   ;;
 
+msvcmsys)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
 none)
   exec "$@"
   ;;
@@ -580,5 +786,6 @@ exit 0
 # eval: (add-hook 'write-file-hooks 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
 # End:
index 6781b98..377bb86 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 # install - install a program, script, or datafile
 
-scriptversion=2009-04-28.21; # UTC
+scriptversion=2011-11-20.07; # UTC
 
 # This originates from X11R5 (mit/util/scripts/install.sh), which was
 # later released in X11R6 (xc/config/util/install.sh) with the
@@ -35,7 +35,7 @@ scriptversion=2009-04-28.21; # UTC
 # FSF changes to this file are in the public domain.
 #
 # Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
+# 'make' implicit rules from creating a file called install from it
 # when there is no Makefile.
 #
 # This script is compatible with the BSD install script, but was written
@@ -156,6 +156,10 @@ while test $# -ne 0; do
     -s) stripcmd=$stripprog;;
 
     -t) dst_arg=$2
+       # Protect names problematic for 'test' and other utilities.
+       case $dst_arg in
+         -* | [=\(\)!]) dst_arg=./$dst_arg;;
+       esac
        shift;;
 
     -T) no_target_directory=true;;
@@ -186,6 +190,10 @@ if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
     fi
     shift # arg
     dst_arg=$arg
+    # Protect names problematic for 'test' and other utilities.
+    case $dst_arg in
+      -* | [=\(\)!]) dst_arg=./$dst_arg;;
+    esac
   done
 fi
 
@@ -194,13 +202,17 @@ if test $# -eq 0; then
     echo "$0: no input file specified." >&2
     exit 1
   fi
-  # It's OK to call `install-sh -d' without argument.
+  # It's OK to call 'install-sh -d' without argument.
   # This can happen when creating conditional directories.
   exit 0
 fi
 
 if test -z "$dir_arg"; then
-  trap '(exit $?); exit' 1 2 13 15
+  do_exit='(exit $ret); exit $ret'
+  trap "ret=129; $do_exit" 1
+  trap "ret=130; $do_exit" 2
+  trap "ret=141; $do_exit" 13
+  trap "ret=143; $do_exit" 15
 
   # Set umask so as not to create temps with too-generous modes.
   # However, 'strip' requires both read and write access to temps.
@@ -228,9 +240,9 @@ fi
 
 for src
 do
-  # Protect names starting with `-'.
+  # Protect names problematic for 'test' and other utilities.
   case $src in
-    -*) src=./$src;;
+    -* | [=\(\)!]) src=./$src;;
   esac
 
   if test -n "$dir_arg"; then
@@ -252,12 +264,7 @@ do
       echo "$0: no destination specified." >&2
       exit 1
     fi
-
     dst=$dst_arg
-    # Protect names starting with `-'.
-    case $dst in
-      -*) dst=./$dst;;
-    esac
 
     # If destination is a directory, append the input filename; won't work
     # if double slashes aren't ignored.
@@ -347,7 +354,7 @@ do
              if test -z "$dir_arg" || {
                   # Check for POSIX incompatibilities with -m.
                   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
-                  # other-writeable bit of parent directory when it shouldn't.
+                  # other-writable bit of parent directory when it shouldn't.
                   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
                   ls_ld_tmpdir=`ls -ld "$tmpdir"`
                   case $ls_ld_tmpdir in
@@ -385,7 +392,7 @@ do
 
       case $dstdir in
        /*) prefix='/';;
-       -*) prefix='./';;
+       [-=\(\)!]*) prefix='./';;
        *)  prefix='';;
       esac
 
@@ -403,7 +410,7 @@ do
 
       for d
       do
-       test -z "$d" && continue
+       test X"$d" = X && continue
 
        prefix=$prefix$d
        if test -d "$prefix"; then
index cd916c0..b3719cf 100755 (executable)
@@ -1,10 +1,9 @@
 #!/bin/sh
 # Get modification time of a file or directory and pretty-print it.
 
-scriptversion=2005-06-29.22
+scriptversion=2010-08-21.06; # UTC
 
-# Copyright (C) 1995, 1996, 1997, 2003, 2004, 2005 Free Software
-# Foundation, Inc.
+# Copyright (C) 1995-2013 Free Software Foundation, Inc.
 # written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, June 1995
 #
 # This program is free software; you can redistribute it and/or modify
@@ -18,8 +17,7 @@ scriptversion=2005-06-29.22
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -30,16 +28,26 @@ scriptversion=2005-06-29.22
 # bugs to <bug-automake@gnu.org> or send patches to
 # <automake-patches@gnu.org>.
 
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+fi
+
 case $1 in
   '')
-     echo "$0: No file.  Try \`$0 --help' for more information." 1>&2
+     echo "$0: No file.  Try '$0 --help' for more information." 1>&2
      exit 1;
      ;;
   -h | --h*)
     cat <<\EOF
 Usage: mdate-sh [--help] [--version] FILE
 
-Pretty-print the modification time of FILE.
+Pretty-print the modification day of FILE, in the format:
+1 January 1970
 
 Report bugs to <bug-automake@gnu.org>.
 EOF
@@ -51,6 +59,13 @@ EOF
     ;;
 esac
 
+error ()
+{
+  echo "$0: $1" >&2
+  exit 1
+}
+
+
 # Prevent date giving response in another language.
 LANG=C
 export LANG
@@ -60,7 +75,7 @@ LC_TIME=C
 export LC_TIME
 
 # GNU ls changes its time format in response to the TIME_STYLE
-# variable.  Since we cannot assume `unset' works, revert this
+# variable.  Since we cannot assume 'unset' works, revert this
 # variable to its documented default.
 if test "${TIME_STYLE+set}" = set; then
   TIME_STYLE=posix-long-iso
@@ -75,27 +90,32 @@ if ls -L /dev/null 1>/dev/null 2>&1; then
 else
   ls_command='ls -l -d'
 fi
+# Avoid user/group names that might have spaces, when possible.
+if ls -n /dev/null 1>/dev/null 2>&1; then
+  ls_command="$ls_command -n"
+fi
 
-# A `ls -l' line looks as follows on OS/2.
+# A 'ls -l' line looks as follows on OS/2.
 #  drwxrwx---        0 Aug 11  2001 foo
 # This differs from Unix, which adds ownership information.
 #  drwxrwx---   2 root  root      4096 Aug 11  2001 foo
 #
 # To find the date, we split the line on spaces and iterate on words
 # until we find a month.  This cannot work with files whose owner is a
-# user named `Jan', or `Feb', etc.  However, it's unlikely that `/'
+# user named "Jan", or "Feb", etc.  However, it's unlikely that '/'
 # will be owned by a user whose name is a month.  So we first look at
 # the extended ls output of the root directory to decide how many
 # words should be skipped to get the date.
 
 # On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below.
-set x`ls -l -d /`
+set x`$ls_command /`
 
 # Find which argument is the month.
 month=
 command=
 until test $month
 do
+  test $# -gt 0 || error "failed parsing '$ls_command /' output"
   shift
   # Add another shift to the command.
   command="$command shift;"
@@ -115,8 +135,10 @@ do
   esac
 done
 
+test -n "$month" || error "failed parsing '$ls_command /' output"
+
 # Get the extended ls output of the file or directory.
-set dummy x`eval "$ls_command \"\$save_arg1\""`
+set dummy x`eval "$ls_command \"\\\$save_arg1\""`
 
 # Remove all preceding arguments
 eval $command
@@ -197,5 +219,6 @@ echo $day $month $year
 # eval: (add-hook 'write-file-hooks 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
 # End:
index 894e786..db98974 100755 (executable)
@@ -1,11 +1,10 @@
 #! /bin/sh
-# Common stub for a few missing GNU programs while installing.
+# Common wrapper for a few potentially missing GNU programs.
 
-scriptversion=2005-06-08.21
+scriptversion=2013-10-28.13; # UTC
 
-# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005
-#   Free Software Foundation, Inc.
-# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -18,9 +17,7 @@ scriptversion=2005-06-08.21
 # GNU General Public License for more details.
 
 # You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -28,63 +25,40 @@ scriptversion=2005-06-08.21
 # the same distribution terms that you use for the rest of that program.
 
 if test $# -eq 0; then
-  echo 1>&2 "Try \`$0 --help' for more information"
+  echo 1>&2 "Try '$0 --help' for more information"
   exit 1
 fi
 
-run=:
+case $1 in
 
-# In the cases where this matters, `missing' is being run in the
-# srcdir already.
-if test -f configure.ac; then
-  configure_ac=configure.ac
-else
-  configure_ac=configure.in
-fi
-
-msg="missing on your system"
+  --is-lightweight)
+    # Used by our autoconf macros to check whether the available missing
+    # script is modern enough.
+    exit 0
+    ;;
 
-case "$1" in
---run)
-  # Try to run requested program, and just exit if it succeeds.
-  run=
-  shift
-  "$@" && exit 0
-  # Exit code 63 means version mismatch.  This often happens
-  # when the user try to use an ancient version of a tool on
-  # a file that requires a minimum version.  In this case we
-  # we should proceed has if the program had been absent, or
-  # if --run hadn't been passed.
-  if test $? = 63; then
-    run=:
-    msg="probably too old"
-  fi
-  ;;
+  --run)
+    # Back-compat with the calling convention used by older automake.
+    shift
+    ;;
 
   -h|--h|--he|--hel|--help)
     echo "\
 $0 [OPTION]... PROGRAM [ARGUMENT]...
 
-Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
-error status if there is no known handling for PROGRAM.
+Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
+to PROGRAM being missing or too old.
 
 Options:
   -h, --help      display this help and exit
   -v, --version   output version information and exit
-  --run           try to run the given command, and emulate it if it fails
 
 Supported PROGRAM values:
-  aclocal      touch file \`aclocal.m4'
-  autoconf     touch file \`configure'
-  autoheader   touch file \`config.h.in'
-  automake     touch all \`Makefile.in' files
-  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
-  flex         create \`lex.yy.c', if possible, from existing .c
-  help2man     touch the output file
-  lex          create \`lex.yy.c', if possible, from existing .c
-  makeinfo     touch the output file
-  tar          try tar, gnutar, gtar, then tar without non-portable flags
-  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]
+  aclocal   autoconf  autoheader   autom4te  automake  makeinfo
+  bison     yacc      flex         lex       help2man
+
+Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
+'g' are ignored when checking the name.
 
 Send bug reports to <bug-automake@gnu.org>."
     exit $?
@@ -96,265 +70,146 @@ Send bug reports to <bug-automake@gnu.org>."
     ;;
 
   -*)
-    echo 1>&2 "$0: Unknown \`$1' option"
-    echo 1>&2 "Try \`$0 --help' for more information"
+    echo 1>&2 "$0: unknown '$1' option"
+    echo 1>&2 "Try '$0 --help' for more information"
     exit 1
     ;;
 
 esac
 
-# Now exit if we have it, but it failed.  Also exit now if we
-# don't have it and --version was passed (most likely to detect
-# the program).
-case "$1" in
-  lex|yacc)
-    # Not GNU programs, they don't have --version.
-    ;;
-
-  tar)
-    if test -n "$run"; then
-       echo 1>&2 "ERROR: \`tar' requires --run"
-       exit 1
-    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
-       exit 1
-    fi
-    ;;
-
-  *)
-    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
-       # We have it, but it failed.
-       exit 1
-    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
-       # Could not run --version or --help.  This is probably someone
-       # running `$TOOL --version' or `$TOOL --help' to check whether
-       # $TOOL exists and not knowing $TOOL uses missing.
-       exit 1
-    fi
-    ;;
-esac
-
-# If it does not exist, or fails to run (possibly an outdated version),
-# try to emulate it.
-case "$1" in
-  aclocal*)
-    echo 1>&2 "\
-WARNING: \`$1' is $msg.  You should only need it if
-         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
-         to install the \`Automake' and \`Perl' packages.  Grab them from
-         any GNU archive site."
-    touch aclocal.m4
-    ;;
-
-  autoconf)
-    echo 1>&2 "\
-WARNING: \`$1' is $msg.  You should only need it if
-         you modified \`${configure_ac}'.  You might want to install the
-         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
-         archive site."
-    touch configure
-    ;;
-
-  autoheader)
-    echo 1>&2 "\
-WARNING: \`$1' is $msg.  You should only need it if
-         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
-         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
-         from any GNU archive site."
-    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
-    test -z "$files" && files="config.h"
-    touch_files=
-    for f in $files; do
-      case "$f" in
-      *:*) touch_files="$touch_files "`echo "$f" |
-                                      sed -e 's/^[^:]*://' -e 's/:.*//'`;;
-      *) touch_files="$touch_files $f.in";;
-      esac
-    done
-    touch $touch_files
-    ;;
-
-  automake*)
-    echo 1>&2 "\
-WARNING: \`$1' is $msg.  You should only need it if
-         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
-         You might want to install the \`Automake' and \`Perl' packages.
-         Grab them from any GNU archive site."
-    find . -type f -name Makefile.am -print |
-          sed 's/\.am$/.in/' |
-          while read f; do touch "$f"; done
-    ;;
-
-  autom4te)
-    echo 1>&2 "\
-WARNING: \`$1' is needed, but is $msg.
-         You might have modified some files without having the
-         proper tools for further handling them.
-         You can get \`$1' as part of \`Autoconf' from any GNU
-         archive site."
-
-    file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
-    test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
-    if test -f "$file"; then
-       touch $file
-    else
-       test -z "$file" || exec >$file
-       echo "#! /bin/sh"
-       echo "# Created by GNU Automake missing as a replacement of"
-       echo "#  $ $@"
-       echo "exit 0"
-       chmod +x $file
-       exit 1
-    fi
-    ;;
-
-  bison|yacc)
-    echo 1>&2 "\
-WARNING: \`$1' $msg.  You should only need it if
-         you modified a \`.y' file.  You may need the \`Bison' package
-         in order for those modifications to take effect.  You can get
-         \`Bison' from any GNU archive site."
-    rm -f y.tab.c y.tab.h
-    if [ $# -ne 1 ]; then
-        eval LASTARG="\${$#}"
-       case "$LASTARG" in
-       *.y)
-           SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
-           if [ -f "$SRCFILE" ]; then
-                cp "$SRCFILE" y.tab.c
-           fi
-           SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
-           if [ -f "$SRCFILE" ]; then
-                cp "$SRCFILE" y.tab.h
-           fi
-         ;;
-       esac
-    fi
-    if [ ! -f y.tab.h ]; then
-       echo >y.tab.h
-    fi
-    if [ ! -f y.tab.c ]; then
-       echo 'main() { return 0; }' >y.tab.c
-    fi
-    ;;
-
-  lex|flex)
-    echo 1>&2 "\
-WARNING: \`$1' is $msg.  You should only need it if
-         you modified a \`.l' file.  You may need the \`Flex' package
-         in order for those modifications to take effect.  You can get
-         \`Flex' from any GNU archive site."
-    rm -f lex.yy.c
-    if [ $# -ne 1 ]; then
-        eval LASTARG="\${$#}"
-       case "$LASTARG" in
-       *.l)
-           SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
-           if [ -f "$SRCFILE" ]; then
-                cp "$SRCFILE" lex.yy.c
-           fi
-         ;;
-       esac
-    fi
-    if [ ! -f lex.yy.c ]; then
-       echo 'main() { return 0; }' >lex.yy.c
-    fi
-    ;;
-
-  help2man)
-    echo 1>&2 "\
-WARNING: \`$1' is $msg.  You should only need it if
-        you modified a dependency of a manual page.  You may need the
-        \`Help2man' package in order for those modifications to take
-        effect.  You can get \`Help2man' from any GNU archive site."
-
-    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
-    if test -z "$file"; then
-       file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
-    fi
-    if [ -f "$file" ]; then
-       touch $file
-    else
-       test -z "$file" || exec >$file
-       echo ".ab help2man is required to generate this page"
-       exit 1
-    fi
-    ;;
-
-  makeinfo)
-    echo 1>&2 "\
-WARNING: \`$1' is $msg.  You should only need it if
-         you modified a \`.texi' or \`.texinfo' file, or any other file
-         indirectly affecting the aspect of the manual.  The spurious
-         call might also be the consequence of using a buggy \`make' (AIX,
-         DU, IRIX).  You might want to install the \`Texinfo' package or
-         the \`GNU make' package.  Grab either from any GNU archive site."
-    # The file to touch is that specified with -o ...
-    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
-    if test -z "$file"; then
-      # ... or it is the one specified with @setfilename ...
-      infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
-      file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile`
-      # ... or it is derived from the source name (dir/f.texi becomes f.info)
-      test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
-    fi
-    # If the file does not exist, the user really needs makeinfo;
-    # let's fail without touching anything.
-    test -f $file || exit 1
-    touch $file
-    ;;
-
-  tar)
-    shift
-
-    # We have already tried tar in the generic part.
-    # Look for gnutar/gtar before invocation to avoid ugly error
-    # messages.
-    if (gnutar --version > /dev/null 2>&1); then
-       gnutar "$@" && exit 0
-    fi
-    if (gtar --version > /dev/null 2>&1); then
-       gtar "$@" && exit 0
-    fi
-    firstarg="$1"
-    if shift; then
-       case "$firstarg" in
-       *o*)
-           firstarg=`echo "$firstarg" | sed s/o//`
-           tar "$firstarg" "$@" && exit 0
-           ;;
-       esac
-       case "$firstarg" in
-       *h*)
-           firstarg=`echo "$firstarg" | sed s/h//`
-           tar "$firstarg" "$@" && exit 0
-           ;;
-       esac
-    fi
-
-    echo 1>&2 "\
-WARNING: I can't seem to be able to run \`tar' with the given arguments.
-         You may want to install GNU tar or Free paxutils, or check the
-         command line arguments."
-    exit 1
-    ;;
-
-  *)
-    echo 1>&2 "\
-WARNING: \`$1' is needed, and is $msg.
-         You might have modified some files without having the
-         proper tools for further handling them.  Check the \`README' file,
-         it often tells you about the needed prerequisites for installing
-         this package.  You may also peek at any GNU archive site, in case
-         some other package would contain this missing \`$1' program."
-    exit 1
-    ;;
-esac
+# Run the given program, remember its exit status.
+"$@"; st=$?
+
+# If it succeeded, we are done.
+test $st -eq 0 && exit 0
+
+# Also exit now if we it failed (or wasn't found), and '--version' was
+# passed; such an option is passed most likely to detect whether the
+# program is present and works.
+case $2 in --version|--help) exit $st;; esac
+
+# Exit code 63 means version mismatch.  This often happens when the user
+# tries to use an ancient version of a tool on a file that requires a
+# minimum version.
+if test $st -eq 63; then
+  msg="probably too old"
+elif test $st -eq 127; then
+  # Program was missing.
+  msg="missing on your system"
+else
+  # Program was found and executed, but failed.  Give up.
+  exit $st
+fi
 
-exit 0
+perl_URL=http://www.perl.org/
+flex_URL=http://flex.sourceforge.net/
+gnu_software_URL=http://www.gnu.org/software
+
+program_details ()
+{
+  case $1 in
+    aclocal|automake)
+      echo "The '$1' program is part of the GNU Automake package:"
+      echo "<$gnu_software_URL/automake>"
+      echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
+      echo "<$gnu_software_URL/autoconf>"
+      echo "<$gnu_software_URL/m4/>"
+      echo "<$perl_URL>"
+      ;;
+    autoconf|autom4te|autoheader)
+      echo "The '$1' program is part of the GNU Autoconf package:"
+      echo "<$gnu_software_URL/autoconf/>"
+      echo "It also requires GNU m4 and Perl in order to run:"
+      echo "<$gnu_software_URL/m4/>"
+      echo "<$perl_URL>"
+      ;;
+  esac
+}
+
+give_advice ()
+{
+  # Normalize program name to check for.
+  normalized_program=`echo "$1" | sed '
+    s/^gnu-//; t
+    s/^gnu//; t
+    s/^g//; t'`
+
+  printf '%s\n' "'$1' is $msg."
+
+  configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
+  case $normalized_program in
+    autoconf*)
+      echo "You should only need it if you modified 'configure.ac',"
+      echo "or m4 files included by it."
+      program_details 'autoconf'
+      ;;
+    autoheader*)
+      echo "You should only need it if you modified 'acconfig.h' or"
+      echo "$configure_deps."
+      program_details 'autoheader'
+      ;;
+    automake*)
+      echo "You should only need it if you modified 'Makefile.am' or"
+      echo "$configure_deps."
+      program_details 'automake'
+      ;;
+    aclocal*)
+      echo "You should only need it if you modified 'acinclude.m4' or"
+      echo "$configure_deps."
+      program_details 'aclocal'
+      ;;
+   autom4te*)
+      echo "You might have modified some maintainer files that require"
+      echo "the 'autom4te' program to be rebuilt."
+      program_details 'autom4te'
+      ;;
+    bison*|yacc*)
+      echo "You should only need it if you modified a '.y' file."
+      echo "You may want to install the GNU Bison package:"
+      echo "<$gnu_software_URL/bison/>"
+      ;;
+    lex*|flex*)
+      echo "You should only need it if you modified a '.l' file."
+      echo "You may want to install the Fast Lexical Analyzer package:"
+      echo "<$flex_URL>"
+      ;;
+    help2man*)
+      echo "You should only need it if you modified a dependency" \
+           "of a man page."
+      echo "You may want to install the GNU Help2man package:"
+      echo "<$gnu_software_URL/help2man/>"
+    ;;
+    makeinfo*)
+      echo "You should only need it if you modified a '.texi' file, or"
+      echo "any other file indirectly affecting the aspect of the manual."
+      echo "You might want to install the Texinfo package:"
+      echo "<$gnu_software_URL/texinfo/>"
+      echo "The spurious makeinfo call might also be the consequence of"
+      echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
+      echo "want to install GNU make:"
+      echo "<$gnu_software_URL/make/>"
+      ;;
+    *)
+      echo "You might have modified some files without having the proper"
+      echo "tools for further handling them.  Check the 'README' file, it"
+      echo "often tells you about the needed prerequisites for installing"
+      echo "this package.  You may also peek at any GNU archive site, in"
+      echo "case some other package contains this missing '$1' program."
+      ;;
+  esac
+}
+
+give_advice "$1" | sed -e '1s/^/WARNING: /' \
+                       -e '2,$s/^/         /' >&2
+
+# Propagate the correct exit status (expected to be 127 for a program
+# not found, 63 for a program that failed due to version mismatch).
+exit $st
 
 # Local variables:
 # eval: (add-hook 'write-file-hooks 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
 # End:
index 8f99418..a181898 100644 (file)
@@ -3,15 +3,15 @@
 % Load plain if necessary, i.e., if running under initex.
 \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
 %
-\def\texinfoversion{2006-10-04.17}
+\def\texinfoversion{2007-05-03.09}
 %
 % Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
-% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free
-% Software Foundation, Inc.
+% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+% 2007 Free Software Foundation, Inc.
 %
 % This texinfo.tex file is free software; you can redistribute it and/or
 % modify it under the terms of the GNU General Public License as
-% published by the Free Software Foundation; either version 2, or (at
+% published by the Free Software Foundation; either version 3, or (at
 % your option) any later version.
 %
 % This texinfo.tex file is distributed in the hope that it will be
@@ -20,9 +20,8 @@
 % General Public License for more details.
 %
 % You should have received a copy of the GNU General Public License
-% along with this texinfo.tex file; see the file COPYING.  If not, write
-% to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-% Boston, MA 02110-1301, USA.
+% along with this texinfo.tex file; see the file COPYING.  If not,
+% see <http://www.gnu.org/licenses/>.
 %
 % As a special exception, when this file is read by TeX when processing
 % a Texinfo source document, you may use the result without
@@ -67,7 +66,7 @@
 \everyjob{\message{[Texinfo version \texinfoversion]}%
   \catcode`+=\active \catcode`\_=\active}
 
-\message{Basics,}
+
 \chardef\other=12
 
 % We never want plain's \outer definition of \+ in Texinfo.
@@ -1225,8 +1224,9 @@ where each line of input produces a line of output.}
 
 % To handle parens, we must adopt a different approach, since parens are
 % not active characters.  hyperref.dtx (which has the same problem as
-% us) handles it with this amazing macro to replace tokens.  I've
-% tinkered with it a little for texinfo, but it's definitely from there.
+% us) handles it with this amazing macro to replace tokens, with minor
+% changes for Texinfo.  It is included here under the GPL by permission
+% from the author, Heiko Oberdiek.
 %
 % #1 is the tokens to replace.
 % #2 is the replacement.
@@ -1255,13 +1255,44 @@ where each line of input produces a line of output.}
   \HyPsdSubst{)}{\realbackslash)}{#1}%
 }
 
+\newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images
+with PDF output, and none of those formats could be found.  (.eps cannot
+be supported due to the design of the PDF format; use regular TeX (DVI
+output) for that.)}
+
 \ifpdf
   \input pdfcolor
-  \pdfcatalog{/PageMode /UseOutlines}%
+  \pdfcatalog{/PageMode /UseOutlines}
+  %
   % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto).
   \def\dopdfimage#1#2#3{%
     \def\imagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}%
     \def\imageheight{#3}\setbox2 = \hbox{\ignorespaces #3}%
+    %
+    % pdftex (and the PDF format) support .png, .jpg, .pdf (among
+    % others).  Let's try in that order.
+    \let\pdfimgext=\empty
+    \begingroup
+      \openin 1 #1.png \ifeof 1
+        \openin 1 #1.jpg \ifeof 1
+          \openin 1 #1.jpeg \ifeof 1
+            \openin 1 #1.JPG \ifeof 1
+              \openin 1 #1.pdf \ifeof 1
+                \errhelp = \nopdfimagehelp
+                \errmessage{Could not find image file #1 for pdf}%
+              \else \gdef\pdfimgext{pdf}%
+              \fi
+            \else \gdef\pdfimgext{JPG}%
+            \fi
+          \else \gdef\pdfimgext{jpeg}%
+          \fi
+        \else \gdef\pdfimgext{jpg}%
+        \fi
+      \else \gdef\pdfimgext{png}%
+      \fi
+      \closein 1
+    \endgroup
+    %
     % without \immediate, pdftex seg faults when the same image is
     % included twice.  (Version 3.14159-pre-1.0-unofficial-20010704.)
     \ifnum\pdftexversion < 14
@@ -1272,28 +1303,36 @@ where each line of input produces a line of output.}
       \ifdim \wd0 >0pt width \imagewidth \fi
       \ifdim \wd2 >0pt height \imageheight \fi
       \ifnum\pdftexversion<13
-         #1.pdf%
+         #1.\pdfimgext
        \else
-         {#1.pdf}%
+         {#1.\pdfimgext}%
        \fi
     \ifnum\pdftexversion < 14 \else
       \pdfrefximage \pdflastximage
     \fi}
+  %
   \def\pdfmkdest#1{{%
     % We have to set dummies so commands such as @code, and characters
     % such as \, aren't expanded when present in a section title.
-    \atdummies
+    \indexnofonts
+    \turnoffactive
     \activebackslashdouble
+    \makevalueexpandable
     \def\pdfdestname{#1}%
     \backslashparens\pdfdestname
-    \pdfdest name{\pdfdestname} xyz%
-  }}%
+    \safewhatsit{\pdfdest name{\pdfdestname} xyz}%
+  }}
   %
   % used to mark target names; must be expandable.
-  \def\pdfmkpgn#1{#1}%
+  \def\pdfmkpgn#1{#1}
   %
-  \let\linkcolor = \Blue  % was Cyan, but that seems light?
+  % by default, use a color that is dark enough to print on paper as
+  % nearly black, but still distinguishable for online viewing.
+  % (Defined in pdfcolor.tex.)
+  \let\urlcolor = \BrickRed
+  \let\linkcolor = \BrickRed
   \def\endlink{\Black\pdfendlink}
+  %
   % Adding outlines to PDF; macros for calculating structure of outlines
   % come from Petr Olsak
   \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0%
@@ -1425,7 +1464,7 @@ where each line of input produces a line of output.}
       \def\@{@}%
       \let\/=\empty
       \makevalueexpandable
-      \leavevmode\Red
+      \leavevmode\urlcolor
       \startlink attr{/Border [0 0 0]}%
         user{/Subtype /Link /A << /S /URI /URI (#1) >>}%
     \endgroup}
@@ -1515,11 +1554,276 @@ where each line of input produces a line of output.}
   }%
 }
 
+%
+% PDF CMaps.  See also LaTeX's t1.cmap.
+%
+% \cmapOT1
+\ifpdf
+  \begingroup
+    \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+    \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1-0)
+%%Title: (TeX-OT1-0 TeX OT1 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+8 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<23> <26> <0023>
+<28> <3B> <0028>
+<3F> <5B> <003F>
+<5D> <5E> <005D>
+<61> <7A> <0061>
+<7B> <7C> <2013>
+endbfrange
+40 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <00660066>
+<0C> <00660069>
+<0D> <0066006C>
+<0E> <006600660069>
+<0F> <00660066006C>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<21> <0021>
+<22> <201D>
+<27> <2019>
+<3C> <00A1>
+<3D> <003D>
+<3E> <00BF>
+<5C> <201C>
+<5F> <02D9>
+<60> <2018>
+<7D> <02DD>
+<7E> <007E>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+    }\endgroup
+  \expandafter\edef\csname cmapOT1\endcsname#1{%
+    \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+  }%
+%
+% \cmapOT1IT
+  \begingroup
+    \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+    \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1IT-0)
+%%Title: (TeX-OT1IT-0 TeX OT1IT 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1IT)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1IT-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+8 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<25> <26> <0025>
+<28> <3B> <0028>
+<3F> <5B> <003F>
+<5D> <5E> <005D>
+<61> <7A> <0061>
+<7B> <7C> <2013>
+endbfrange
+42 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <00660066>
+<0C> <00660069>
+<0D> <0066006C>
+<0E> <006600660069>
+<0F> <00660066006C>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<21> <0021>
+<22> <201D>
+<23> <0023>
+<24> <00A3>
+<27> <2019>
+<3C> <00A1>
+<3D> <003D>
+<3E> <00BF>
+<5C> <201C>
+<5F> <02D9>
+<60> <2018>
+<7D> <02DD>
+<7E> <007E>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+    }\endgroup
+  \expandafter\edef\csname cmapOT1IT\endcsname#1{%
+    \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+  }%
+%
+% \cmapOT1TT
+  \begingroup
+    \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+    \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1TT-0)
+%%Title: (TeX-OT1TT-0 TeX OT1TT 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1TT)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1TT-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+5 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<21> <26> <0021>
+<28> <5F> <0028>
+<61> <7E> <0061>
+endbfrange
+32 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <2191>
+<0C> <2193>
+<0D> <0027>
+<0E> <00A1>
+<0F> <00BF>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<20> <2423>
+<27> <2019>
+<60> <2018>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+    }\endgroup
+  \expandafter\edef\csname cmapOT1TT\endcsname#1{%
+    \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+  }%
+\else
+  \expandafter\let\csname cmapOT1\endcsname\gobble
+  \expandafter\let\csname cmapOT1IT\endcsname\gobble
+  \expandafter\let\csname cmapOT1TT\endcsname\gobble
+\fi
+
 
 % Set the font macro #1 to the font named #2, adding on the
 % specified font prefix (normally `cm').
-% #3 is the font's design size, #4 is a scale factor
-\def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4}
+% #3 is the font's design size, #4 is a scale factor, #5 is the CMap
+% encoding (currently only OT1, OT1IT and OT1TT are allowed, pass
+% empty to omit).
+\def\setfont#1#2#3#4#5{%
+  \font#1=\fontprefix#2#3 scaled #4
+  \csname cmap#5\endcsname#1%
+}
+% This is what gets called when #5 of \setfont is empty.
+\let\cmap\gobble
 
 
 % Use cm as the default font prefix.
@@ -1548,63 +1852,63 @@ where each line of input produces a line of output.}
 % Definitions for a main text size of 11pt.  This is the default in
 % Texinfo.
 %
-\def\definetextfontsizexi{
+\def\definetextfontsizexi{%
 % Text fonts (11.2pt, magstep1).
 \def\textnominalsize{11pt}
 \edef\mainmagstep{\magstephalf}
-\setfont\textrm\rmshape{10}{\mainmagstep}
-\setfont\texttt\ttshape{10}{\mainmagstep}
-\setfont\textbf\bfshape{10}{\mainmagstep}
-\setfont\textit\itshape{10}{\mainmagstep}
-\setfont\textsl\slshape{10}{\mainmagstep}
-\setfont\textsf\sfshape{10}{\mainmagstep}
-\setfont\textsc\scshape{10}{\mainmagstep}
-\setfont\textttsl\ttslshape{10}{\mainmagstep}
+\setfont\textrm\rmshape{10}{\mainmagstep}{OT1}
+\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT}
+\setfont\textbf\bfshape{10}{\mainmagstep}{OT1}
+\setfont\textit\itshape{10}{\mainmagstep}{OT1IT}
+\setfont\textsl\slshape{10}{\mainmagstep}{OT1}
+\setfont\textsf\sfshape{10}{\mainmagstep}{OT1}
+\setfont\textsc\scshape{10}{\mainmagstep}{OT1}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT}
 \font\texti=cmmi10 scaled \mainmagstep
 \font\textsy=cmsy10 scaled \mainmagstep
 
 % A few fonts for @defun names and args.
-\setfont\defbf\bfshape{10}{\magstep1}
-\setfont\deftt\ttshape{10}{\magstep1}
-\setfont\defttsl\ttslshape{10}{\magstep1}
+\setfont\defbf\bfshape{10}{\magstep1}{OT1}
+\setfont\deftt\ttshape{10}{\magstep1}{OT1TT}
+\setfont\defttsl\ttslshape{10}{\magstep1}{OT1TT}
 \def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
 
 % Fonts for indices, footnotes, small examples (9pt).
 \def\smallnominalsize{9pt}
-\setfont\smallrm\rmshape{9}{1000}
-\setfont\smalltt\ttshape{9}{1000}
-\setfont\smallbf\bfshape{10}{900}
-\setfont\smallit\itshape{9}{1000}
-\setfont\smallsl\slshape{9}{1000}
-\setfont\smallsf\sfshape{9}{1000}
-\setfont\smallsc\scshape{10}{900}
-\setfont\smallttsl\ttslshape{10}{900}
+\setfont\smallrm\rmshape{9}{1000}{OT1}
+\setfont\smalltt\ttshape{9}{1000}{OT1TT}
+\setfont\smallbf\bfshape{10}{900}{OT1}
+\setfont\smallit\itshape{9}{1000}{OT1IT}
+\setfont\smallsl\slshape{9}{1000}{OT1}
+\setfont\smallsf\sfshape{9}{1000}{OT1}
+\setfont\smallsc\scshape{10}{900}{OT1}
+\setfont\smallttsl\ttslshape{10}{900}{OT1TT}
 \font\smalli=cmmi9
 \font\smallsy=cmsy9
 
 % Fonts for small examples (8pt).
 \def\smallernominalsize{8pt}
-\setfont\smallerrm\rmshape{8}{1000}
-\setfont\smallertt\ttshape{8}{1000}
-\setfont\smallerbf\bfshape{10}{800}
-\setfont\smallerit\itshape{8}{1000}
-\setfont\smallersl\slshape{8}{1000}
-\setfont\smallersf\sfshape{8}{1000}
-\setfont\smallersc\scshape{10}{800}
-\setfont\smallerttsl\ttslshape{10}{800}
+\setfont\smallerrm\rmshape{8}{1000}{OT1}
+\setfont\smallertt\ttshape{8}{1000}{OT1TT}
+\setfont\smallerbf\bfshape{10}{800}{OT1}
+\setfont\smallerit\itshape{8}{1000}{OT1IT}
+\setfont\smallersl\slshape{8}{1000}{OT1}
+\setfont\smallersf\sfshape{8}{1000}{OT1}
+\setfont\smallersc\scshape{10}{800}{OT1}
+\setfont\smallerttsl\ttslshape{10}{800}{OT1TT}
 \font\smalleri=cmmi8
 \font\smallersy=cmsy8
 
 % Fonts for title page (20.4pt):
 \def\titlenominalsize{20pt}
-\setfont\titlerm\rmbshape{12}{\magstep3}
-\setfont\titleit\itbshape{10}{\magstep4}
-\setfont\titlesl\slbshape{10}{\magstep4}
-\setfont\titlett\ttbshape{12}{\magstep3}
-\setfont\titlettsl\ttslshape{10}{\magstep4}
-\setfont\titlesf\sfbshape{17}{\magstep1}
+\setfont\titlerm\rmbshape{12}{\magstep3}{OT1}
+\setfont\titleit\itbshape{10}{\magstep4}{OT1IT}
+\setfont\titlesl\slbshape{10}{\magstep4}{OT1}
+\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT}
+\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT}
+\setfont\titlesf\sfbshape{17}{\magstep1}{OT1}
 \let\titlebf=\titlerm
-\setfont\titlesc\scbshape{10}{\magstep4}
+\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
 \font\titlei=cmmi12 scaled \magstep3
 \font\titlesy=cmsy10 scaled \magstep4
 \def\authorrm{\secrm}
@@ -1612,53 +1916,53 @@ where each line of input produces a line of output.}
 
 % Chapter (and unnumbered) fonts (17.28pt).
 \def\chapnominalsize{17pt}
-\setfont\chaprm\rmbshape{12}{\magstep2}
-\setfont\chapit\itbshape{10}{\magstep3}
-\setfont\chapsl\slbshape{10}{\magstep3}
-\setfont\chaptt\ttbshape{12}{\magstep2}
-\setfont\chapttsl\ttslshape{10}{\magstep3}
-\setfont\chapsf\sfbshape{17}{1000}
+\setfont\chaprm\rmbshape{12}{\magstep2}{OT1}
+\setfont\chapit\itbshape{10}{\magstep3}{OT1IT}
+\setfont\chapsl\slbshape{10}{\magstep3}{OT1}
+\setfont\chaptt\ttbshape{12}{\magstep2}{OT1TT}
+\setfont\chapttsl\ttslshape{10}{\magstep3}{OT1TT}
+\setfont\chapsf\sfbshape{17}{1000}{OT1}
 \let\chapbf=\chaprm
-\setfont\chapsc\scbshape{10}{\magstep3}
+\setfont\chapsc\scbshape{10}{\magstep3}{OT1}
 \font\chapi=cmmi12 scaled \magstep2
 \font\chapsy=cmsy10 scaled \magstep3
 
 % Section fonts (14.4pt).
 \def\secnominalsize{14pt}
-\setfont\secrm\rmbshape{12}{\magstep1}
-\setfont\secit\itbshape{10}{\magstep2}
-\setfont\secsl\slbshape{10}{\magstep2}
-\setfont\sectt\ttbshape{12}{\magstep1}
-\setfont\secttsl\ttslshape{10}{\magstep2}
-\setfont\secsf\sfbshape{12}{\magstep1}
+\setfont\secrm\rmbshape{12}{\magstep1}{OT1}
+\setfont\secit\itbshape{10}{\magstep2}{OT1IT}
+\setfont\secsl\slbshape{10}{\magstep2}{OT1}
+\setfont\sectt\ttbshape{12}{\magstep1}{OT1TT}
+\setfont\secttsl\ttslshape{10}{\magstep2}{OT1TT}
+\setfont\secsf\sfbshape{12}{\magstep1}{OT1}
 \let\secbf\secrm
-\setfont\secsc\scbshape{10}{\magstep2}
+\setfont\secsc\scbshape{10}{\magstep2}{OT1}
 \font\seci=cmmi12 scaled \magstep1
 \font\secsy=cmsy10 scaled \magstep2
 
 % Subsection fonts (13.15pt).
 \def\ssecnominalsize{13pt}
-\setfont\ssecrm\rmbshape{12}{\magstephalf}
-\setfont\ssecit\itbshape{10}{1315}
-\setfont\ssecsl\slbshape{10}{1315}
-\setfont\ssectt\ttbshape{12}{\magstephalf}
-\setfont\ssecttsl\ttslshape{10}{1315}
-\setfont\ssecsf\sfbshape{12}{\magstephalf}
+\setfont\ssecrm\rmbshape{12}{\magstephalf}{OT1}
+\setfont\ssecit\itbshape{10}{1315}{OT1IT}
+\setfont\ssecsl\slbshape{10}{1315}{OT1}
+\setfont\ssectt\ttbshape{12}{\magstephalf}{OT1TT}
+\setfont\ssecttsl\ttslshape{10}{1315}{OT1TT}
+\setfont\ssecsf\sfbshape{12}{\magstephalf}{OT1}
 \let\ssecbf\ssecrm
-\setfont\ssecsc\scbshape{10}{1315}
+\setfont\ssecsc\scbshape{10}{1315}{OT1}
 \font\sseci=cmmi12 scaled \magstephalf
 \font\ssecsy=cmsy10 scaled 1315
 
 % Reduced fonts for @acro in text (10pt).
 \def\reducednominalsize{10pt}
-\setfont\reducedrm\rmshape{10}{1000}
-\setfont\reducedtt\ttshape{10}{1000}
-\setfont\reducedbf\bfshape{10}{1000}
-\setfont\reducedit\itshape{10}{1000}
-\setfont\reducedsl\slshape{10}{1000}
-\setfont\reducedsf\sfshape{10}{1000}
-\setfont\reducedsc\scshape{10}{1000}
-\setfont\reducedttsl\ttslshape{10}{1000}
+\setfont\reducedrm\rmshape{10}{1000}{OT1}
+\setfont\reducedtt\ttshape{10}{1000}{OT1TT}
+\setfont\reducedbf\bfshape{10}{1000}{OT1}
+\setfont\reducedit\itshape{10}{1000}{OT1IT}
+\setfont\reducedsl\slshape{10}{1000}{OT1}
+\setfont\reducedsf\sfshape{10}{1000}{OT1}
+\setfont\reducedsc\scshape{10}{1000}{OT1}
+\setfont\reducedttsl\ttslshape{10}{1000}{OT1TT}
 \font\reducedi=cmmi10
 \font\reducedsy=cmsy10
 
@@ -1677,59 +1981,59 @@ where each line of input produces a line of output.}
 % Text fonts (10pt).
 \def\textnominalsize{10pt}
 \edef\mainmagstep{1000}
-\setfont\textrm\rmshape{10}{\mainmagstep}
-\setfont\texttt\ttshape{10}{\mainmagstep}
-\setfont\textbf\bfshape{10}{\mainmagstep}
-\setfont\textit\itshape{10}{\mainmagstep}
-\setfont\textsl\slshape{10}{\mainmagstep}
-\setfont\textsf\sfshape{10}{\mainmagstep}
-\setfont\textsc\scshape{10}{\mainmagstep}
-\setfont\textttsl\ttslshape{10}{\mainmagstep}
+\setfont\textrm\rmshape{10}{\mainmagstep}{OT1}
+\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT}
+\setfont\textbf\bfshape{10}{\mainmagstep}{OT1}
+\setfont\textit\itshape{10}{\mainmagstep}{OT1IT}
+\setfont\textsl\slshape{10}{\mainmagstep}{OT1}
+\setfont\textsf\sfshape{10}{\mainmagstep}{OT1}
+\setfont\textsc\scshape{10}{\mainmagstep}{OT1}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT}
 \font\texti=cmmi10 scaled \mainmagstep
 \font\textsy=cmsy10 scaled \mainmagstep
 
 % A few fonts for @defun names and args.
-\setfont\defbf\bfshape{10}{\magstephalf}
-\setfont\deftt\ttshape{10}{\magstephalf}
-\setfont\defttsl\ttslshape{10}{\magstephalf}
+\setfont\defbf\bfshape{10}{\magstephalf}{OT1}
+\setfont\deftt\ttshape{10}{\magstephalf}{OT1TT}
+\setfont\defttsl\ttslshape{10}{\magstephalf}{OT1TT}
 \def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
 
 % Fonts for indices, footnotes, small examples (9pt).
 \def\smallnominalsize{9pt}
-\setfont\smallrm\rmshape{9}{1000}
-\setfont\smalltt\ttshape{9}{1000}
-\setfont\smallbf\bfshape{10}{900}
-\setfont\smallit\itshape{9}{1000}
-\setfont\smallsl\slshape{9}{1000}
-\setfont\smallsf\sfshape{9}{1000}
-\setfont\smallsc\scshape{10}{900}
-\setfont\smallttsl\ttslshape{10}{900}
+\setfont\smallrm\rmshape{9}{1000}{OT1}
+\setfont\smalltt\ttshape{9}{1000}{OT1TT}
+\setfont\smallbf\bfshape{10}{900}{OT1}
+\setfont\smallit\itshape{9}{1000}{OT1IT}
+\setfont\smallsl\slshape{9}{1000}{OT1}
+\setfont\smallsf\sfshape{9}{1000}{OT1}
+\setfont\smallsc\scshape{10}{900}{OT1}
+\setfont\smallttsl\ttslshape{10}{900}{OT1TT}
 \font\smalli=cmmi9
 \font\smallsy=cmsy9
 
 % Fonts for small examples (8pt).
 \def\smallernominalsize{8pt}
-\setfont\smallerrm\rmshape{8}{1000}
-\setfont\smallertt\ttshape{8}{1000}
-\setfont\smallerbf\bfshape{10}{800}
-\setfont\smallerit\itshape{8}{1000}
-\setfont\smallersl\slshape{8}{1000}
-\setfont\smallersf\sfshape{8}{1000}
-\setfont\smallersc\scshape{10}{800}
-\setfont\smallerttsl\ttslshape{10}{800}
+\setfont\smallerrm\rmshape{8}{1000}{OT1}
+\setfont\smallertt\ttshape{8}{1000}{OT1TT}
+\setfont\smallerbf\bfshape{10}{800}{OT1}
+\setfont\smallerit\itshape{8}{1000}{OT1IT}
+\setfont\smallersl\slshape{8}{1000}{OT1}
+\setfont\smallersf\sfshape{8}{1000}{OT1}
+\setfont\smallersc\scshape{10}{800}{OT1}
+\setfont\smallerttsl\ttslshape{10}{800}{OT1TT}
 \font\smalleri=cmmi8
 \font\smallersy=cmsy8
 
 % Fonts for title page (20.4pt):
 \def\titlenominalsize{20pt}
-\setfont\titlerm\rmbshape{12}{\magstep3}
-\setfont\titleit\itbshape{10}{\magstep4}
-\setfont\titlesl\slbshape{10}{\magstep4}
-\setfont\titlett\ttbshape{12}{\magstep3}
-\setfont\titlettsl\ttslshape{10}{\magstep4}
-\setfont\titlesf\sfbshape{17}{\magstep1}
+\setfont\titlerm\rmbshape{12}{\magstep3}{OT1}
+\setfont\titleit\itbshape{10}{\magstep4}{OT1IT}
+\setfont\titlesl\slbshape{10}{\magstep4}{OT1}
+\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT}
+\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT}
+\setfont\titlesf\sfbshape{17}{\magstep1}{OT1}
 \let\titlebf=\titlerm
-\setfont\titlesc\scbshape{10}{\magstep4}
+\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
 \font\titlei=cmmi12 scaled \magstep3
 \font\titlesy=cmsy10 scaled \magstep4
 \def\authorrm{\secrm}
@@ -1737,53 +2041,53 @@ where each line of input produces a line of output.}
 
 % Chapter fonts (14.4pt).
 \def\chapnominalsize{14pt}
-\setfont\chaprm\rmbshape{12}{\magstep1}
-\setfont\chapit\itbshape{10}{\magstep2}
-\setfont\chapsl\slbshape{10}{\magstep2}
-\setfont\chaptt\ttbshape{12}{\magstep1}
-\setfont\chapttsl\ttslshape{10}{\magstep2}
-\setfont\chapsf\sfbshape{12}{\magstep1}
+\setfont\chaprm\rmbshape{12}{\magstep1}{OT1}
+\setfont\chapit\itbshape{10}{\magstep2}{OT1IT}
+\setfont\chapsl\slbshape{10}{\magstep2}{OT1}
+\setfont\chaptt\ttbshape{12}{\magstep1}{OT1TT}
+\setfont\chapttsl\ttslshape{10}{\magstep2}{OT1TT}
+\setfont\chapsf\sfbshape{12}{\magstep1}{OT1}
 \let\chapbf\chaprm
-\setfont\chapsc\scbshape{10}{\magstep2}
+\setfont\chapsc\scbshape{10}{\magstep2}{OT1}
 \font\chapi=cmmi12 scaled \magstep1
 \font\chapsy=cmsy10 scaled \magstep2
 
 % Section fonts (12pt).
 \def\secnominalsize{12pt}
-\setfont\secrm\rmbshape{12}{1000}
-\setfont\secit\itbshape{10}{\magstep1}
-\setfont\secsl\slbshape{10}{\magstep1}
-\setfont\sectt\ttbshape{12}{1000}
-\setfont\secttsl\ttslshape{10}{\magstep1}
-\setfont\secsf\sfbshape{12}{1000}
+\setfont\secrm\rmbshape{12}{1000}{OT1}
+\setfont\secit\itbshape{10}{\magstep1}{OT1IT}
+\setfont\secsl\slbshape{10}{\magstep1}{OT1}
+\setfont\sectt\ttbshape{12}{1000}{OT1TT}
+\setfont\secttsl\ttslshape{10}{\magstep1}{OT1TT}
+\setfont\secsf\sfbshape{12}{1000}{OT1}
 \let\secbf\secrm
-\setfont\secsc\scbshape{10}{\magstep1}
+\setfont\secsc\scbshape{10}{\magstep1}{OT1}
 \font\seci=cmmi12
 \font\secsy=cmsy10 scaled \magstep1
 
 % Subsection fonts (10pt).
 \def\ssecnominalsize{10pt}
-\setfont\ssecrm\rmbshape{10}{1000}
-\setfont\ssecit\itbshape{10}{1000}
-\setfont\ssecsl\slbshape{10}{1000}
-\setfont\ssectt\ttbshape{10}{1000}
-\setfont\ssecttsl\ttslshape{10}{1000}
-\setfont\ssecsf\sfbshape{10}{1000}
+\setfont\ssecrm\rmbshape{10}{1000}{OT1}
+\setfont\ssecit\itbshape{10}{1000}{OT1IT}
+\setfont\ssecsl\slbshape{10}{1000}{OT1}
+\setfont\ssectt\ttbshape{10}{1000}{OT1TT}
+\setfont\ssecttsl\ttslshape{10}{1000}{OT1TT}
+\setfont\ssecsf\sfbshape{10}{1000}{OT1}
 \let\ssecbf\ssecrm
-\setfont\ssecsc\scbshape{10}{1000}
+\setfont\ssecsc\scbshape{10}{1000}{OT1}
 \font\sseci=cmmi10
 \font\ssecsy=cmsy10
 
 % Reduced fonts for @acro in text (9pt).
 \def\reducednominalsize{9pt}
-\setfont\reducedrm\rmshape{9}{1000}
-\setfont\reducedtt\ttshape{9}{1000}
-\setfont\reducedbf\bfshape{10}{900}
-\setfont\reducedit\itshape{9}{1000}
-\setfont\reducedsl\slshape{9}{1000}
-\setfont\reducedsf\sfshape{9}{1000}
-\setfont\reducedsc\scshape{10}{900}
-\setfont\reducedttsl\ttslshape{10}{900}
+\setfont\reducedrm\rmshape{9}{1000}{OT1}
+\setfont\reducedtt\ttshape{9}{1000}{OT1TT}
+\setfont\reducedbf\bfshape{10}{900}{OT1}
+\setfont\reducedit\itshape{9}{1000}{OT1IT}
+\setfont\reducedsl\slshape{9}{1000}{OT1}
+\setfont\reducedsf\sfshape{9}{1000}{OT1}
+\setfont\reducedsc\scshape{10}{900}{OT1}
+\setfont\reducedttsl\ttslshape{10}{900}{OT1TT}
 \font\reducedi=cmmi9
 \font\reducedsy=cmsy9
 
@@ -1941,10 +2245,10 @@ where each line of input produces a line of output.}
 \newcount\fontdepth \fontdepth=0
 
 % Fonts for short table of contents.
-\setfont\shortcontrm\rmshape{12}{1000}
-\setfont\shortcontbf\bfshape{10}{\magstep1}  % no cmb12
-\setfont\shortcontsl\slshape{12}{1000}
-\setfont\shortconttt\ttshape{12}{1000}
+\setfont\shortcontrm\rmshape{12}{1000}{OT1}
+\setfont\shortcontbf\bfshape{10}{\magstep1}{OT1}  % no cmb12
+\setfont\shortcontsl\slshape{12}{1000}{OT1}
+\setfont\shortconttt\ttshape{12}{1000}{OT1TT}
 
 %% Add scribe-like font environments, plus @l for inline lisp (usually sans
 %% serif) and @ii for TeX italic
@@ -2007,7 +2311,7 @@ where each line of input produces a line of output.}
   \null
 }
 \def\samp#1{`\tclose{#1}'\null}
-\setfont\keyrm\rmshape{8}{1000}
+\setfont\keyrm\rmshape{8}{1000}{OT1}
 \font\keysy=cmsy9
 \def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
   \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
@@ -2015,6 +2319,7 @@ where each line of input produces a line of output.}
      \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
     \kern-0.4pt\hrule}%
   \kern-.06em\raise0.4pt\hbox{\angleright}}}}
+\def\key #1{{\nohyphenation \uppercase{#1}}\null}
 % The old definition, with no lozenge:
 %\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null}
 \def\ctrl #1{{\tt \rawbackslash \hat}#1}
@@ -3710,11 +4015,7 @@ where each line of input produces a line of output.}
     %
     \edef\writeto{\csname#1indfile\endcsname}%
     %
-    \ifvmode
-      \dosubindsanitize
-    \else
-      \dosubindwrite
-    \fi
+    \safewhatsit\dosubindwrite
   }%
   \fi
 }
@@ -3751,13 +4052,13 @@ where each line of input produces a line of output.}
   \temp
 }
 
-% Take care of unwanted page breaks:
+% Take care of unwanted page breaks/skips around a whatsit:
 %
 % If a skip is the last thing on the list now, preserve it
 % by backing up by \lastskip, doing the \write, then inserting
 % the skip again.  Otherwise, the whatsit generated by the
-% \write will make \lastskip zero.  The result is that sequences
-% like this:
+% \write or \pdfdest will make \lastskip zero.  The result is that
+% sequences like this:
 % @end defun
 % @tindex whatever
 % @defun ...
@@ -3781,13 +4082,19 @@ where each line of input produces a line of output.}
 %
 \edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname}
 %
+\newskip\whatsitskip
+\newcount\whatsitpenalty
+%
 % ..., ready, GO:
 %
-\def\dosubindsanitize{%
+\def\safewhatsit#1{%
+\ifhmode
+  #1%
+\else
   % \lastskip and \lastpenalty cannot both be nonzero simultaneously.
-  \skip0 = \lastskip
+  \whatsitskip = \lastskip
   \edef\lastskipmacro{\the\lastskip}%
-  \count255 = \lastpenalty
+  \whatsitpenalty = \lastpenalty
   %
   % If \lastskip is nonzero, that means the last item was a
   % skip.  And since a skip is discardable, that means this
@@ -3796,10 +4103,10 @@ where each line of input produces a line of output.}
   % breakpoint, therefore no \nobreak needed.
   \ifx\lastskipmacro\zeroskipmacro
   \else
-    \vskip-\skip0
+    \vskip-\whatsitskip
   \fi
   %
-  \dosubindwrite
+  #1%
   %
   \ifx\lastskipmacro\zeroskipmacro
     % If \lastskip was zero, perhaps the last item was a penalty, and
@@ -3813,13 +4120,14 @@ where each line of input produces a line of output.}
     %   Description.
     % would allow a break between the index-whatever whatsit
     % and the "Description." paragraph.
-    \ifnum\count255>9999 \penalty\count255 \fi
+    \ifnum\whatsitpenalty>9999 \penalty\whatsitpenalty \fi
   \else
     % On the other hand, if we had a nonzero \lastskip,
     % this make-up glue would be preceded by a non-discardable item
     % (the whatsit from the \write), so we must insert a \nobreak.
-    \nobreak\vskip\skip0
+    \nobreak\vskip\whatsitskip
   \fi
+\fi
 }
 
 % The index entry written in the file actually looks like
@@ -3862,6 +4170,7 @@ where each line of input produces a line of output.}
   %
   \smallfonts \rm
   \tolerance = 9500
+  \plainfrenchspacing
   \everypar = {}% don't want the \kern\-parindent from indentation suppression.
   %
   % See if the index file exists and is nonempty.
@@ -4131,6 +4440,34 @@ where each line of input produces a line of output.}
 %
 % All done with double columns.
 \def\enddoublecolumns{%
+  % The following penalty ensures that the page builder is exercised
+  % _before_ we change the output routine.  This is necessary in the
+  % following situation:
+  %
+  % The last section of the index consists only of a single entry.
+  % Before this section, \pagetotal is less than \pagegoal, so no
+  % break occurs before the last section starts.  However, the last
+  % section, consisting of \initial and the single \entry, does not
+  % fit on the page and has to be broken off.  Without the following
+  % penalty the page builder will not be exercised until \eject
+  % below, and by that time we'll already have changed the output
+  % routine to the \balancecolumns version, so the next-to-last
+  % double-column page will be processed with \balancecolumns, which
+  % is wrong:  The two columns will go to the main vertical list, with
+  % the broken-off section in the recent contributions.  As soon as
+  % the output routine finishes, TeX starts reconsidering the page
+  % break.  The two columns and the broken-off section both fit on the
+  % page, because the two columns now take up only half of the page
+  % goal.  When TeX sees \eject from below which follows the final
+  % section, it invokes the new output routine that we've set after
+  % \balancecolumns below; \onepageout will try to fit the two columns
+  % and the final section into the vbox of \pageheight (see
+  % \pagebody), causing an overfull box.
+  %
+  % Note that glue won't work here, because glue does not exercise the
+  % page builder, unlike penalties (see The TeXbook, pp. 280-281).
+  \penalty0
+  %
   \output = {%
     % Split the last of the double-column material.  Leave it on the
     % current page, no automatic page break.
@@ -5247,12 +5584,18 @@ where each line of input produces a line of output.}
 \let\SETdispenvsize\relax
 \def\setnormaldispenv{%
   \ifx\SETdispenvsize\smallword
+    % end paragraph for sake of leading, in case document has no blank
+    % line.  This is redundant with what happens in \aboveenvbreak, but
+    % we need to do it before changing the fonts, and it's inconvenient
+    % to change the fonts afterward.
+    \ifnum \lastpenalty=10000 \else \endgraf \fi
     \smallexamplefonts \rm
   \fi
 }
 \def\setsmalldispenv{%
   \ifx\SETdispenvsize\nosmallword
   \else
+    \ifnum \lastpenalty=10000 \else \endgraf \fi
     \smallexamplefonts \rm
   \fi
 }
@@ -5553,27 +5896,35 @@ where each line of input produces a line of output.}
   \endgroup
 }
 
+
 \message{defuns,}
 % @defun etc.
 
 \newskip\defbodyindent \defbodyindent=.4in
 \newskip\defargsindent \defargsindent=50pt
 \newskip\deflastargmargin \deflastargmargin=18pt
+\newcount\defunpenalty
 
 % Start the processing of @deffn:
 \def\startdefun{%
   \ifnum\lastpenalty<10000
     \medbreak
+    \defunpenalty=10003 % Will keep this @deffn together with the
+                        % following @def command, see below.
   \else
     % If there are two @def commands in a row, we'll have a \nobreak,
     % which is there to keep the function description together with its
     % header.  But if there's nothing but headers, we need to allow a
     % break somewhere.  Check specifically for penalty 10002, inserted
-    % by \defargscommonending, instead of 10000, since the sectioning
+    % by \printdefunline, instead of 10000, since the sectioning
     % commands also insert a nobreak penalty, and we don't want to allow
     % a break between a section heading and a defun.
     %
-    \ifnum\lastpenalty=10002 \penalty2000 \fi
+    % As a minor refinement, we avoid "club" headers by signalling
+    % with penalty of 10003 after the very first @deffn in the
+    % sequence (see above), and penalty of 10002 after any following
+    % @def command.
+    \ifnum\lastpenalty=10002 \penalty2000 \else \defunpenalty=10002 \fi
     %
     % Similarly, after a section heading, do not allow a break.
     % But do insert the glue.
@@ -5591,7 +5942,7 @@ where each line of input produces a line of output.}
   %
   % As above, allow line break if we have multiple x headers in a row.
   % It's not a great place, though.
-  \ifnum\lastpenalty=10002 \penalty3000 \fi
+  \ifnum\lastpenalty=10002 \penalty3000 \else \defunpenalty=10002 \fi
   %
   % And now, it's time to reuse the body of the original defun:
   \expandafter\gobbledefun#1%
@@ -5609,7 +5960,7 @@ where each line of input produces a line of output.}
     \advance\rightskip by 0pt plus 1fil
     \endgraf
     \nobreak\vskip -\parskip
-    \penalty 10002  % signal to \startdefun and \dodefunx
+    \penalty\defunpenalty  % signal to \startdefun and \dodefunx
     % Some of the @defun-type tags do not enable magic parentheses,
     % rendering the following check redundant.  But we don't optimize.
     \checkparencounts
@@ -6209,7 +6560,6 @@ where each line of input produces a line of output.}
 \message{cross references,}
 
 \newwrite\auxfile
-
 \newif\ifhavexrefs    % True if xref values are known.
 \newif\ifwarnedxrefs  % True if we warned once that they aren't known.
 
@@ -6276,7 +6626,7 @@ where each line of input produces a line of output.}
       \toks0 = \expandafter{\thissection}%
       \immediate \writexrdef{title}{\the\toks0 }%
       \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc.
-      \writexrdef{pg}{\folio}% will be written later, during \shipout
+      \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, during \shipout
     }%
   \fi
 }
@@ -6322,7 +6672,8 @@ where each line of input produces a line of output.}
   \ifpdf
     \leavevmode
     \getfilename{#4}%
-    {\turnoffactive
+    {\indexnofonts
+     \turnoffactive
      % See comments at \activebackslashdouble.
      {\activebackslashdouble \xdef\pdfxrefdest{#1}%
       \backslashparens\pdfxrefdest}%
@@ -6469,10 +6820,18 @@ where each line of input produces a line of output.}
 % collisions).  But if this is a float type, we have more work to do.
 %
 \def\xrdef#1#2{%
-  \expandafter\gdef\csname XR#1\endcsname{#2}% remember this xref value.
+  {% The node name might contain 8-bit characters, which in our current
+   % implementation are changed to commands like @'e.  Don't let these
+   % mess up the control sequence name.
+    \indexnofonts
+    \turnoffactive
+    \xdef\safexrefname{#1}%
+  }%
+  %
+  \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% remember this xref
   %
   % Was that xref control sequence that we just defined for a float?
-  \expandafter\iffloat\csname XR#1\endcsname
+  \expandafter\iffloat\csname XR\safexrefname\endcsname
     % it was a float, and we have the (safe) float type in \iffloattype.
     \expandafter\let\expandafter\floatlist
       \csname floatlist\iffloattype\endcsname
@@ -6487,7 +6846,8 @@ where each line of input produces a line of output.}
     %
     % Remember this xref in the control sequence \floatlistFLOATTYPE,
     % for later use in \listoffloats.
-    \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0{#1}}%
+    \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0
+      {\safexrefname}}%
   \fi
 }
 
@@ -6591,6 +6951,7 @@ where each line of input produces a line of output.}
   \input\jobname.#1
 \endgroup}
 
+
 \message{insertions,}
 % including footnotes.
 
@@ -7065,8 +7426,8 @@ where each line of input produces a line of output.}
   \writeentry
 }}
 
+
 \message{localization,}
-% and i18n.
 
 % @documentlanguage is usually given very early, just after
 % @setfilename.  If done too late, it may not override everything
@@ -7090,14 +7451,809 @@ where each line of input produces a line of output.}
 is empty.  Maybe you need to install it?  In the current directory
 should work if nowhere else does.}
 
+% Set the catcode of characters 128 through 255 to the specified number.
+%
+\def\setnonasciicharscatcode#1{%
+   \count255=128
+   \loop\ifnum\count255<256
+      \global\catcode\count255=#1
+      \advance\count255 by 1
+   \repeat
+}
+
+% @documentencoding sets the definition of non-ASCII characters
+% according to the specified encoding.
+%
+\parseargdef\documentencoding{%
+  % Encoding being declared for the document.
+  \def\declaredencoding{\csname #1.enc\endcsname}%
+  %
+  % Supported encodings: names converted to tokens in order to be able
+  % to compare them with \ifx.
+  \def\ascii{\csname US-ASCII.enc\endcsname}%
+  \def\latnine{\csname ISO-8859-15.enc\endcsname}%
+  \def\latone{\csname ISO-8859-1.enc\endcsname}%
+  \def\lattwo{\csname ISO-8859-2.enc\endcsname}%
+  \def\utfeight{\csname UTF-8.enc\endcsname}%
+  %
+  \ifx \declaredencoding \ascii
+     \asciichardefs
+  %
+  \else \ifx \declaredencoding \lattwo
+     \setnonasciicharscatcode\active
+     \lattwochardefs
+  %
+  \else \ifx \declaredencoding \latone
+     \setnonasciicharscatcode\active
+     \latonechardefs
+  %
+  \else \ifx \declaredencoding \latnine
+     \setnonasciicharscatcode\active
+     \latninechardefs
+  %
+  \else \ifx \declaredencoding \utfeight
+     \setnonasciicharscatcode\active
+     \utfeightchardefs
+  %
+  \else
+    \message{Unknown document encoding #1, ignoring.}%
+  %
+  \fi % utfeight
+  \fi % latnine
+  \fi % latone
+  \fi % lattwo
+  \fi % ascii
+}
+
+% A message to be logged when using a character that isn't available
+% the default font encoding (OT1).
+%
+\def\missingcharmsg#1{\message{Character missing in OT1 encoding: #1.}}
+
+% Take account of \c (plain) vs. \, (Texinfo) difference.
+\def\cedilla#1{\ifx\c\ptexc\c{#1}\else\,{#1}\fi}
+
+% First, make active non-ASCII characters in order for them to be
+% correctly categorized when TeX reads the replacement text of
+% macros containing the character definitions.
+\setnonasciicharscatcode\active
+%
+% Latin1 (ISO-8859-1) character definitions.
+\def\latonechardefs{%
+  \gdef^^a0{~}
+  \gdef^^a1{\exclamdown}
+  \gdef^^a2{\missingcharmsg{CENT SIGN}}
+  \gdef^^a3{{\pounds}}
+  \gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
+  \gdef^^a5{\missingcharmsg{YEN SIGN}}
+  \gdef^^a6{\missingcharmsg{BROKEN BAR}}
+  \gdef^^a7{\S}
+  \gdef^^a8{\"{}}
+  \gdef^^a9{\copyright}
+  \gdef^^aa{\ordf}
+  \gdef^^ab{\missingcharmsg{LEFT-POINTING DOUBLE ANGLE QUOTATION MARK}}
+  \gdef^^ac{$\lnot$}
+  \gdef^^ad{\-}
+  \gdef^^ae{\registeredsymbol}
+  \gdef^^af{\={}}
+  %
+  \gdef^^b0{\textdegree}
+  \gdef^^b1{$\pm$}
+  \gdef^^b2{$^2$}
+  \gdef^^b3{$^3$}
+  \gdef^^b4{\'{}}
+  \gdef^^b5{$\mu$}
+  \gdef^^b6{\P}
+  %
+  \gdef^^b7{$^.$}
+  \gdef^^b8{\cedilla\ }
+  \gdef^^b9{$^1$}
+  \gdef^^ba{\ordm}
+  %
+  \gdef^^bb{\missingcharmsg{RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK}}
+  \gdef^^bc{$1\over4$}
+  \gdef^^bd{$1\over2$}
+  \gdef^^be{$3\over4$}
+  \gdef^^bf{\questiondown}
+  %
+  \gdef^^c0{\`A}
+  \gdef^^c1{\'A}
+  \gdef^^c2{\^A}
+  \gdef^^c3{\~A}
+  \gdef^^c4{\"A}
+  \gdef^^c5{\ringaccent A}
+  \gdef^^c6{\AE}
+  \gdef^^c7{\cedilla C}
+  \gdef^^c8{\`E}
+  \gdef^^c9{\'E}
+  \gdef^^ca{\^E}
+  \gdef^^cb{\"E}
+  \gdef^^cc{\`I}
+  \gdef^^cd{\'I}
+  \gdef^^ce{\^I}
+  \gdef^^cf{\"I}
+  %
+  \gdef^^d0{\missingcharmsg{LATIN CAPITAL LETTER ETH}}
+  \gdef^^d1{\~N}
+  \gdef^^d2{\`O}
+  \gdef^^d3{\'O}
+  \gdef^^d4{\^O}
+  \gdef^^d5{\~O}
+  \gdef^^d6{\"O}
+  \gdef^^d7{$\times$}
+  \gdef^^d8{\O}
+  \gdef^^d9{\`U}
+  \gdef^^da{\'U}
+  \gdef^^db{\^U}
+  \gdef^^dc{\"U}
+  \gdef^^dd{\'Y}
+  \gdef^^de{\missingcharmsg{LATIN CAPITAL LETTER THORN}}
+  \gdef^^df{\ss}
+  %
+  \gdef^^e0{\`a}
+  \gdef^^e1{\'a}
+  \gdef^^e2{\^a}
+  \gdef^^e3{\~a}
+  \gdef^^e4{\"a}
+  \gdef^^e5{\ringaccent a}
+  \gdef^^e6{\ae}
+  \gdef^^e7{\cedilla c}
+  \gdef^^e8{\`e}
+  \gdef^^e9{\'e}
+  \gdef^^ea{\^e}
+  \gdef^^eb{\"e}
+  \gdef^^ec{\`{\dotless i}}
+  \gdef^^ed{\'{\dotless i}}
+  \gdef^^ee{\^{\dotless i}}
+  \gdef^^ef{\"{\dotless i}}
+  %
+  \gdef^^f0{\missingcharmsg{LATIN SMALL LETTER ETH}}
+  \gdef^^f1{\~n}
+  \gdef^^f2{\`o}
+  \gdef^^f3{\'o}
+  \gdef^^f4{\^o}
+  \gdef^^f5{\~o}
+  \gdef^^f6{\"o}
+  \gdef^^f7{$\div$}
+  \gdef^^f8{\o}
+  \gdef^^f9{\`u}
+  \gdef^^fa{\'u}
+  \gdef^^fb{\^u}
+  \gdef^^fc{\"u}
+  \gdef^^fd{\'y}
+  \gdef^^fe{\missingcharmsg{LATIN SMALL LETTER THORN}}
+  \gdef^^ff{\"y}
+}
+
+% Latin9 (ISO-8859-15) encoding character definitions.
+\def\latninechardefs{%
+  % Encoding is almost identical to Latin1.
+  \latonechardefs
+  %
+  \gdef^^a4{\euro}
+  \gdef^^a6{\v S}
+  \gdef^^a8{\v s}
+  \gdef^^b4{\v Z}
+  \gdef^^b8{\v z}
+  \gdef^^bc{\OE}
+  \gdef^^bd{\oe}
+  \gdef^^be{\"Y}
+}
+
+% Latin2 (ISO-8859-2) character definitions.
+\def\lattwochardefs{%
+  \gdef^^a0{~}
+  \gdef^^a1{\missingcharmsg{LATIN CAPITAL LETTER A WITH OGONEK}}
+  \gdef^^a2{\u{}}
+  \gdef^^a3{\L}
+  \gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
+  \gdef^^a5{\v L}
+  \gdef^^a6{\'S}
+  \gdef^^a7{\S}
+  \gdef^^a8{\"{}}
+  \gdef^^a9{\v S}
+  \gdef^^aa{\cedilla S}
+  \gdef^^ab{\v T}
+  \gdef^^ac{\'Z}
+  \gdef^^ad{\-}
+  \gdef^^ae{\v Z}
+  \gdef^^af{\dotaccent Z}
+  %
+  \gdef^^b0{\textdegree}
+  \gdef^^b1{\missingcharmsg{LATIN SMALL LETTER A WITH OGONEK}}
+  \gdef^^b2{\missingcharmsg{OGONEK}}
+  \gdef^^b3{\l}
+  \gdef^^b4{\'{}}
+  \gdef^^b5{\v l}
+  \gdef^^b6{\'s}
+  \gdef^^b7{\v{}}
+  \gdef^^b8{\cedilla\ }
+  \gdef^^b9{\v s}
+  \gdef^^ba{\cedilla s}
+  \gdef^^bb{\v t}
+  \gdef^^bc{\'z}
+  \gdef^^bd{\H{}}
+  \gdef^^be{\v z}
+  \gdef^^bf{\dotaccent z}
+  %
+  \gdef^^c0{\'R}
+  \gdef^^c1{\'A}
+  \gdef^^c2{\^A}
+  \gdef^^c3{\u A}
+  \gdef^^c4{\"A}
+  \gdef^^c5{\'L}
+  \gdef^^c6{\'C}
+  \gdef^^c7{\cedilla C}
+  \gdef^^c8{\v C}
+  \gdef^^c9{\'E}
+  \gdef^^ca{\missingcharmsg{LATIN CAPITAL LETTER E WITH OGONEK}}
+  \gdef^^cb{\"E}
+  \gdef^^cc{\v E}
+  \gdef^^cd{\'I}
+  \gdef^^ce{\^I}
+  \gdef^^cf{\v D}
+  %
+  \gdef^^d0{\missingcharmsg{LATIN CAPITAL LETTER D WITH STROKE}}
+  \gdef^^d1{\'N}
+  \gdef^^d2{\v N}
+  \gdef^^d3{\'O}
+  \gdef^^d4{\^O}
+  \gdef^^d5{\H O}
+  \gdef^^d6{\"O}
+  \gdef^^d7{$\times$}
+  \gdef^^d8{\v R}
+  \gdef^^d9{\ringaccent U}
+  \gdef^^da{\'U}
+  \gdef^^db{\H U}
+  \gdef^^dc{\"U}
+  \gdef^^dd{\'Y}
+  \gdef^^de{\cedilla T}
+  \gdef^^df{\ss}
+  %
+  \gdef^^e0{\'r}
+  \gdef^^e1{\'a}
+  \gdef^^e2{\^a}
+  \gdef^^e3{\u a}
+  \gdef^^e4{\"a}
+  \gdef^^e5{\'l}
+  \gdef^^e6{\'c}
+  \gdef^^e7{\cedilla c}
+  \gdef^^e8{\v c}
+  \gdef^^e9{\'e}
+  \gdef^^ea{\missingcharmsg{LATIN SMALL LETTER E WITH OGONEK}}
+  \gdef^^eb{\"e}
+  \gdef^^ec{\v e}
+  \gdef^^ed{\'\i}
+  \gdef^^ee{\^\i}
+  \gdef^^ef{\v d}
+  %
+  \gdef^^f0{\missingcharmsg{LATIN SMALL LETTER D WITH STROKE}}
+  \gdef^^f1{\'n}
+  \gdef^^f2{\v n}
+  \gdef^^f3{\'o}
+  \gdef^^f4{\^o}
+  \gdef^^f5{\H o}
+  \gdef^^f6{\"o}
+  \gdef^^f7{$\div$}
+  \gdef^^f8{\v r}
+  \gdef^^f9{\ringaccent u}
+  \gdef^^fa{\'u}
+  \gdef^^fb{\H u}
+  \gdef^^fc{\"u}
+  \gdef^^fd{\'y}
+  \gdef^^fe{\cedilla t}
+  \gdef^^ff{\dotaccent{}}
+}
+
+% UTF-8 character definitions.
+%
+% This code to support UTF-8 is based on LaTeX's utf8.def, with some
+% changes for Texinfo conventions.  It is included here under the GPL by
+% permission from Frank Mittelbach and the LaTeX team.
+%
+\newcount\countUTFx
+\newcount\countUTFy
+\newcount\countUTFz
+
+\gdef\UTFviiiTwoOctets#1#2{\expandafter
+   \UTFviiiDefined\csname u8:#1\string #2\endcsname}
+%
+\gdef\UTFviiiThreeOctets#1#2#3{\expandafter
+   \UTFviiiDefined\csname u8:#1\string #2\string #3\endcsname}
+%
+\gdef\UTFviiiFourOctets#1#2#3#4{\expandafter
+   \UTFviiiDefined\csname u8:#1\string #2\string #3\string #4\endcsname}
+
+\gdef\UTFviiiDefined#1{%
+  \ifx #1\relax
+    \message{\linenumber Unicode char \string #1 not defined for Texinfo}%
+  \else
+    \expandafter #1%
+  \fi
+}
+
+\begingroup
+  \catcode`\~13
+  \catcode`\"12
+
+  \def\UTFviiiLoop{%
+    \global\catcode\countUTFx\active
+    \uccode`\~\countUTFx
+    \uppercase\expandafter{\UTFviiiTmp}%
+    \advance\countUTFx by 1
+    \ifnum\countUTFx < \countUTFy
+      \expandafter\UTFviiiLoop
+    \fi}
 
-% @documentencoding should change something in TeX eventually, most
-% likely, but for now just recognize it.
-\let\documentencoding = \comment
+  \countUTFx = "C2
+  \countUTFy = "E0
+  \def\UTFviiiTmp{%
+    \xdef~{\noexpand\UTFviiiTwoOctets\string~}}
+  \UTFviiiLoop
+
+  \countUTFx = "E0
+  \countUTFy = "F0
+  \def\UTFviiiTmp{%
+    \xdef~{\noexpand\UTFviiiThreeOctets\string~}}
+  \UTFviiiLoop
+
+  \countUTFx = "F0
+  \countUTFy = "F4
+  \def\UTFviiiTmp{%
+    \xdef~{\noexpand\UTFviiiFourOctets\string~}}
+  \UTFviiiLoop
+\endgroup
 
+\begingroup
+  \catcode`\"=12
+  \catcode`\<=12
+  \catcode`\.=12
+  \catcode`\,=12
+  \catcode`\;=12
+  \catcode`\!=12
+  \catcode`\~=13
+
+  \gdef\DeclareUnicodeCharacter#1#2{%
+    \countUTFz = "#1\relax
+    \wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}%
+    \begingroup
+      \parseXMLCharref
+      \def\UTFviiiTwoOctets##1##2{%
+        \csname u8:##1\string ##2\endcsname}%
+      \def\UTFviiiThreeOctets##1##2##3{%
+        \csname u8:##1\string ##2\string ##3\endcsname}%
+      \def\UTFviiiFourOctets##1##2##3##4{%
+        \csname u8:##1\string ##2\string ##3\string ##4\endcsname}%
+      \expandafter\expandafter\expandafter\expandafter
+       \expandafter\expandafter\expandafter
+       \gdef\UTFviiiTmp{#2}%
+    \endgroup}
+
+  \gdef\parseXMLCharref{%
+    \ifnum\countUTFz < "A0\relax
+      \errhelp = \EMsimple
+      \errmessage{Cannot define Unicode char value < 00A0}%
+    \else\ifnum\countUTFz < "800\relax
+      \parseUTFviiiA,%
+      \parseUTFviiiB C\UTFviiiTwoOctets.,%
+    \else\ifnum\countUTFz < "10000\relax
+      \parseUTFviiiA;%
+      \parseUTFviiiA,%
+      \parseUTFviiiB E\UTFviiiThreeOctets.{,;}%
+    \else
+      \parseUTFviiiA;%
+      \parseUTFviiiA,%
+      \parseUTFviiiA!%
+      \parseUTFviiiB F\UTFviiiFourOctets.{!,;}%
+    \fi\fi\fi
+  }
+
+  \gdef\parseUTFviiiA#1{%
+    \countUTFx = \countUTFz
+    \divide\countUTFz by 64
+    \countUTFy = \countUTFz
+    \multiply\countUTFz by 64
+    \advance\countUTFx by -\countUTFz
+    \advance\countUTFx by 128
+    \uccode `#1\countUTFx
+    \countUTFz = \countUTFy}
+
+  \gdef\parseUTFviiiB#1#2#3#4{%
+    \advance\countUTFz by "#10\relax
+    \uccode `#3\countUTFz
+    \uppercase{\gdef\UTFviiiTmp{#2#3#4}}}
+\endgroup
+
+\def\utfeightchardefs{%
+  \DeclareUnicodeCharacter{00A0}{\tie}
+  \DeclareUnicodeCharacter{00A1}{\exclamdown}
+  \DeclareUnicodeCharacter{00A3}{\pounds}
+  \DeclareUnicodeCharacter{00A8}{\"{ }}
+  \DeclareUnicodeCharacter{00A9}{\copyright}
+  \DeclareUnicodeCharacter{00AA}{\ordf}
+  \DeclareUnicodeCharacter{00AD}{\-}
+  \DeclareUnicodeCharacter{00AE}{\registeredsymbol}
+  \DeclareUnicodeCharacter{00AF}{\={ }}
+
+  \DeclareUnicodeCharacter{00B0}{\ringaccent{ }}
+  \DeclareUnicodeCharacter{00B4}{\'{ }}
+  \DeclareUnicodeCharacter{00B8}{\cedilla{ }}
+  \DeclareUnicodeCharacter{00BA}{\ordm}
+  \DeclareUnicodeCharacter{00BF}{\questiondown}
+
+  \DeclareUnicodeCharacter{00C0}{\`A}
+  \DeclareUnicodeCharacter{00C1}{\'A}
+  \DeclareUnicodeCharacter{00C2}{\^A}
+  \DeclareUnicodeCharacter{00C3}{\~A}
+  \DeclareUnicodeCharacter{00C4}{\"A}
+  \DeclareUnicodeCharacter{00C5}{\AA}
+  \DeclareUnicodeCharacter{00C6}{\AE}
+  \DeclareUnicodeCharacter{00C7}{\cedilla{C}}
+  \DeclareUnicodeCharacter{00C8}{\`E}
+  \DeclareUnicodeCharacter{00C9}{\'E}
+  \DeclareUnicodeCharacter{00CA}{\^E}
+  \DeclareUnicodeCharacter{00CB}{\"E}
+  \DeclareUnicodeCharacter{00CC}{\`I}
+  \DeclareUnicodeCharacter{00CD}{\'I}
+  \DeclareUnicodeCharacter{00CE}{\^I}
+  \DeclareUnicodeCharacter{00CF}{\"I}
+
+  \DeclareUnicodeCharacter{00D1}{\~N}
+  \DeclareUnicodeCharacter{00D2}{\`O}
+  \DeclareUnicodeCharacter{00D3}{\'O}
+  \DeclareUnicodeCharacter{00D4}{\^O}
+  \DeclareUnicodeCharacter{00D5}{\~O}
+  \DeclareUnicodeCharacter{00D6}{\"O}
+  \DeclareUnicodeCharacter{00D8}{\O}
+  \DeclareUnicodeCharacter{00D9}{\`U}
+  \DeclareUnicodeCharacter{00DA}{\'U}
+  \DeclareUnicodeCharacter{00DB}{\^U}
+  \DeclareUnicodeCharacter{00DC}{\"U}
+  \DeclareUnicodeCharacter{00DD}{\'Y}
+  \DeclareUnicodeCharacter{00DF}{\ss}
+
+  \DeclareUnicodeCharacter{00E0}{\`a}
+  \DeclareUnicodeCharacter{00E1}{\'a}
+  \DeclareUnicodeCharacter{00E2}{\^a}
+  \DeclareUnicodeCharacter{00E3}{\~a}
+  \DeclareUnicodeCharacter{00E4}{\"a}
+  \DeclareUnicodeCharacter{00E5}{\aa}
+  \DeclareUnicodeCharacter{00E6}{\ae}
+  \DeclareUnicodeCharacter{00E7}{\cedilla{c}}
+  \DeclareUnicodeCharacter{00E8}{\`e}
+  \DeclareUnicodeCharacter{00E9}{\'e}
+  \DeclareUnicodeCharacter{00EA}{\^e}
+  \DeclareUnicodeCharacter{00EB}{\"e}
+  \DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}}
+  \DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}}
+  \DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}}
+  \DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}}
+
+  \DeclareUnicodeCharacter{00F1}{\~n}
+  \DeclareUnicodeCharacter{00F2}{\`o}
+  \DeclareUnicodeCharacter{00F3}{\'o}
+  \DeclareUnicodeCharacter{00F4}{\^o}
+  \DeclareUnicodeCharacter{00F5}{\~o}
+  \DeclareUnicodeCharacter{00F6}{\"o}
+  \DeclareUnicodeCharacter{00F8}{\o}
+  \DeclareUnicodeCharacter{00F9}{\`u}
+  \DeclareUnicodeCharacter{00FA}{\'u}
+  \DeclareUnicodeCharacter{00FB}{\^u}
+  \DeclareUnicodeCharacter{00FC}{\"u}
+  \DeclareUnicodeCharacter{00FD}{\'y}
+  \DeclareUnicodeCharacter{00FF}{\"y}
+
+  \DeclareUnicodeCharacter{0100}{\=A}
+  \DeclareUnicodeCharacter{0101}{\=a}
+  \DeclareUnicodeCharacter{0102}{\u{A}}
+  \DeclareUnicodeCharacter{0103}{\u{a}}
+  \DeclareUnicodeCharacter{0106}{\'C}
+  \DeclareUnicodeCharacter{0107}{\'c}
+  \DeclareUnicodeCharacter{0108}{\^C}
+  \DeclareUnicodeCharacter{0109}{\^c}
+  \DeclareUnicodeCharacter{010A}{\dotaccent{C}}
+  \DeclareUnicodeCharacter{010B}{\dotaccent{c}}
+  \DeclareUnicodeCharacter{010C}{\v{C}}
+  \DeclareUnicodeCharacter{010D}{\v{c}}
+  \DeclareUnicodeCharacter{010E}{\v{D}}
+
+  \DeclareUnicodeCharacter{0112}{\=E}
+  \DeclareUnicodeCharacter{0113}{\=e}
+  \DeclareUnicodeCharacter{0114}{\u{E}}
+  \DeclareUnicodeCharacter{0115}{\u{e}}
+  \DeclareUnicodeCharacter{0116}{\dotaccent{E}}
+  \DeclareUnicodeCharacter{0117}{\dotaccent{e}}
+  \DeclareUnicodeCharacter{011A}{\v{E}}
+  \DeclareUnicodeCharacter{011B}{\v{e}}
+  \DeclareUnicodeCharacter{011C}{\^G}
+  \DeclareUnicodeCharacter{011D}{\^g}
+  \DeclareUnicodeCharacter{011E}{\u{G}}
+  \DeclareUnicodeCharacter{011F}{\u{g}}
+
+  \DeclareUnicodeCharacter{0120}{\dotaccent{G}}
+  \DeclareUnicodeCharacter{0121}{\dotaccent{g}}
+  \DeclareUnicodeCharacter{0124}{\^H}
+  \DeclareUnicodeCharacter{0125}{\^h}
+  \DeclareUnicodeCharacter{0128}{\~I}
+  \DeclareUnicodeCharacter{0129}{\~{\dotless{i}}}
+  \DeclareUnicodeCharacter{012A}{\=I}
+  \DeclareUnicodeCharacter{012B}{\={\dotless{i}}}
+  \DeclareUnicodeCharacter{012C}{\u{I}}
+  \DeclareUnicodeCharacter{012D}{\u{\dotless{i}}}
+
+  \DeclareUnicodeCharacter{0130}{\dotaccent{I}}
+  \DeclareUnicodeCharacter{0131}{\dotless{i}}
+  \DeclareUnicodeCharacter{0132}{IJ}
+  \DeclareUnicodeCharacter{0133}{ij}
+  \DeclareUnicodeCharacter{0134}{\^J}
+  \DeclareUnicodeCharacter{0135}{\^{\dotless{j}}}
+  \DeclareUnicodeCharacter{0139}{\'L}
+  \DeclareUnicodeCharacter{013A}{\'l}
+
+  \DeclareUnicodeCharacter{0141}{\L}
+  \DeclareUnicodeCharacter{0142}{\l}
+  \DeclareUnicodeCharacter{0143}{\'N}
+  \DeclareUnicodeCharacter{0144}{\'n}
+  \DeclareUnicodeCharacter{0147}{\v{N}}
+  \DeclareUnicodeCharacter{0148}{\v{n}}
+  \DeclareUnicodeCharacter{014C}{\=O}
+  \DeclareUnicodeCharacter{014D}{\=o}
+  \DeclareUnicodeCharacter{014E}{\u{O}}
+  \DeclareUnicodeCharacter{014F}{\u{o}}
+
+  \DeclareUnicodeCharacter{0150}{\H{O}}
+  \DeclareUnicodeCharacter{0151}{\H{o}}
+  \DeclareUnicodeCharacter{0152}{\OE}
+  \DeclareUnicodeCharacter{0153}{\oe}
+  \DeclareUnicodeCharacter{0154}{\'R}
+  \DeclareUnicodeCharacter{0155}{\'r}
+  \DeclareUnicodeCharacter{0158}{\v{R}}
+  \DeclareUnicodeCharacter{0159}{\v{r}}
+  \DeclareUnicodeCharacter{015A}{\'S}
+  \DeclareUnicodeCharacter{015B}{\'s}
+  \DeclareUnicodeCharacter{015C}{\^S}
+  \DeclareUnicodeCharacter{015D}{\^s}
+  \DeclareUnicodeCharacter{015E}{\cedilla{S}}
+  \DeclareUnicodeCharacter{015F}{\cedilla{s}}
+
+  \DeclareUnicodeCharacter{0160}{\v{S}}
+  \DeclareUnicodeCharacter{0161}{\v{s}}
+  \DeclareUnicodeCharacter{0162}{\cedilla{t}}
+  \DeclareUnicodeCharacter{0163}{\cedilla{T}}
+  \DeclareUnicodeCharacter{0164}{\v{T}}
+
+  \DeclareUnicodeCharacter{0168}{\~U}
+  \DeclareUnicodeCharacter{0169}{\~u}
+  \DeclareUnicodeCharacter{016A}{\=U}
+  \DeclareUnicodeCharacter{016B}{\=u}
+  \DeclareUnicodeCharacter{016C}{\u{U}}
+  \DeclareUnicodeCharacter{016D}{\u{u}}
+  \DeclareUnicodeCharacter{016E}{\ringaccent{U}}
+  \DeclareUnicodeCharacter{016F}{\ringaccent{u}}
+
+  \DeclareUnicodeCharacter{0170}{\H{U}}
+  \DeclareUnicodeCharacter{0171}{\H{u}}
+  \DeclareUnicodeCharacter{0174}{\^W}
+  \DeclareUnicodeCharacter{0175}{\^w}
+  \DeclareUnicodeCharacter{0176}{\^Y}
+  \DeclareUnicodeCharacter{0177}{\^y}
+  \DeclareUnicodeCharacter{0178}{\"Y}
+  \DeclareUnicodeCharacter{0179}{\'Z}
+  \DeclareUnicodeCharacter{017A}{\'z}
+  \DeclareUnicodeCharacter{017B}{\dotaccent{Z}}
+  \DeclareUnicodeCharacter{017C}{\dotaccent{z}}
+  \DeclareUnicodeCharacter{017D}{\v{Z}}
+  \DeclareUnicodeCharacter{017E}{\v{z}}
+
+  \DeclareUnicodeCharacter{01C4}{D\v{Z}}
+  \DeclareUnicodeCharacter{01C5}{D\v{z}}
+  \DeclareUnicodeCharacter{01C6}{d\v{z}}
+  \DeclareUnicodeCharacter{01C7}{LJ}
+  \DeclareUnicodeCharacter{01C8}{Lj}
+  \DeclareUnicodeCharacter{01C9}{lj}
+  \DeclareUnicodeCharacter{01CA}{NJ}
+  \DeclareUnicodeCharacter{01CB}{Nj}
+  \DeclareUnicodeCharacter{01CC}{nj}
+  \DeclareUnicodeCharacter{01CD}{\v{A}}
+  \DeclareUnicodeCharacter{01CE}{\v{a}}
+  \DeclareUnicodeCharacter{01CF}{\v{I}}
+
+  \DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}}
+  \DeclareUnicodeCharacter{01D1}{\v{O}}
+  \DeclareUnicodeCharacter{01D2}{\v{o}}
+  \DeclareUnicodeCharacter{01D3}{\v{U}}
+  \DeclareUnicodeCharacter{01D4}{\v{u}}
+
+  \DeclareUnicodeCharacter{01E2}{\={\AE}}
+  \DeclareUnicodeCharacter{01E3}{\={\ae}}
+  \DeclareUnicodeCharacter{01E6}{\v{G}}
+  \DeclareUnicodeCharacter{01E7}{\v{g}}
+  \DeclareUnicodeCharacter{01E8}{\v{K}}
+  \DeclareUnicodeCharacter{01E9}{\v{k}}
+
+  \DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}}
+  \DeclareUnicodeCharacter{01F1}{DZ}
+  \DeclareUnicodeCharacter{01F2}{Dz}
+  \DeclareUnicodeCharacter{01F3}{dz}
+  \DeclareUnicodeCharacter{01F4}{\'G}
+  \DeclareUnicodeCharacter{01F5}{\'g}
+  \DeclareUnicodeCharacter{01F8}{\`N}
+  \DeclareUnicodeCharacter{01F9}{\`n}
+  \DeclareUnicodeCharacter{01FC}{\'{\AE}}
+  \DeclareUnicodeCharacter{01FD}{\'{\ae}}
+  \DeclareUnicodeCharacter{01FE}{\'{\O}}
+  \DeclareUnicodeCharacter{01FF}{\'{\o}}
+
+  \DeclareUnicodeCharacter{021E}{\v{H}}
+  \DeclareUnicodeCharacter{021F}{\v{h}}
+
+  \DeclareUnicodeCharacter{0226}{\dotaccent{A}}
+  \DeclareUnicodeCharacter{0227}{\dotaccent{a}}
+  \DeclareUnicodeCharacter{0228}{\cedilla{E}}
+  \DeclareUnicodeCharacter{0229}{\cedilla{e}}
+  \DeclareUnicodeCharacter{022E}{\dotaccent{O}}
+  \DeclareUnicodeCharacter{022F}{\dotaccent{o}}
+
+  \DeclareUnicodeCharacter{0232}{\=Y}
+  \DeclareUnicodeCharacter{0233}{\=y}
+  \DeclareUnicodeCharacter{0237}{\dotless{j}}
+
+  \DeclareUnicodeCharacter{1E02}{\dotaccent{B}}
+  \DeclareUnicodeCharacter{1E03}{\dotaccent{b}}
+  \DeclareUnicodeCharacter{1E04}{\udotaccent{B}}
+  \DeclareUnicodeCharacter{1E05}{\udotaccent{b}}
+  \DeclareUnicodeCharacter{1E06}{\ubaraccent{B}}
+  \DeclareUnicodeCharacter{1E07}{\ubaraccent{b}}
+  \DeclareUnicodeCharacter{1E0A}{\dotaccent{D}}
+  \DeclareUnicodeCharacter{1E0B}{\dotaccent{d}}
+  \DeclareUnicodeCharacter{1E0C}{\udotaccent{D}}
+  \DeclareUnicodeCharacter{1E0D}{\udotaccent{d}}
+  \DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}}
+  \DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}}
+
+  \DeclareUnicodeCharacter{1E1E}{\dotaccent{F}}
+  \DeclareUnicodeCharacter{1E1F}{\dotaccent{f}}
+
+  \DeclareUnicodeCharacter{1E20}{\=G}
+  \DeclareUnicodeCharacter{1E21}{\=g}
+  \DeclareUnicodeCharacter{1E22}{\dotaccent{H}}
+  \DeclareUnicodeCharacter{1E23}{\dotaccent{h}}
+  \DeclareUnicodeCharacter{1E24}{\udotaccent{H}}
+  \DeclareUnicodeCharacter{1E25}{\udotaccent{h}}
+  \DeclareUnicodeCharacter{1E26}{\"H}
+  \DeclareUnicodeCharacter{1E27}{\"h}
+
+  \DeclareUnicodeCharacter{1E30}{\'K}
+  \DeclareUnicodeCharacter{1E31}{\'k}
+  \DeclareUnicodeCharacter{1E32}{\udotaccent{K}}
+  \DeclareUnicodeCharacter{1E33}{\udotaccent{k}}
+  \DeclareUnicodeCharacter{1E34}{\ubaraccent{K}}
+  \DeclareUnicodeCharacter{1E35}{\ubaraccent{k}}
+  \DeclareUnicodeCharacter{1E36}{\udotaccent{L}}
+  \DeclareUnicodeCharacter{1E37}{\udotaccent{l}}
+  \DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}}
+  \DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}}
+  \DeclareUnicodeCharacter{1E3E}{\'M}
+  \DeclareUnicodeCharacter{1E3F}{\'m}
+
+  \DeclareUnicodeCharacter{1E40}{\dotaccent{M}}
+  \DeclareUnicodeCharacter{1E41}{\dotaccent{m}}
+  \DeclareUnicodeCharacter{1E42}{\udotaccent{M}}
+  \DeclareUnicodeCharacter{1E43}{\udotaccent{m}}
+  \DeclareUnicodeCharacter{1E44}{\dotaccent{N}}
+  \DeclareUnicodeCharacter{1E45}{\dotaccent{n}}
+  \DeclareUnicodeCharacter{1E46}{\udotaccent{N}}
+  \DeclareUnicodeCharacter{1E47}{\udotaccent{n}}
+  \DeclareUnicodeCharacter{1E48}{\ubaraccent{N}}
+  \DeclareUnicodeCharacter{1E49}{\ubaraccent{n}}
+
+  \DeclareUnicodeCharacter{1E54}{\'P}
+  \DeclareUnicodeCharacter{1E55}{\'p}
+  \DeclareUnicodeCharacter{1E56}{\dotaccent{P}}
+  \DeclareUnicodeCharacter{1E57}{\dotaccent{p}}
+  \DeclareUnicodeCharacter{1E58}{\dotaccent{R}}
+  \DeclareUnicodeCharacter{1E59}{\dotaccent{r}}
+  \DeclareUnicodeCharacter{1E5A}{\udotaccent{R}}
+  \DeclareUnicodeCharacter{1E5B}{\udotaccent{r}}
+  \DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}}
+  \DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}}
+
+  \DeclareUnicodeCharacter{1E60}{\dotaccent{S}}
+  \DeclareUnicodeCharacter{1E61}{\dotaccent{s}}
+  \DeclareUnicodeCharacter{1E62}{\udotaccent{S}}
+  \DeclareUnicodeCharacter{1E63}{\udotaccent{s}}
+  \DeclareUnicodeCharacter{1E6A}{\dotaccent{T}}
+  \DeclareUnicodeCharacter{1E6B}{\dotaccent{t}}
+  \DeclareUnicodeCharacter{1E6C}{\udotaccent{T}}
+  \DeclareUnicodeCharacter{1E6D}{\udotaccent{t}}
+  \DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}}
+  \DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}}
+
+  \DeclareUnicodeCharacter{1E7C}{\~V}
+  \DeclareUnicodeCharacter{1E7D}{\~v}
+  \DeclareUnicodeCharacter{1E7E}{\udotaccent{V}}
+  \DeclareUnicodeCharacter{1E7F}{\udotaccent{v}}
+
+  \DeclareUnicodeCharacter{1E80}{\`W}
+  \DeclareUnicodeCharacter{1E81}{\`w}
+  \DeclareUnicodeCharacter{1E82}{\'W}
+  \DeclareUnicodeCharacter{1E83}{\'w}
+  \DeclareUnicodeCharacter{1E84}{\"W}
+  \DeclareUnicodeCharacter{1E85}{\"w}
+  \DeclareUnicodeCharacter{1E86}{\dotaccent{W}}
+  \DeclareUnicodeCharacter{1E87}{\dotaccent{w}}
+  \DeclareUnicodeCharacter{1E88}{\udotaccent{W}}
+  \DeclareUnicodeCharacter{1E89}{\udotaccent{w}}
+  \DeclareUnicodeCharacter{1E8A}{\dotaccent{X}}
+  \DeclareUnicodeCharacter{1E8B}{\dotaccent{x}}
+  \DeclareUnicodeCharacter{1E8C}{\"X}
+  \DeclareUnicodeCharacter{1E8D}{\"x}
+  \DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}}
+  \DeclareUnicodeCharacter{1E8F}{\dotaccent{y}}
+
+  \DeclareUnicodeCharacter{1E90}{\^Z}
+  \DeclareUnicodeCharacter{1E91}{\^z}
+  \DeclareUnicodeCharacter{1E92}{\udotaccent{Z}}
+  \DeclareUnicodeCharacter{1E93}{\udotaccent{z}}
+  \DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}}
+  \DeclareUnicodeCharacter{1E95}{\ubaraccent{z}}
+  \DeclareUnicodeCharacter{1E96}{\ubaraccent{h}}
+  \DeclareUnicodeCharacter{1E97}{\"t}
+  \DeclareUnicodeCharacter{1E98}{\ringaccent{w}}
+  \DeclareUnicodeCharacter{1E99}{\ringaccent{y}}
+
+  \DeclareUnicodeCharacter{1EA0}{\udotaccent{A}}
+  \DeclareUnicodeCharacter{1EA1}{\udotaccent{a}}
+
+  \DeclareUnicodeCharacter{1EB8}{\udotaccent{E}}
+  \DeclareUnicodeCharacter{1EB9}{\udotaccent{e}}
+  \DeclareUnicodeCharacter{1EBC}{\~E}
+  \DeclareUnicodeCharacter{1EBD}{\~e}
+
+  \DeclareUnicodeCharacter{1ECA}{\udotaccent{I}}
+  \DeclareUnicodeCharacter{1ECB}{\udotaccent{i}}
+  \DeclareUnicodeCharacter{1ECC}{\udotaccent{O}}
+  \DeclareUnicodeCharacter{1ECD}{\udotaccent{o}}
+
+  \DeclareUnicodeCharacter{1EE4}{\udotaccent{U}}
+  \DeclareUnicodeCharacter{1EE5}{\udotaccent{u}}
+
+  \DeclareUnicodeCharacter{1EF2}{\`Y}
+  \DeclareUnicodeCharacter{1EF3}{\`y}
+  \DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}}
+
+  \DeclareUnicodeCharacter{1EF8}{\~Y}
+  \DeclareUnicodeCharacter{1EF9}{\~y}
+
+  \DeclareUnicodeCharacter{2013}{--}
+  \DeclareUnicodeCharacter{2014}{---}
+  \DeclareUnicodeCharacter{2022}{\bullet}
+  \DeclareUnicodeCharacter{2026}{\dots}
+  \DeclareUnicodeCharacter{20AC}{\euro}
+
+  \DeclareUnicodeCharacter{2192}{\expansion}
+  \DeclareUnicodeCharacter{21D2}{\result}
+
+  \DeclareUnicodeCharacter{2212}{\minus}
+  \DeclareUnicodeCharacter{2217}{\point}
+  \DeclareUnicodeCharacter{2261}{\equiv}
+}% end of \utfeightchardefs
+
+
+% US-ASCII character definitions.
+\def\asciichardefs{% nothing need be done
+   \relax
+}
+
+% Make non-ASCII characters printable again for compatibility with
+% existing Texinfo documents that may use them, even without declaring a
+% document encoding.
+%
+\setnonasciicharscatcode \other
+
+
+\message{formatting,}
 
-% Page size parameters.
-%
 \newdimen\defaultparindent \defaultparindent = 15pt
 
 \chapheadingskip = 15pt plus 4pt minus 2pt
index 0a62d3c..f60338a 100644 (file)
@@ -19,8 +19,6 @@
 
 # Process this file with automake to produce Makefile.in
 
-EXTRA_DIST = Manifest
-
 # Need to include ../src in addition to top_srcdir because gcrypt.h is
 # a built header.
 AM_CPPFLAGS = -I../src -I$(top_srcdir)/src
@@ -28,6 +26,10 @@ AM_CFLAGS = $(GPG_ERROR_CFLAGS)
 
 AM_CCASFLAGS = $(NOEXECSTACK_FLAGS)
 
+EXTRA_DIST = gost-s-box.c
+
+CLEANFILES = gost-s-box
+DISTCLEANFILES = gost-sb.h
 
 noinst_LTLIBRARIES = libcipher.la
 
@@ -40,12 +42,14 @@ libcipher_la_LIBADD = $(GCRYPT_MODULES)
 libcipher_la_SOURCES = \
 cipher.c cipher-internal.h \
 cipher-cbc.c cipher-cfb.c cipher-ofb.c cipher-ctr.c cipher-aeswrap.c \
-cipher-ccm.c cipher-cmac.c cipher-gcm.c \
+cipher-ccm.c cipher-cmac.c cipher-gcm.c cipher-gcm-intel-pclmul.c \
+cipher-poly1305.c cipher-ocb.c \
 cipher-selftest.c cipher-selftest.h \
 pubkey.c pubkey-internal.h pubkey-util.c \
 md.c \
 mac.c mac-internal.h \
-mac-hmac.c mac-cmac.c mac-gmac.c \
+mac-hmac.c mac-cmac.c mac-gmac.c mac-poly1305.c \
+poly1305.c poly1305-internal.h \
 kdf.c kdf-internal.h \
 hmac-tests.c \
 bithelp.h  \
@@ -53,14 +57,17 @@ bufhelp.h  \
 primegen.c  \
 hash-common.c hash-common.h \
 dsa-common.c rsa-common.c \
-rmd.h
+sha1.h
 
 EXTRA_libcipher_la_SOURCES = \
-arcfour.c \
+arcfour.c arcfour-amd64.S \
 blowfish.c blowfish-amd64.S blowfish-arm.S \
 cast5.c cast5-amd64.S cast5-arm.S \
+chacha20.c chacha20-sse2-amd64.S chacha20-ssse3-amd64.S chacha20-avx2-amd64.S \
+  chacha20-armv7-neon.S \
 crc.c \
-des.c \
+  crc-intel-pclmul.c \
+des.c des-amd64.S \
 dsa.c \
 elgamal.c \
 ecc.c ecc-curves.c ecc-misc.c ecc-common.h \
@@ -70,25 +77,37 @@ gost28147.c gost.h \
 gostr3411-94.c \
 md4.c \
 md5.c \
-rijndael.c rijndael-tables.h rijndael-amd64.S rijndael-arm.S \
+poly1305-sse2-amd64.S poly1305-avx2-amd64.S poly1305-armv7-neon.S \
+rijndael.c rijndael-internal.h rijndael-tables.h rijndael-aesni.c \
+  rijndael-padlock.c rijndael-amd64.S rijndael-arm.S rijndael-ssse3-amd64.c \
 rmd160.c \
 rsa.c \
 salsa20.c salsa20-amd64.S salsa20-armv7-neon.S \
 scrypt.c \
 seed.c \
 serpent.c serpent-sse2-amd64.S serpent-avx2-amd64.S serpent-armv7-neon.S \
-sha1.c sha1-ssse3-amd64.S \
-sha256.c sha256-ssse3-amd64.S \
+sha1.c sha1-ssse3-amd64.S sha1-avx-amd64.S sha1-avx-bmi2-amd64.S \
+  sha1-armv7-neon.S \
+sha256.c sha256-ssse3-amd64.S sha256-avx-amd64.S sha256-avx2-bmi2-amd64.S \
 sha512.c sha512-ssse3-amd64.S sha512-avx-amd64.S sha512-avx2-bmi2-amd64.S \
-  sha512-armv7-neon.S \
+  sha512-armv7-neon.S sha512-arm.S \
+keccak.c keccak_permute_32.h keccak_permute_64.h keccak-armv7-neon.S \
 stribog.c \
 tiger.c \
-whirlpool.c \
+whirlpool.c whirlpool-sse2-amd64.S \
 twofish.c twofish-amd64.S twofish-arm.S \
 rfc2268.c \
 camellia.c camellia.h camellia-glue.c camellia-aesni-avx-amd64.S \
   camellia-aesni-avx2-amd64.S camellia-arm.S
 
+gost28147.lo: gost-sb.h
+gost-sb.h: gost-s-box
+       ./gost-s-box $@
+
+gost-s-box: gost-s-box.c
+       $(CC_FOR_BUILD) -o $@ $(srcdir)/gost-s-box.c
+
+
 if ENABLE_O_FLAG_MUNGING
 o_flag_munging = sed -e 's/-O\([2-9s][2-9s]*\)/-O1/' -e 's/-Ofast/-O1/g'
 else
index e9f20b0..9b4f540 100644 (file)
@@ -1,9 +1,8 @@
-# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
-# Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 # Process this file with automake to produce Makefile.in
 
 VPATH = @srcdir@
-am__make_dryrun = \
-  { \
-    am__dry=no; \
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
     case $$MAKEFLAGS in \
       *\\[\ \  ]*) \
-        echo 'am--echo: ; @echo "AM"  OK' | $(MAKE) -f - 2>/dev/null \
-          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
-      *) \
-        for am__flg in $$MAKEFLAGS; do \
-          case $$am__flg in \
-            *=*|--*) ;; \
-            *n*) am__dry=yes; break;; \
-          esac; \
-        done;; \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs  ]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
     esac; \
-    test $$am__dry = yes; \
-  }
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -73,16 +100,16 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = cipher
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+       $(top_srcdir)/build-aux/depcomp
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/gpg-error.m4 \
-       $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/lock.m4 \
-       $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
-       $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+       $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+       $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+       $(top_srcdir)/m4/lt~obsolete.m4 \
        $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \
        $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
-       $(top_srcdir)/m4/threadlib.m4 $(top_srcdir)/acinclude.m4 \
-       $(top_srcdir)/configure.ac
+       $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -93,14 +120,28 @@ LTLIBRARIES = $(noinst_LTLIBRARIES)
 am__DEPENDENCIES_1 =
 am_libcipher_la_OBJECTS = cipher.lo cipher-cbc.lo cipher-cfb.lo \
        cipher-ofb.lo cipher-ctr.lo cipher-aeswrap.lo cipher-ccm.lo \
-       cipher-cmac.lo cipher-gcm.lo cipher-selftest.lo pubkey.lo \
+       cipher-cmac.lo cipher-gcm.lo cipher-gcm-intel-pclmul.lo \
+       cipher-poly1305.lo cipher-ocb.lo cipher-selftest.lo pubkey.lo \
        pubkey-util.lo md.lo mac.lo mac-hmac.lo mac-cmac.lo \
-       mac-gmac.lo kdf.lo hmac-tests.lo primegen.lo hash-common.lo \
-       dsa-common.lo rsa-common.lo
+       mac-gmac.lo mac-poly1305.lo poly1305.lo kdf.lo hmac-tests.lo \
+       primegen.lo hash-common.lo dsa-common.lo rsa-common.lo
 libcipher_la_OBJECTS = $(am_libcipher_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
 am__v_lt_0 = --silent
+am__v_lt_1 = 
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
 depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
 am__depfiles_maybe = depfiles
@@ -113,10 +154,8 @@ LTCPPASCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \
        $(AM_CCASFLAGS) $(CCASFLAGS)
 AM_V_CPPAS = $(am__v_CPPAS_@AM_V@)
 am__v_CPPAS_ = $(am__v_CPPAS_@AM_DEFAULT_V@)
-am__v_CPPAS_0 = @echo "  CPPAS " $@;
-AM_V_at = $(am__v_at_@AM_V@)
-am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
-am__v_at_0 = @
+am__v_CPPAS_0 = @echo "  CPPAS   " $@;
+am__v_CPPAS_1 = 
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
        $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
@@ -125,17 +164,16 @@ LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(AM_CFLAGS) $(CFLAGS)
 AM_V_CC = $(am__v_CC_@AM_V@)
 am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
-am__v_CC_0 = @echo "  CC    " $@;
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
 CCLD = $(CC)
 LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
        $(AM_LDFLAGS) $(LDFLAGS) -o $@
 AM_V_CCLD = $(am__v_CCLD_@AM_V@)
 am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
-am__v_CCLD_0 = @echo "  CCLD  " $@;
-AM_V_GEN = $(am__v_GEN_@AM_V@)
-am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
-am__v_GEN_0 = @echo "  GEN   " $@;
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
 SOURCES = $(libcipher_la_SOURCES) $(EXTRA_libcipher_la_SOURCES)
 DIST_SOURCES = $(libcipher_la_SOURCES) $(EXTRA_libcipher_la_SOURCES)
 am__can_run_installinfo = \
@@ -143,6 +181,23 @@ am__can_run_installinfo = \
     n|no|NO) false;; \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -190,6 +245,8 @@ GCRYPT_RANDOM = @GCRYPT_RANDOM@
 GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
 GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
 GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GPG_ERROR_MT_CFLAGS = @GPG_ERROR_MT_CFLAGS@
+GPG_ERROR_MT_LIBS = @GPG_ERROR_MT_LIBS@
 GREP = @GREP@
 INSERT_SYS_SELECT_H = @INSERT_SYS_SELECT_H@
 INSTALL = @INSTALL@
@@ -210,16 +267,12 @@ LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@
 LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@
 LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@
 LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@
-LIBMULTITHREAD = @LIBMULTITHREAD@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
-LIBTHREAD = @LIBTHREAD@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
-LTLIBMULTITHREAD = @LTLIBMULTITHREAD@
 LTLIBOBJS = @LTLIBOBJS@
-LTLIBTHREAD = @LTLIBTHREAD@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
@@ -250,6 +303,7 @@ SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
+SYSROOT = @SYSROOT@
 SYS_SOCKET_H = @SYS_SOCKET_H@
 VERSION = @VERSION@
 VERSION_NUMBER = @VERSION_NUMBER@
@@ -308,13 +362,15 @@ target_alias = @target_alias@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-EXTRA_DIST = Manifest
 
 # Need to include ../src in addition to top_srcdir because gcrypt.h is
 # a built header.
 AM_CPPFLAGS = -I../src -I$(top_srcdir)/src
 AM_CFLAGS = $(GPG_ERROR_CFLAGS)
 AM_CCASFLAGS = $(NOEXECSTACK_FLAGS)
+EXTRA_DIST = gost-s-box.c
+CLEANFILES = gost-s-box
+DISTCLEANFILES = gost-sb.h
 noinst_LTLIBRARIES = libcipher.la
 GCRYPT_MODULES = @GCRYPT_CIPHERS@ @GCRYPT_PUBKEY_CIPHERS@ \
                  @GCRYPT_DIGESTS@ @GCRYPT_KDFS@
@@ -324,12 +380,14 @@ libcipher_la_LIBADD = $(GCRYPT_MODULES)
 libcipher_la_SOURCES = \
 cipher.c cipher-internal.h \
 cipher-cbc.c cipher-cfb.c cipher-ofb.c cipher-ctr.c cipher-aeswrap.c \
-cipher-ccm.c cipher-cmac.c cipher-gcm.c \
+cipher-ccm.c cipher-cmac.c cipher-gcm.c cipher-gcm-intel-pclmul.c \
+cipher-poly1305.c cipher-ocb.c \
 cipher-selftest.c cipher-selftest.h \
 pubkey.c pubkey-internal.h pubkey-util.c \
 md.c \
 mac.c mac-internal.h \
-mac-hmac.c mac-cmac.c mac-gmac.c \
+mac-hmac.c mac-cmac.c mac-gmac.c mac-poly1305.c \
+poly1305.c poly1305-internal.h \
 kdf.c kdf-internal.h \
 hmac-tests.c \
 bithelp.h  \
@@ -337,14 +395,17 @@ bufhelp.h  \
 primegen.c  \
 hash-common.c hash-common.h \
 dsa-common.c rsa-common.c \
-rmd.h
+sha1.h
 
 EXTRA_libcipher_la_SOURCES = \
-arcfour.c \
+arcfour.c arcfour-amd64.S \
 blowfish.c blowfish-amd64.S blowfish-arm.S \
 cast5.c cast5-amd64.S cast5-arm.S \
+chacha20.c chacha20-sse2-amd64.S chacha20-ssse3-amd64.S chacha20-avx2-amd64.S \
+  chacha20-armv7-neon.S \
 crc.c \
-des.c \
+  crc-intel-pclmul.c \
+des.c des-amd64.S \
 dsa.c \
 elgamal.c \
 ecc.c ecc-curves.c ecc-misc.c ecc-common.h \
@@ -354,20 +415,24 @@ gost28147.c gost.h \
 gostr3411-94.c \
 md4.c \
 md5.c \
-rijndael.c rijndael-tables.h rijndael-amd64.S rijndael-arm.S \
+poly1305-sse2-amd64.S poly1305-avx2-amd64.S poly1305-armv7-neon.S \
+rijndael.c rijndael-internal.h rijndael-tables.h rijndael-aesni.c \
+  rijndael-padlock.c rijndael-amd64.S rijndael-arm.S rijndael-ssse3-amd64.c \
 rmd160.c \
 rsa.c \
 salsa20.c salsa20-amd64.S salsa20-armv7-neon.S \
 scrypt.c \
 seed.c \
 serpent.c serpent-sse2-amd64.S serpent-avx2-amd64.S serpent-armv7-neon.S \
-sha1.c sha1-ssse3-amd64.S \
-sha256.c sha256-ssse3-amd64.S \
+sha1.c sha1-ssse3-amd64.S sha1-avx-amd64.S sha1-avx-bmi2-amd64.S \
+  sha1-armv7-neon.S \
+sha256.c sha256-ssse3-amd64.S sha256-avx-amd64.S sha256-avx2-bmi2-amd64.S \
 sha512.c sha512-ssse3-amd64.S sha512-avx-amd64.S sha512-avx2-bmi2-amd64.S \
-  sha512-armv7-neon.S \
+  sha512-armv7-neon.S sha512-arm.S \
+keccak.c keccak_permute_32.h keccak_permute_64.h keccak-armv7-neon.S \
 stribog.c \
 tiger.c \
-whirlpool.c \
+whirlpool.c whirlpool-sse2-amd64.S \
 twofish.c twofish-amd64.S twofish-arm.S \
 rfc2268.c \
 camellia.c camellia.h camellia-glue.c camellia-aesni-avx-amd64.S \
@@ -412,12 +477,15 @@ $(am__aclocal_m4_deps):
 
 clean-noinstLTLIBRARIES:
        -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
-       @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
-         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
-         test "$$dir" != "$$p" || dir=.; \
-         echo "rm -f \"$${dir}/so_locations\""; \
-         rm -f "$${dir}/so_locations"; \
-       done
+       @list='$(noinst_LTLIBRARIES)'; \
+       locs=`for p in $$list; do echo $$p; done | \
+             sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+             sort -u`; \
+       test -z "$$locs" || { \
+         echo rm -f $${locs}; \
+         rm -f $${locs}; \
+       }
+
 libcipher.la: $(libcipher_la_OBJECTS) $(libcipher_la_DEPENDENCIES) $(EXTRA_libcipher_la_DEPENDENCIES) 
        $(AM_V_CCLD)$(LINK)  $(libcipher_la_OBJECTS) $(libcipher_la_LIBADD) $(LIBS)
 
@@ -427,6 +495,7 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arcfour-amd64.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arcfour.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blowfish-amd64.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blowfish-arm.Plo@am__quote@
@@ -439,17 +508,27 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cast5-amd64.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cast5-arm.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cast5.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chacha20-armv7-neon.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chacha20-avx2-amd64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chacha20-sse2-amd64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chacha20-ssse3-amd64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chacha20.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-aeswrap.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-cbc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-ccm.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-cfb.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-cmac.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-ctr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-gcm-intel-pclmul.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-gcm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-ocb.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-ofb.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-poly1305.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-selftest.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crc-intel-pclmul.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/des-amd64.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/des.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dsa-common.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dsa.Plo@am__quote@
@@ -466,19 +545,29 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmac-tests.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idea.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kdf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keccak-armv7-neon.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keccak.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mac-cmac.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mac-gmac.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mac-hmac.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mac-poly1305.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mac.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md4.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/poly1305-armv7-neon.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/poly1305-avx2-amd64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/poly1305-sse2-amd64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/poly1305.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/primegen.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pubkey-util.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pubkey.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfc2268.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael-aesni.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael-amd64.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael-arm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael-padlock.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael-ssse3-amd64.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rmd160.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsa-common.Plo@am__quote@
@@ -492,10 +581,16 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/serpent-avx2-amd64.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/serpent-sse2-amd64.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/serpent.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1-armv7-neon.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1-avx-amd64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1-avx-bmi2-amd64.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1-ssse3-amd64.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha256-avx-amd64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha256-avx2-bmi2-amd64.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha256-ssse3-amd64.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha256.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha512-arm.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha512-armv7-neon.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha512-avx-amd64.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha512-avx2-bmi2-amd64.Plo@am__quote@
@@ -506,6 +601,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/twofish-amd64.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/twofish-arm.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/twofish.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/whirlpool-sse2-amd64.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/whirlpool.Plo@am__quote@
 
 .S.o:
@@ -534,14 +630,14 @@ distclean-compile:
 @am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
 
 .c.obj:
 @am__fastdepCC_TRUE@   $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
 @am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
 
 .c.lo:
 @am__fastdepCC_TRUE@   $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -556,26 +652,15 @@ mostlyclean-libtool:
 clean-libtool:
        -rm -rf .libs _libs
 
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
-       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
-       unique=`for i in $$list; do \
-           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-         done | \
-         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-             END { if (nonempty) { for (i in files) print i; }; }'`; \
-       mkid -fID $$unique
-tags: TAGS
-
-TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-               $(TAGS_FILES) $(LISP)
+ID: $(am__tagged_files)
+       $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
        set x; \
        here=`pwd`; \
-       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-       unique=`for i in $$list; do \
-           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-         done | \
-         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-             END { if (nonempty) { for (i in files) print i; }; }'`; \
+       $(am__define_uniq_tagged_files); \
        shift; \
        if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
@@ -587,15 +672,11 @@ TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
              $$unique; \
          fi; \
        fi
-ctags: CTAGS
-CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-               $(TAGS_FILES) $(LISP)
-       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-       unique=`for i in $$list; do \
-           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-         done | \
-         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-             END { if (nonempty) { for (i in files) print i; }; }'`; \
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+       $(am__define_uniq_tagged_files); \
        test -z "$(CTAGS_ARGS)$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$unique
@@ -604,6 +685,21 @@ GTAGS:
        here=`$(am__cd) $(top_builddir) && pwd` \
          && $(am__cd) $(top_srcdir) \
          && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+       list='$(am__tagged_files)'; \
+       case "$(srcdir)" in \
+         [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+         *) sdir=$(subdir)/$(srcdir) ;; \
+       esac; \
+       for i in $$list; do \
+         if test -f "$$i"; then \
+           echo "$(subdir)/$$i"; \
+         else \
+           echo "$$sdir/$$i"; \
+         fi; \
+       done >> $(top_builddir)/cscope.files
 
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
@@ -664,10 +760,12 @@ install-strip:
 mostlyclean-generic:
 
 clean-generic:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
 
 distclean-generic:
        -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
        -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+       -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
 
 maintainer-clean-generic:
        @echo "This command is intended for maintainers to use"
@@ -745,19 +843,27 @@ uninstall-am:
 
 .MAKE: install-am install-strip
 
-.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
-       clean-libtool clean-noinstLTLIBRARIES ctags distclean \
-       distclean-compile distclean-generic distclean-libtool \
-       distclean-tags distdir dvi dvi-am html html-am info info-am \
-       install install-am install-data install-data-am install-dvi \
-       install-dvi-am install-exec install-exec-am install-html \
-       install-html-am install-info install-info-am install-man \
-       install-pdf install-pdf-am install-ps install-ps-am \
-       install-strip installcheck installcheck-am installdirs \
-       maintainer-clean maintainer-clean-generic mostlyclean \
-       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
-       pdf pdf-am ps ps-am tags uninstall uninstall-am
-
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+       clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \
+       ctags-am distclean distclean-compile distclean-generic \
+       distclean-libtool distclean-tags distdir dvi dvi-am html \
+       html-am info info-am install install-am install-data \
+       install-data-am install-dvi install-dvi-am install-exec \
+       install-exec-am install-html install-html-am install-info \
+       install-info-am install-man install-pdf install-pdf-am \
+       install-ps install-ps-am install-strip installcheck \
+       installcheck-am installdirs maintainer-clean \
+       maintainer-clean-generic mostlyclean mostlyclean-compile \
+       mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+       tags tags-am uninstall uninstall-am
+
+
+gost28147.lo: gost-sb.h
+gost-sb.h: gost-s-box
+       ./gost-s-box $@
+
+gost-s-box: gost-s-box.c
+       $(CC_FOR_BUILD) -o $@ $(srcdir)/gost-s-box.c
 
 # We need to lower the optimization for this module.
 tiger.o: $(srcdir)/tiger.c
diff --git a/cipher/Manifest b/cipher/Manifest
deleted file mode 100644 (file)
index 0cd64f7..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-# Manifest - checksums of the cipher directory
-# Copyright 2003 Free Software Foundation, Inc.
-#
-# This file is part of Libgcrypt.
-#
-# Libgcrypt is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser general Public License as
-# published by the Free Software Foundation; either version 2.1 of
-# the License, or (at your option) any later version.
-#
-# Libgcrypt is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
-# Checksums for all source files in this directory. Format is
-# filename, blanks, base-64 part of an OpenPGP detached signature
-# without the header lines.  Blank lines and lines beginning with a
-# hash mark are ignored.  A tool to process this file is available by
-# cvs -d :pserver:anoncvs@cvs.gnupg.org:/cvs/wk co misc-scripts/manifest-tool
-#
-# The special entry "$names$" holds a signature over all sorted
-# filenames excluding itself.
-
-
-# Algorithm API
-cipher.c iQCVAwUAQDzrVjEAnp832S/7AQIPDgP+OVJ/YNWY5m7c09EBbPAzL/WsGoj6wrBNMmkRlMOqTHeh+OOtjuFHt1f9uhfM2Nzl7sJ5+h4ryZKLEZmQPRMTZTnAqkvGdsrJWJnigUA9QwYdV0ONqC9C63gpuG465gO9TZVOqlQu/FTxSRuTQYUulkaBNG71n8nZEOusBVwV2YA==58xH
-pubkey.c iQCVAwUAP9XQ3jEAnp832S/7AQJ5UgQAyHfEBvPVJ8wTRg8c7ixS2GiVmIgwIo5tvQaiQJTPWASevvYrB+2Z2qa9cATyu50ACjLzbaquGBgPzjJV3dU/qttT1gCqRuN/LCNvXFe5qnIZezejc3RAadFNTw/pOTHq0wxD1Keg66ruei9R36Nba59pEQIWIBXTfubRft2hMYk==E09t
-ac.c iQCVAwUAQDzsOzEAnp832S/7AQJCBQP/WI6EV/dsR4rmha6RVhvkjZo17kQ8z6pIl5J3cXOvqEkIFeD2HYu3HHrWST5l7yXlffhpDkVHkfMih4ruK76q6Fm0dxZ98pO4C/dVtgimlvvcy/wOQjpzsE0fYAe1BYdg81LJ09X33vW5x6C29lunfKROO2tPlV5i8ffeoFvmMF8==j26g
-md.c iQCVAwUAP+NFGjEAnp832S/7AQJs8wP/Qdk0EAKsyr3O1/pmOSN8AG4rPKbd6KDTzvoBPAN4upFwKYY4hWwvy12Q3YU9DmECrzZkRCXHR7mljVQKs6B7CRZJKjFKmOELpcJDtKvu40vTs1bOH4k9iJYZpGgRA83nkQ+ELAcphAbCA+KIpVr2K4mCJAB0FhpC2uOQ50JHAko==BeF6
-primegen.c iQCVAwUAQDzsoDEAnp832S/7AQKYRwP/TqAQBm1rHTnF0HYE05PqXfWlOqa6EosqVpaOcs/OIW6PaqX0xH1UlrukK7jNOjK3xC4o1qNQ1UKzz2dvQaq1bMvNNizeavxAh10SJZc0hIc/ofc83IbjLh8SZVWQ67JxjsUd3DOXmSmhPZ+Pqd7cUIiw8fDoF+I9EZqy3COu1wY==1ebT
-
-# Algorithm implementations
-arcfour.c iQCVAwUAP9XR/TEAnp832S/7AQJcRwP6AlvYEx++fpT4mIYo0xRDqKEQeqMQvbaRhIg2eV74JxItpHa3q5YsYIl+n1yUz5g35JRWWXSWmAZBwO5wLKsHii4kRUhgrKWnSoQZoPpl49L5+N3R58ON3S0ru5lsBiEJEze3xplf2vqwrH9v1QHVD+gU7UTlfNqrIJoOUXN+1O4==Tq+x
-blowfish.c iQCVAwUAP9XTETEAnp832S/7AQJaEgQAgiqqfuO+zQtscgTB0rvOzVymIKjRKjYhFuLjVuc79G4z1RCAffvIn/YM2d7kt+Z/QF7zjcTAOgETCQL1XokpX2zz9HPAMi2tlDY5zsDufTNqj0n4WBL9nM7w6XAvsiwP1B3bqCTv9SjJV4KbxJ58vw1yQE+sqW74R/QIHFvC7mU==wZnX
-cast5.c iQCVAwUAP9XT6DEAnp832S/7AQJ3xgP/ehLjEN3GELGudbqeo91Xd+PqitHrkuBbtRIYX7Udd/fyXLN+h8rMJVyIQX2m+mpxbBxudVU3x8/DNT8B0ZHAwK6qqJmEBLLhEYPgIuF76i9LMrP1KqUPhAwRZ2OppjIIugBQ+rP74aD4eLyd/aKQHNuXML8QGWR6KwQShohXM5I==/BRh
-crc.c iQCVAwUAP7ouejEAnp832S/7AQIgwQQApg5Nm63tH5DQkbN+zPzMO9Ygoj3ukxfFTyTBPYSXYKMiTjEbESegaU40uN8jnz2vprcIQWcgZfzO4+opEJMcI35aPwzEk0vKOp0S/PrBLUY2rJfnDVkX5XgJFZa2Q7LLe826UEBzTVYW924utiCCe8oOaOEWVNpg1mqdknu3M9o==kz5D
-des.c iQCVAwUAQCN2oDEAnp832S/7AQL/jwP6Auoq6nZCDBjpgc9tDzuIRwa9DqyuM3gX94uvgEpUwdHszb2bG43dz03kVmcYxtj1MzXbyCeCZOwox0b2SKmLgxIbrNP6yGbzVdTj6592gDYuf/ZXmc1ZNJ1DDldcPQ0n9fXUipUPwyPaNWo3mSZaNcMKSWWzdK0J6ciG6nk7SWI==9k/t
-dsa.c iQCVAwUAP9XZHDEAnp832S/7AQLBRgP/XrBzTEYx5ccMj1MMb6sg37liEHdIyyy49zjvt6jUqxj4RuwVEN8S6v3u4q/QyJkHAi1E0EkREgENlyHW6PKWhYbcrd0vPIAN15yjnl2yqtrCrJImexUCoqJJewK0E4JOicGbabTil8MZjk+mbhEPnjJBqOkyP1w0i31pEDgE/8M==pC8s
-elgamal.c iQCVAwUAP9XbYzEAnp832S/7AQLXagQA3HrvspZfbTGgmUH0IqLQTJ0exUPxJv5DET2TvoIy62trDmMN6lTAj5P+a7jQ8udcu0w+mR2vXUHcxUpNA2PxLaMwGzNSY4zRDNe9r3SFTDrFm6m4y9Ko2e8XtEA+WF6P/XLpck4Jn7vMEDmVGPwkNd22kXFFE8dBGwG6i5Hk1Mk==oBUs
-md4.c iQCVAwUAP9h50DEAnp832S/7AQJhHgQAzNA/B6MWFDlCtPkIVaW8RpP1Eg0ZNMsy0s7SJkopOCBlu6CwXUOKe+8ppcSxhjYKh4i4uQr/QtfipYlBjzKJGnrafoF/NugXNCOHSTGT11TvK7mCiBuUMVgvZGAlOJImk6eTTfUjRrMfaXM/SWl8bdJ4ZpzdjEyVh89r7I5JrGk==x2UD
-md5.c iQCVAwUAP9h7LzEAnp832S/7AQJUGQP/c0cbf6WZXCzmjufHxiE9FAQBzTsA0WtaNqdFcHl7fhmikGtknlaED8n5a7eYd/C481UQW6Wgq/oZdsvgoPWPhG3fOCy2CFP9cZVXITuMSf0ucyZTFUJNO15fnZ+nDfsUv+JPdv1aSeRinAUtfAcSKfkSyR9BCPZvkx+tgU6cphU==Zv+h
-rijndael.c iQCVAwUAP9h9cTEAnp832S/7AQKF1AP+P2L/tPqDJRDg+/fwbOk8Ts0MNxnvvYEm3gE73TKuLt1S+B2+jkrZcKNvM5VGPnVMJbnS0lmIK04nmedHCOftGTOwhGulZAHHIaKGystT3Jql4iPws/JMgAjE7Fyxh5WZMtB9yEljKBpJ5XNqhrMvvxcHpnyP3+YzIXNwzk34V+c==dJ5k
-rmd160.c iQCVAwUAP9h+bTEAnp832S/7AQK1OgP+PNKF6Nzi6X93easVlksdLqKEsArCAw2QjGWDGyxTnbiJM55qAl9JxR1mn3V+oOL7izLLwTt6EYK9evhzfcxY5N5Mni85RAcsLPsuAfQDEzjI6GUWHtQUKPbM+BaorzfhQjYFSZyvum/dZYJ/WfiwwwhqqIKyVU2ZFSqA38YGC/c==9jdA
-rsa.c iQCVAwUAP9iHIzEAnp832S/7AQKAYwQAuWtnMte54QHN+Hij9t4sGuypXogajOb1vQQwGgS0fKsaBZsuSP2amze4o5diIvsQTsFQ4CzjvqoCVuBDoHM3xkSD8wGDizgvtCamAxkdbF7wmzldKFn8SpJqlVwWQMP6kk1IjXHEuYb4IDWGTbVMhfEu+eOlU8+PSK4IhZqNvt4==/3hp
-serpent.c iQCVAwUAP9h/VzEAnp832S/7AQLyCwP/d1zbmb7l/PriZNa9/Z7mo01XFe5MnAqCfIwhl9GjeaMszcoS37jECNq5nLvrTTFIIJpm3rvBePwiCG4Wwx1I18HCxaP198pcSaR+BLOJ3Aj52EZPrxtqlDKuFr38ZOP5giyUqUYVYGVdrz4kRMNWAZQK53GeJnGhXCnhxojLEgA==ck46
-sha1.c iQCVAwUAP9iATTEAnp832S/7AQKcSwQAwAs/HnNqho3lU1ZUgCPNt5P2/Brm6W21+wWWGKJkSrra/c4NYVKJGDDwlsFE0b9ln1uZt7bHReFkKXK3JnrKTmNVcx/Cy64iCMRNMhaM72Mqy7wWx5yHBAmMBxzFGnNQKbmeY52zeGih5HsNLSibc2pPuOViWo2JPJ5Ci/wIwl8==/wtO
-sha256.c iQCVAwUAP9iAtzEAnp832S/7AQJD2QP/UqvL0hhjG1wEFbGrdkV9tba1sMDXdnnK6X7HdLuRpVAgNiQiFf8JDmntd/dZ2Q71p4Uae2ctqve4WoEijPUZPjACnpuZfx0SEQL0lQBkwxzJp7lz9ujVtwQ2cM/aYexJkXcWgGcloJNLM3JbWPGIJnuYbr/IwJ6RQF9vgj0357o==UWO1
-sha512.c iQCVAwUAP9iBTDEAnp832S/7AQIPBAQA28CJSUQLiW0s2x9u8/OH2eKnxPjA4sZmb50WP7920Lem66P31C3BrOqwfBot4RLhjL+zh/+Uc4s3HPwApZuj9E4BxNMlqLv+Tqk++DAbdaOeYT4jeUt+mlhQQ6mH/RDsy32rZsNsGQ2bUGxazZmfG++PL3JyhawqCy00SUDr/o0==H+0X
-tiger.c iQCVAwUAP9iCfjEAnp832S/7AQKufwP/fryv3MqSOYY+90325DH7X3/CtekxeooN0scGsHX0fxBakWSMecTNrj33KPddLS46gU/S89zIc2N/Bw/7EVIAXVFA3/3Ip+OrFOuIMO4Py1sCdB8o2Y+5ygv8iXLcsXIq1O0av79i9g774V3uaXa2qN9ZnXe0AEhcy8FHJ2i/wro==5XVB
-twofish.c iQCVAwUAP9iD6TEAnp832S/7AQKUnQP/Rq8FaYeHTG7HbZuqAs9pbPitzjDbkdZddmInWR7NmevBkKvhsJALjVooc0KGQfo2lAAmy3Xi/4QQN8VPn51DVjDIgf7x+DQh/9TFJHMccxI9asUgi4+TNnmMqLU1k3N8S2PjyZ1sjeC8B79fKPpwCzj72WkqPkzZw3l2jArr+dU==NdJT
-rfc2268.c iQCVAwUAQCN+3jEAnp832S/7AQLv1gQA1hJh29hAjKi4uLSGxXvJ6cyYmPdmevdKrbLnuHZWtHe4xvCgy/nTdEojEpxgLp/hL/ogasuWRC1W16Wiz9ryxf7YR0uhZWayO/bQNagpfU5MIkJTLuKqqgpwYumCSQfOugXVAqcgEzj+13eeyJaFVrzwrNa67sh84nmbjOjNjvE==0zBq
-
-# Random number related
-random.c iQCVAwUAP7nsITEAnp832S/7AQK4SAQAtvfUgrtGOQ2PlxGMla0qJLPHjJacMwgq0ecusiI79elPdDsFfCCk6dK1Ug2kFbNm22nCGHNcUquqbX7noi7ZVQnmPBQXzyLNZd7GmrawRZfdlRerTUDBpSnR8V8ui/5+YYp627E7kKGC0hPSgqXFql6oBMIfno0LZwFJTjIevRY==L419
-random.h iQCVAwUAP7ovKDEAnp832S/7AQJ3bQQAjnPebnyTC7sphAv2I7uIz+yPgw1ZfbVhLv+OiWDlO9ish+fRyyMpy+HELBOgZjJdgRegqhlZC6qyns5arM/VglYi+PzvdLO3hIqHE/YFfpIFPz8wBrcmlqrYyd3CsGqcYsfjocXNttCBLeSWmoJ09ltKQH8yzJf3oAgN6X1yuc4==eNoU
-rand-internal.h iQCVAwUAP7ouvDEAnp832S/7AQLYnAQAhdI7ERoJVCkV8GiV7MjaUxv1WIL7iZ+jIOvVhv4fNyhCGCGoEtTjkyput/lj7Nsh3FXEqRhypGGrCLf47x/gua5n+BwffogxVyUDqiOyyGhNTPpe3fQcNBvbPCtco8yMK4GJO5G3BqzlPyN+BMeogLymyV6Sm1mvh5LZDyAFbfQ==tZSE
-rndlinux.c iQCVAwUAP9iPYTEAnp832S/7AQL6/AP/ZDrbOkVuB9qJ7sKeX1MImZEsz3mi0xPovJzaBtBU7a0idcUKrWYOvQFWRlLUeq0iCT6+h2l5bniP7q7hepzlKa+VPY9VWaQthqeJm2l5LN6QQ5PyMfBq04QuBncw9BJnCGmEyTLt3RxIXBAPdxmiVxtcRIFUqCBtQvoUXGLvemw==t37k
-rndegd.c iQCVAwUAP9iPRDEAnp832S/7AQImBQP/WHKg+hKXcm1pQvilzML0jZpwK5PAMM4uBnnPJNIXWOYBO6I/Xg9d/tPLg8NlmmtyQCo2Eu0ybDSt+8mu+dWveAys+0LTi0MIqeP9BMzCKz8dnWH6+S8huLXwTF3m0IrqM0JLb6b71GK9SOq6sWQ22yW5vf61hXP8kH9dhIaoMZs==FaHV
-rndunix.c iQCVAwUAP9iQlzEAnp832S/7AQL/KgQA29GnvcD4Xb5qjDMBgW9THEE4+4lfex/6k+Fh0IT61OLJsWVLJ7bJpRntburw4uQm4Tf7CO8vaiDFDYhKKrzXeOF1fmdpcL8hA+fNp9I/MUOc4e9kN9+YJ9wikVa0SZj1OBfhzgcFLd1xOtulkr3ii52HLF9vhrxzkgVwvD10Bi8==2cML
-rndw32.c iQCVAwUAP9iRKDEAnp832S/7AQIuaAQA3AJr3WqnxNDsWCIdvehf8Suotthj+laX8nJsvDfFhXPKcXDpsg0wTTXSnnKgyED53+uYiMDnVRsxeWAyhKwvx1MjjlaSMMjzbH6isWTH8FaWpLgrxEkXoPeNqYf5FXpdUkcUxGX2RkQeuX/cIfiHLNE9CV0usaF2jysjBX2iERY==EEnO
-
-# Helper
-bithelp.h iQCVAwUAP7ouPTEAnp832S/7AQKXggQAqjcgvihIF3WclOgw1JV2rbARw4ISIDRMFqdaNCqBRx6BwEz3UGsEIlz6+iR1sS/reqN61WvtjLb+D0+tujAkGrgQJhFLG85WtG2tB5UVoI3am1fpkwiRm+bR4rv0rGk0BYk81bC7+l4KrK9o5lVp4lCsrorlUKsd48lNmBHyAXM==mDDN
-rmd.h iQCVAwUAP7oumjEAnp832S/7AQJiJQP/V4bJwjZaYndJzV+KRnIDbl1koHuw+ZK5heMYVu8Qk4ylqv//BGyeRa3jZCcfPHI35q6HilCs2VBm8hiBMjHSqY/VPn2ZQ0yg/lt6qEvl7YjsLmyMICvjG+ncszHoq9pRvnF3vTnM18sPIioXLk8fskuM0XOCNBs0ARBAQjY9UGI==olUN
-
-# Configuration
-Makefile.am iQCVAwUAQCN33TEAnp832S/7AQKFJAQAz7BDkC814q+QiuE/jnutJHR5qlgbrm3ikGbQwdRzYUscst4bCCWy3uKL/sIPGLg+JQXtF5FnsQy3s4D9BOYhp72cA9ktYK65hhi4pNm/JQ0lXkZMNfk8Go5lNzKezlWwHvkMwRXR0Fep0wPdyeaKW5BfaW2ABvgep6Bp+hHEbyg==zSyi
-$names$ iQCVAwUAQCN3EDEAnp832S/7AQJXLAP8DvHTpm5DkTF35EmzeKpi9ie59AZcZanD19ir/e/7+PaQxr2riuLHDGwFKTju+dcvvBsqrygXOC378GXVWzIF2OZwS4EdDcJ+pgojo9UpsqpKsJHouY4Ugx5cQialxba462kUn8hcihSBnMyc4LzbJ5WQ4puQuqy544d2x94+2ms==G4Ls
diff --git a/cipher/arcfour-amd64.S b/cipher/arcfour-amd64.S
new file mode 100644 (file)
index 0000000..2e52ea0
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+** RC4 implementation optimized for AMD64.
+**
+** Author: Marc Bevand <bevand_m (at) epita.fr>
+** Licence: I hereby disclaim the copyright on this code and place it
+** in the public domain.
+**
+** The throughput achieved by this code is about 320 MBytes/sec, on
+** a 1.8 GHz AMD Opteron (rev C0) processor.
+**
+** 2013/12/20 <jussi.kivilinna@iki.fi>:
+**  - Integrated to libgcrypt
+**  - 4.18 cycles/byte on Intel i5-4570
+*/
+
+#ifdef __x86_64__
+#include <config.h>
+#if defined(USE_ARCFOUR) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+    defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
+
+.text
+.align 16
+.globl _gcry_arcfour_amd64
+ELF(.type _gcry_arcfour_amd64,@function)
+_gcry_arcfour_amd64:
+       push    %rbp
+       push    %rbx
+       mov     %rdi,           %rbp    # key = ARG(key)
+       mov     %rsi,           %rbx    # rbx = ARG(len)
+       mov     %rdx,           %rsi    # in = ARG(in)
+       mov     %rcx,           %rdi    # out = ARG(out)
+       mov     (4*256)(%rbp),  %ecx    # x = key->x
+       mov     (4*256+4)(%rbp),%edx    # y = key->y
+       inc     %rcx                    # x++
+       and     $255,           %rcx    # x &= 0xff
+       lea     -8(%rbx,%rsi),  %rbx    # rbx = in+len-8
+       mov     %rbx,           %r9     # tmp = in+len-8
+       mov     (%rbp,%rcx,4),  %eax    # tx = d[x]
+       cmp     %rsi,           %rbx    # cmp in with in+len-8
+       jl      .Lend                   # jump if (in+len-8 < in)
+
+.Lstart:
+       add     $8,             %rsi            # increment in
+       add     $8,             %rdi            # increment out
+
+       # generate the next 8 bytes of the rc4 stream into %r8
+       mov     $8,             %r11            # byte counter
+1:     add     %al,            %dl             # y += tx
+       mov     (%rbp,%rdx,4),  %ebx            # ty = d[y]
+       mov     %ebx,           (%rbp,%rcx,4)   # d[x] = ty
+       add     %al,            %bl             # val = ty + tx
+       mov     %eax,           (%rbp,%rdx,4)   # d[y] = tx
+       inc     %cl                             # x++           (NEXT ROUND)
+       mov     (%rbp,%rcx,4),  %eax            # tx = d[x]     (NEXT ROUND)
+       shl     $8,             %r8
+       movb    (%rbp,%rbx,4),  %r8b            # val = d[val]
+       dec     %r11b
+       jnz 1b
+
+       # xor 8 bytes
+       bswap   %r8
+       xor     -8(%rsi),       %r8
+       cmp     %r9,            %rsi            # cmp in+len-8 with in
+       mov     %r8,            -8(%rdi)
+       jle     .Lstart                         # jump if (in <= in+len-8)
+
+.Lend:
+       add     $8,             %r9             # tmp = in+len
+
+       # handle the last bytes, one by one
+1:     cmp     %rsi,           %r9             # cmp in with in+len
+       jle     .Lfinished                      # jump if (in+len <= in)
+       add     %al,            %dl             # y += tx
+       mov     (%rbp,%rdx,4),  %ebx            # ty = d[y]
+       mov     %ebx,           (%rbp,%rcx,4)   # d[x] = ty
+       add     %al,            %bl             # val = ty + tx
+       mov     %eax,           (%rbp,%rdx,4)   # d[y] = tx
+       inc     %cl                             # x++           (NEXT ROUND)
+       mov     (%rbp,%rcx,4),  %eax            # tx = d[x]     (NEXT ROUND)
+       movb    (%rbp,%rbx,4),  %r8b            # val = d[val]
+       xor     (%rsi),         %r8b            # xor 1 byte
+       movb    %r8b,           (%rdi)
+       inc     %rsi                            # in++
+       inc     %rdi                            # out++
+       jmp 1b
+
+.Lfinished:
+       dec     %rcx                            # x--
+       movb    %cl,            (4*256)(%rbp)   # key->y = y
+       movb    %dl,            (4*256+4)(%rbp) # key->x = x
+       pop     %rbx
+       pop     %rbp
+       ret
+.L__gcry_arcfour_amd64_end:
+ELF(.size _gcry_arcfour_amd64,.L__gcry_arcfour_amd64_end-_gcry_arcfour_amd64)
+
+#endif
+#endif
index d692c84..44e8ef4 100644 (file)
 #include "g10lib.h"
 #include "cipher.h"
 
+/* 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) || \
+    defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define USE_AMD64_ASM 1
+#endif
+
 static const char *selftest(void);
 
+#ifdef USE_AMD64_ASM
+
+typedef struct {
+    u32 sbox[256];
+    u32 idx_i, idx_j;
+} ARCFOUR_context;
+
+void _gcry_arcfour_amd64(void *key, size_t len, const byte *indata,
+                        byte *outdata);
+
+static void
+encrypt_stream (void *context,
+                byte *outbuf, const byte *inbuf, size_t length)
+{
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+  const void *fn = _gcry_arcfour_amd64;
+  /* Call SystemV ABI function without storing non-volatile XMM registers,
+   * as target function does not use vector instruction sets. */
+  asm volatile ("callq *%0\n\t"
+                : "+a" (fn),
+                  "+D" (context),
+                  "+S" (length),
+                  "+d" (inbuf),
+                  "+c" (outbuf)
+                :
+                : "cc", "memory", "r8", "r9", "r10", "r11");
+#else
+  _gcry_arcfour_amd64 (context, length, inbuf, outbuf );
+#endif
+}
+
+#else /*!USE_AMD64_ASM*/
+
 typedef struct {
     byte sbox[256];
     int idx_i, idx_j;
@@ -96,6 +136,8 @@ encrypt_stream (void *context,
   _gcry_burn_stack (64);
 }
 
+#endif /*!USE_AMD64_ASM*/
+
 
 static gcry_err_code_t
 do_arcfour_setkey (void *context, const byte *key, unsigned int keylen)
index 6e59c53..4575380 100644 (file)
@@ -4,7 +4,7 @@
  * This file is part of Libgcrypt.
  *
  * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser general Public License as
+ * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation; either version 2.1 of
  * the License, or (at your option) any later version.
  *
  * GNU Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef G10_BITHELP_H
-#define G10_BITHELP_H
+#ifndef GCRYPT_BITHELP_H
+#define GCRYPT_BITHELP_H
 
 #include "types.h"
 
@@ -48,33 +47,70 @@ _gcry_bswap32(u32 x)
 }
 #endif
 
-#ifdef HAVE_U64_TYPEDEF
-# ifdef HAVE_BUILTIN_BSWAP64
-#  define _gcry_bswap64 __builtin_bswap64
-# else
+#ifdef HAVE_BUILTIN_BSWAP64
+# define _gcry_bswap64 __builtin_bswap64
+#else
 static inline u64
 _gcry_bswap64(u64 x)
 {
        return ((u64)_gcry_bswap32(x) << 32) | (_gcry_bswap32(x >> 32));
 }
-# endif
 #endif
 
 /* Endian dependent byte swap operations.  */
 #ifdef WORDS_BIGENDIAN
 # define le_bswap32(x) _gcry_bswap32(x)
 # define be_bswap32(x) ((u32)(x))
-# ifdef HAVE_U64_TYPEDEF
-#  define le_bswap64(x) _gcry_bswap64(x)
-#  define be_bswap64(x) ((u64)(x))
-# endif
+# define le_bswap64(x) _gcry_bswap64(x)
+# define be_bswap64(x) ((u64)(x))
 #else
 # define le_bswap32(x) ((u32)(x))
 # define be_bswap32(x) _gcry_bswap32(x)
-# ifdef HAVE_U64_TYPEDEF
-#  define le_bswap64(x) ((u64)(x))
-#  define be_bswap64(x) _gcry_bswap64(x)
-# endif
+# define le_bswap64(x) ((u64)(x))
+# define be_bswap64(x) _gcry_bswap64(x)
+#endif
+
+
+/* Count trailing zero bits in an unsigend int.  We return an int
+   because that is what gcc's builtin does.  Returns the number of
+   bits in X if X is 0. */
+static inline int
+_gcry_ctz (unsigned int x)
+{
+#if defined (HAVE_BUILTIN_CTZ)
+  return x? __builtin_ctz (x) : 8 * sizeof (x);
+#else
+  /* See
+   * http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightModLookup
+   */
+  static const unsigned char mod37[] =
+    {
+      sizeof (unsigned int)*8,
+          0,  1, 26,  2, 23, 27,  0,  3, 16, 24, 30, 28, 11,  0, 13,
+      4,  7, 17,  0, 25, 22, 31, 15, 29, 10, 12,  6,  0, 21, 14,  9,
+      5, 20,  8, 19, 18
+    };
+  return (int)mod37[(-x & x) % 37];
+#endif
+}
+
+
+/* Count trailing zero bits in an u64.  We return an int because that
+   is what gcc's builtin does.  Returns the number of bits in X if X
+   is 0.  */
+static inline int
+_gcry_ctz64(u64 x)
+{
+#if defined (HAVE_BUILTIN_CTZ) && SIZEOF_UNSIGNED_INT >= 8
+#warning hello
+  return x? __builtin_ctz (x) : 8 * sizeof (x);
+#else
+  if ((x & 0xffffffff))
+    return _gcry_ctz (x);
+  else
+    return 32 + _gcry_ctz (x >> 32);
 #endif
+}
+
 
-#endif /*G10_BITHELP_H*/
+#endif /*GCRYPT_BITHELP_H*/
index 6975e55..21b63fc 100644 (file)
@@ -1,6 +1,6 @@
 /* blowfish-amd64.S  -  AMD64 assembly implementation of Blowfish cipher
  *
- * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
 
 #ifdef __x86_64
 #include <config.h>
-#if defined(USE_BLOWFISH) && defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS)
+#if defined(USE_BLOWFISH) && \
+    (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
 
 .text
 
        movq RX0,               (RIO);
 
 .align 8
-.type   __blowfish_enc_blk1,@function;
+ELF(.type   __blowfish_enc_blk1,@function;)
 
 __blowfish_enc_blk1:
        /* input:
@@ -145,11 +153,11 @@ __blowfish_enc_blk1:
        movq %r11, %rbp;
 
        ret;
-.size __blowfish_enc_blk1,.-__blowfish_enc_blk1;
+ELF(.size __blowfish_enc_blk1,.-__blowfish_enc_blk1;)
 
 .align 8
 .globl  _gcry_blowfish_amd64_do_encrypt
-.type   _gcry_blowfish_amd64_do_encrypt,@function;
+ELF(.type   _gcry_blowfish_amd64_do_encrypt,@function;)
 
 _gcry_blowfish_amd64_do_encrypt:
        /* input:
@@ -171,11 +179,11 @@ _gcry_blowfish_amd64_do_encrypt:
        movl RX0d, (RX2);
 
        ret;
-.size _gcry_blowfish_amd64_do_encrypt,.-_gcry_blowfish_amd64_do_encrypt;
+ELF(.size _gcry_blowfish_amd64_do_encrypt,.-_gcry_blowfish_amd64_do_encrypt;)
 
 .align 8
 .globl  _gcry_blowfish_amd64_encrypt_block
-.type   _gcry_blowfish_amd64_encrypt_block,@function;
+ELF(.type   _gcry_blowfish_amd64_encrypt_block,@function;)
 
 _gcry_blowfish_amd64_encrypt_block:
        /* input:
@@ -195,11 +203,11 @@ _gcry_blowfish_amd64_encrypt_block:
        write_block();
 
        ret;
-.size _gcry_blowfish_amd64_encrypt_block,.-_gcry_blowfish_amd64_encrypt_block;
+ELF(.size _gcry_blowfish_amd64_encrypt_block,.-_gcry_blowfish_amd64_encrypt_block;)
 
 .align 8
 .globl  _gcry_blowfish_amd64_decrypt_block
-.type   _gcry_blowfish_amd64_decrypt_block,@function;
+ELF(.type   _gcry_blowfish_amd64_decrypt_block,@function;)
 
 _gcry_blowfish_amd64_decrypt_block:
        /* input:
@@ -231,7 +239,7 @@ _gcry_blowfish_amd64_decrypt_block:
        movq %r11, %rbp;
 
        ret;
-.size _gcry_blowfish_amd64_decrypt_block,.-_gcry_blowfish_amd64_decrypt_block;
+ELF(.size _gcry_blowfish_amd64_decrypt_block,.-_gcry_blowfish_amd64_decrypt_block;)
 
 /**********************************************************************
   4-way blowfish, four blocks parallel
@@ -319,7 +327,7 @@ _gcry_blowfish_amd64_decrypt_block:
        bswapq                  RX3;
 
 .align 8
-.type   __blowfish_enc_blk4,@function;
+ELF(.type   __blowfish_enc_blk4,@function;)
 
 __blowfish_enc_blk4:
        /* input:
@@ -343,10 +351,10 @@ __blowfish_enc_blk4:
        outbswap_block4();
 
        ret;
-.size __blowfish_enc_blk4,.-__blowfish_enc_blk4;
+ELF(.size __blowfish_enc_blk4,.-__blowfish_enc_blk4;)
 
 .align 8
-.type   __blowfish_dec_blk4,@function;
+ELF(.type   __blowfish_dec_blk4,@function;)
 
 __blowfish_dec_blk4:
        /* input:
@@ -372,11 +380,11 @@ __blowfish_dec_blk4:
        outbswap_block4();
 
        ret;
-.size __blowfish_dec_blk4,.-__blowfish_dec_blk4;
+ELF(.size __blowfish_dec_blk4,.-__blowfish_dec_blk4;)
 
 .align 8
 .globl  _gcry_blowfish_amd64_ctr_enc
-.type   _gcry_blowfish_amd64_ctr_enc,@function;
+ELF(.type   _gcry_blowfish_amd64_ctr_enc,@function;)
 _gcry_blowfish_amd64_ctr_enc:
        /* input:
         *      %rdi: ctx, CTX
@@ -429,11 +437,11 @@ _gcry_blowfish_amd64_ctr_enc:
        popq %rbp;
 
        ret;
-.size _gcry_blowfish_amd64_ctr_enc,.-_gcry_blowfish_amd64_ctr_enc;
+ELF(.size _gcry_blowfish_amd64_ctr_enc,.-_gcry_blowfish_amd64_ctr_enc;)
 
 .align 8
 .globl  _gcry_blowfish_amd64_cbc_dec
-.type   _gcry_blowfish_amd64_cbc_dec,@function;
+ELF(.type   _gcry_blowfish_amd64_cbc_dec,@function;)
 _gcry_blowfish_amd64_cbc_dec:
        /* input:
         *      %rdi: ctx, CTX
@@ -477,11 +485,11 @@ _gcry_blowfish_amd64_cbc_dec:
        popq %rbp;
 
        ret;
-.size _gcry_blowfish_amd64_cbc_dec,.-_gcry_blowfish_amd64_cbc_dec;
+ELF(.size _gcry_blowfish_amd64_cbc_dec,.-_gcry_blowfish_amd64_cbc_dec;)
 
 .align 8
 .globl  _gcry_blowfish_amd64_cfb_dec
-.type   _gcry_blowfish_amd64_cfb_dec,@function;
+ELF(.type   _gcry_blowfish_amd64_cfb_dec,@function;)
 _gcry_blowfish_amd64_cfb_dec:
        /* input:
         *      %rdi: ctx, CTX
@@ -527,7 +535,7 @@ _gcry_blowfish_amd64_cfb_dec:
        popq %rbx;
        popq %rbp;
        ret;
-.size _gcry_blowfish_amd64_cfb_dec,.-_gcry_blowfish_amd64_cfb_dec;
+ELF(.size _gcry_blowfish_amd64_cfb_dec,.-_gcry_blowfish_amd64_cfb_dec;)
 
 #endif /*defined(USE_BLOWFISH)*/
 #endif /*__x86_64*/
index 901d0c3..b30aa31 100644 (file)
@@ -1,6 +1,6 @@
 /* blowfish-arm.S  -  ARM assembly implementation of Blowfish cipher
  *
- * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
index ae470d8..a3fc26c 100644 (file)
@@ -45,7 +45,8 @@
 
 /* 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) && \
+#if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+    defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
     (BLOWFISH_ROUNDS == 16)
 # define USE_AMD64_ASM 1
 #endif
@@ -280,22 +281,87 @@ extern void _gcry_blowfish_amd64_cbc_dec(BLOWFISH_context *ctx, byte *out,
 extern void _gcry_blowfish_amd64_cfb_dec(BLOWFISH_context *ctx, byte *out,
                                         const byte *in, byte *iv);
 
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+static inline void
+call_sysv_fn (const void *fn, const void *arg1, const void *arg2,
+              const void *arg3, const void *arg4)
+{
+  /* Call SystemV ABI function without storing non-volatile XMM registers,
+   * as target function does not use vector instruction sets. */
+  asm volatile ("callq *%0\n\t"
+                : "+a" (fn),
+                  "+D" (arg1),
+                  "+S" (arg2),
+                  "+d" (arg3),
+                  "+c" (arg4)
+                :
+                : "cc", "memory", "r8", "r9", "r10", "r11");
+}
+#endif
+
 static void
 do_encrypt ( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
 {
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+  call_sysv_fn (_gcry_blowfish_amd64_do_encrypt, bc, ret_xl, ret_xr, NULL);
+#else
   _gcry_blowfish_amd64_do_encrypt (bc, ret_xl, ret_xr);
+#endif
 }
 
 static void
 do_encrypt_block (BLOWFISH_context *context, byte *outbuf, const byte *inbuf)
 {
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+  call_sysv_fn (_gcry_blowfish_amd64_encrypt_block, context, outbuf, inbuf,
+                NULL);
+#else
   _gcry_blowfish_amd64_encrypt_block (context, outbuf, inbuf);
+#endif
 }
 
 static void
 do_decrypt_block (BLOWFISH_context *context, byte *outbuf, const byte *inbuf)
 {
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+  call_sysv_fn (_gcry_blowfish_amd64_decrypt_block, context, outbuf, inbuf,
+                NULL);
+#else
   _gcry_blowfish_amd64_decrypt_block (context, outbuf, inbuf);
+#endif
+}
+
+static inline void
+blowfish_amd64_ctr_enc(BLOWFISH_context *ctx, byte *out, const byte *in,
+                       byte *ctr)
+{
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+  call_sysv_fn (_gcry_blowfish_amd64_ctr_enc, ctx, out, in, ctr);
+#else
+  _gcry_blowfish_amd64_ctr_enc(ctx, out, in, ctr);
+#endif
+}
+
+static inline void
+blowfish_amd64_cbc_dec(BLOWFISH_context *ctx, byte *out, const byte *in,
+                       byte *iv)
+{
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+  call_sysv_fn (_gcry_blowfish_amd64_cbc_dec, ctx, out, in, iv);
+#else
+  _gcry_blowfish_amd64_cbc_dec(ctx, out, in, iv);
+#endif
+}
+
+static inline void
+blowfish_amd64_cfb_dec(BLOWFISH_context *ctx, byte *out, const byte *in,
+                       byte *iv)
+{
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+  call_sysv_fn (_gcry_blowfish_amd64_cfb_dec, ctx, out, in, iv);
+#else
+  _gcry_blowfish_amd64_cfb_dec(ctx, out, in, iv);
+#endif
 }
 
 static unsigned int
@@ -605,7 +671,7 @@ _gcry_blowfish_ctr_enc(void *context, unsigned char *ctr, void *outbuf_arg,
     /* Process data in 4 block chunks. */
     while (nblocks >= 4)
       {
-        _gcry_blowfish_amd64_ctr_enc(ctx, outbuf, inbuf, ctr);
+        blowfish_amd64_ctr_enc(ctx, outbuf, inbuf, ctr);
 
         nblocks -= 4;
         outbuf += 4 * BLOWFISH_BLOCKSIZE;
@@ -674,7 +740,7 @@ _gcry_blowfish_cbc_dec(void *context, unsigned char *iv, void *outbuf_arg,
     /* Process data in 4 block chunks. */
     while (nblocks >= 4)
       {
-        _gcry_blowfish_amd64_cbc_dec(ctx, outbuf, inbuf, iv);
+        blowfish_amd64_cbc_dec(ctx, outbuf, inbuf, iv);
 
         nblocks -= 4;
         outbuf += 4 * BLOWFISH_BLOCKSIZE;
@@ -734,7 +800,7 @@ _gcry_blowfish_cfb_dec(void *context, unsigned char *iv, void *outbuf_arg,
     /* Process data in 4 block chunks. */
     while (nblocks >= 4)
       {
-        _gcry_blowfish_amd64_cfb_dec(ctx, outbuf, inbuf, iv);
+        blowfish_amd64_cfb_dec(ctx, outbuf, inbuf, iv);
 
         nblocks -= 4;
         outbuf += 4 * BLOWFISH_BLOCKSIZE;
index 45a7209..df35594 100644 (file)
@@ -1,10 +1,10 @@
 /* bufhelp.h  -  Some buffer manipulation helpers
- *     Copyright © 2012 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+ * Copyright (C) 2012 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
  *
  * This file is part of Libgcrypt.
  *
  * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser general Public License as
+ * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation; either version 2.1 of
  * the License, or (at your option) any later version.
  *
  * GNU Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef G10_BUFHELP_H
-#define G10_BUFHELP_H
+#ifndef GCRYPT_BUFHELP_H
+#define GCRYPT_BUFHELP_H
 
-#include <config.h>
-
-#ifdef HAVE_STDINT_H
-# include <stdint.h> /* uintptr_t */
-#elif defined(HAVE_INTTYPES_H)
-# include <inttypes.h>
-#else
-/* In this case, uintptr_t is provided by config.h. */
-#endif
 
 #include "bithelp.h"
 
 
-#if defined(__i386__) || defined(__x86_64__) || \
-    defined(__powerpc__) || defined(__powerpc64__) || \
-    (defined(__arm__) && defined(__ARM_FEATURE_UNALIGNED)) || \
-    defined(__aarch64__)
+#undef BUFHELP_FAST_UNALIGNED_ACCESS
+#if defined(HAVE_GCC_ATTRIBUTE_PACKED) && \
+    defined(HAVE_GCC_ATTRIBUTE_ALIGNED) && \
+    (defined(__i386__) || defined(__x86_64__) || \
+     (defined(__arm__) && defined(__ARM_FEATURE_UNALIGNED)) || \
+     defined(__aarch64__))
 /* These architectures are able of unaligned memory accesses and can
    handle those fast.
  */
 #endif
 
 
+#ifdef BUFHELP_FAST_UNALIGNED_ACCESS
+/* Define type with one-byte alignment on architectures with fast unaligned
+   memory accesses.
+ */
+typedef struct bufhelp_int_s
+{
+  uintptr_t a;
+} __attribute__((packed, aligned(1))) bufhelp_int_t;
+#else
+/* Define type with default alignment for other architectures (unaligned
+   accessed handled in per byte loops).
+ */
+typedef struct bufhelp_int_s
+{
+  uintptr_t a;
+} bufhelp_int_t;
+#endif
+
+
 /* Optimized function for small buffer copying */
 static inline void
 buf_cpy(void *_dst, const void *_src, size_t len)
@@ -54,21 +65,21 @@ buf_cpy(void *_dst, const void *_src, size_t len)
 #else
   byte *dst = _dst;
   const byte *src = _src;
-  uintptr_t *ldst;
-  const uintptr_t *lsrc;
+  bufhelp_int_t *ldst;
+  const bufhelp_int_t *lsrc;
 #ifndef BUFHELP_FAST_UNALIGNED_ACCESS
-  const unsigned int longmask = sizeof(uintptr_t) - 1;
+  const unsigned int longmask = sizeof(bufhelp_int_t) - 1;
 
   /* Skip fast processing if buffers are unaligned.  */
   if (((uintptr_t)dst | (uintptr_t)src) & longmask)
     goto do_bytes;
 #endif
 
-  ldst = (uintptr_t *)(void *)dst;
-  lsrc = (const uintptr_t *)(const void *)src;
+  ldst = (bufhelp_int_t *)(void *)dst;
+  lsrc = (const bufhelp_int_t *)(const void *)src;
 
-  for (; len >= sizeof(uintptr_t); len -= sizeof(uintptr_t))
-    *ldst++ = *lsrc++;
+  for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t))
+    (ldst++)->a = (lsrc++)->a;
 
   dst = (byte *)ldst;
   src = (const byte *)lsrc;
@@ -90,22 +101,22 @@ buf_xor(void *_dst, const void *_src1, const void *_src2, size_t len)
   byte *dst = _dst;
   const byte *src1 = _src1;
   const byte *src2 = _src2;
-  uintptr_t *ldst;
-  const uintptr_t *lsrc1, *lsrc2;
+  bufhelp_int_t *ldst;
+  const bufhelp_int_t *lsrc1, *lsrc2;
 #ifndef BUFHELP_FAST_UNALIGNED_ACCESS
-  const unsigned int longmask = sizeof(uintptr_t) - 1;
+  const unsigned int longmask = sizeof(bufhelp_int_t) - 1;
 
   /* Skip fast processing if buffers are unaligned.  */
   if (((uintptr_t)dst | (uintptr_t)src1 | (uintptr_t)src2) & longmask)
     goto do_bytes;
 #endif
 
-  ldst = (uintptr_t *)(void *)dst;
-  lsrc1 = (const uintptr_t *)(const void *)src1;
-  lsrc2 = (const uintptr_t *)(const void *)src2;
+  ldst = (bufhelp_int_t *)(void *)dst;
+  lsrc1 = (const bufhelp_int_t *)(const void *)src1;
+  lsrc2 = (const bufhelp_int_t *)(const void *)src2;
 
-  for (; len >= sizeof(uintptr_t); len -= sizeof(uintptr_t))
-    *ldst++ = *lsrc1++ ^ *lsrc2++;
+  for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t))
+    (ldst++)->a = (lsrc1++)->a ^ (lsrc2++)->a;
 
   dst = (byte *)ldst;
   src1 = (const byte *)lsrc1;
@@ -120,6 +131,40 @@ do_bytes:
 }
 
 
+/* Optimized function for in-place buffer xoring. */
+static inline void
+buf_xor_1(void *_dst, const void *_src, size_t len)
+{
+  byte *dst = _dst;
+  const byte *src = _src;
+  bufhelp_int_t *ldst;
+  const bufhelp_int_t *lsrc;
+#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
+  const unsigned int longmask = sizeof(bufhelp_int_t) - 1;
+
+  /* Skip fast processing if buffers are unaligned.  */
+  if (((uintptr_t)dst | (uintptr_t)src) & longmask)
+    goto do_bytes;
+#endif
+
+  ldst = (bufhelp_int_t *)(void *)dst;
+  lsrc = (const bufhelp_int_t *)(const void *)src;
+
+  for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t))
+    (ldst++)->a ^= (lsrc++)->a;
+
+  dst = (byte *)ldst;
+  src = (const byte *)lsrc;
+
+#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
+do_bytes:
+#endif
+  /* Handle tail.  */
+  for (; len; len--)
+    *dst++ ^= *src++;
+}
+
+
 /* Optimized function for buffer xoring with two destination buffers.  Used
    mainly by CFB mode encryption.  */
 static inline void
@@ -128,22 +173,22 @@ buf_xor_2dst(void *_dst1, void *_dst2, const void *_src, size_t len)
   byte *dst1 = _dst1;
   byte *dst2 = _dst2;
   const byte *src = _src;
-  uintptr_t *ldst1, *ldst2;
-  const uintptr_t *lsrc;
+  bufhelp_int_t *ldst1, *ldst2;
+  const bufhelp_int_t *lsrc;
 #ifndef BUFHELP_FAST_UNALIGNED_ACCESS
-  const unsigned int longmask = sizeof(uintptr_t) - 1;
+  const unsigned int longmask = sizeof(bufhelp_int_t) - 1;
 
   /* Skip fast processing if buffers are unaligned.  */
   if (((uintptr_t)src | (uintptr_t)dst1 | (uintptr_t)dst2) & longmask)
     goto do_bytes;
 #endif
 
-  ldst1 = (uintptr_t *)(void *)dst1;
-  ldst2 = (uintptr_t *)(void *)dst2;
-  lsrc = (const uintptr_t *)(const void *)src;
+  ldst1 = (bufhelp_int_t *)(void *)dst1;
+  ldst2 = (bufhelp_int_t *)(void *)dst2;
+  lsrc = (const bufhelp_int_t *)(const void *)src;
 
-  for (; len >= sizeof(uintptr_t); len -= sizeof(uintptr_t))
-    *ldst1++ = (*ldst2++ ^= *lsrc++);
+  for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t))
+    (ldst1++)->a = ((ldst2++)->a ^= (lsrc++)->a);
 
   dst1 = (byte *)ldst1;
   dst2 = (byte *)ldst2;
@@ -169,11 +214,11 @@ buf_xor_n_copy_2(void *_dst_xor, const void *_src_xor, void *_srcdst_cpy,
   const byte *src_xor = _src_xor;
   const byte *src_cpy = _src_cpy;
   byte temp;
-  uintptr_t *ldst_xor, *lsrcdst_cpy;
-  const uintptr_t *lsrc_cpy, *lsrc_xor;
+  bufhelp_int_t *ldst_xor, *lsrcdst_cpy;
+  const bufhelp_int_t *lsrc_cpy, *lsrc_xor;
   uintptr_t ltemp;
 #ifndef BUFHELP_FAST_UNALIGNED_ACCESS
-  const unsigned int longmask = sizeof(uintptr_t) - 1;
+  const unsigned int longmask = sizeof(bufhelp_int_t) - 1;
 
   /* Skip fast processing if buffers are unaligned.  */
   if (((uintptr_t)src_cpy | (uintptr_t)src_xor | (uintptr_t)dst_xor |
@@ -181,16 +226,16 @@ buf_xor_n_copy_2(void *_dst_xor, const void *_src_xor, void *_srcdst_cpy,
     goto do_bytes;
 #endif
 
-  ldst_xor = (uintptr_t *)(void *)dst_xor;
-  lsrc_xor = (const uintptr_t *)(void *)src_xor;
-  lsrcdst_cpy = (uintptr_t *)(void *)srcdst_cpy;
-  lsrc_cpy = (const uintptr_t *)(const void *)src_cpy;
+  ldst_xor = (bufhelp_int_t *)(void *)dst_xor;
+  lsrc_xor = (const bufhelp_int_t *)(void *)src_xor;
+  lsrcdst_cpy = (bufhelp_int_t *)(void *)srcdst_cpy;
+  lsrc_cpy = (const bufhelp_int_t *)(const void *)src_cpy;
 
-  for (; len >= sizeof(uintptr_t); len -= sizeof(uintptr_t))
+  for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t))
     {
-      ltemp = *lsrc_cpy++;
-      *ldst_xor++ = *lsrcdst_cpy ^ *lsrc_xor++;
-      *lsrcdst_cpy++ = ltemp;
+      ltemp = (lsrc_cpy++)->a;
+      (ldst_xor++)->a = (lsrcdst_cpy)->a ^ (lsrc_xor++)->a;
+      (lsrcdst_cpy++)->a = ltemp;
     }
 
   dst_xor = (byte *)ldst_xor;
@@ -273,7 +318,7 @@ static inline void buf_put_le32(void *_buf, u32 val)
   out[0] = val;
 }
 
-#ifdef HAVE_U64_TYPEDEF
+
 /* Functions for loading and storing unaligned u64 values of different
    endianness.  */
 static inline u64 buf_get_be64(const void *_buf)
@@ -319,60 +364,69 @@ static inline void buf_put_le64(void *_buf, u64 val)
   out[1] = val >> 8;
   out[0] = val;
 }
-#endif /*HAVE_U64_TYPEDEF*/
 
 #else /*BUFHELP_FAST_UNALIGNED_ACCESS*/
 
+typedef struct bufhelp_u32_s
+{
+  u32 a;
+} __attribute__((packed, aligned(1))) bufhelp_u32_t;
+
 /* Functions for loading and storing unaligned u32 values of different
    endianness.  */
 static inline u32 buf_get_be32(const void *_buf)
 {
-  return be_bswap32(*(const u32 *)_buf);
+  return be_bswap32(((const bufhelp_u32_t *)_buf)->a);
 }
 
 static inline u32 buf_get_le32(const void *_buf)
 {
-  return le_bswap32(*(const u32 *)_buf);
+  return le_bswap32(((const bufhelp_u32_t *)_buf)->a);
 }
 
 static inline void buf_put_be32(void *_buf, u32 val)
 {
-  u32 *out = _buf;
-  *out = be_bswap32(val);
+  bufhelp_u32_t *out = _buf;
+  out->a = be_bswap32(val);
 }
 
 static inline void buf_put_le32(void *_buf, u32 val)
 {
-  u32 *out = _buf;
-  *out = le_bswap32(val);
+  bufhelp_u32_t *out = _buf;
+  out->a = le_bswap32(val);
 }
 
-#ifdef HAVE_U64_TYPEDEF
+
+typedef struct bufhelp_u64_s
+{
+  u64 a;
+} __attribute__((packed, aligned(1))) bufhelp_u64_t;
+
 /* Functions for loading and storing unaligned u64 values of different
    endianness.  */
 static inline u64 buf_get_be64(const void *_buf)
 {
-  return be_bswap64(*(const u64 *)_buf);
+  return be_bswap64(((const bufhelp_u64_t *)_buf)->a);
 }
 
 static inline u64 buf_get_le64(const void *_buf)
 {
-  return le_bswap64(*(const u64 *)_buf);
+  return le_bswap64(((const bufhelp_u64_t *)_buf)->a);
 }
 
 static inline void buf_put_be64(void *_buf, u64 val)
 {
-  u64 *out = _buf;
-  *out = be_bswap64(val);
+  bufhelp_u64_t *out = _buf;
+  out->a = be_bswap64(val);
 }
 
 static inline void buf_put_le64(void *_buf, u64 val)
 {
-  u64 *out = _buf;
-  *out = le_bswap64(val);
+  bufhelp_u64_t *out = _buf;
+  out->a = le_bswap64(val);
 }
-#endif /*HAVE_U64_TYPEDEF*/
+
 
 #endif /*BUFHELP_FAST_UNALIGNED_ACCESS*/
 
-#endif /*G10_BITHELP_H*/
+#endif /*GCRYPT_BUFHELP_H*/
index 38ec7a3..5a3a3cb 100644 (file)
@@ -1,6 +1,6 @@
 /* camellia-avx-aesni-amd64.S  -  AES-NI/AVX implementation of Camellia cipher
  *
- * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013-2015 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
@@ -20,7 +20,8 @@
 
 #ifdef __x86_64
 #include <config.h>
-#if defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && \
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
     defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX_SUPPORT)
 
 #ifdef __PIC__
 #  define RIP
 #endif
 
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
+
 #define CAMELLIA_TABLE_BYTE_LEN 272
 
 /* struct CAMELLIA_context: */
 .text
 
 .align 8
-.type   __camellia_enc_blk16,@function;
+ELF(.type   __camellia_enc_blk16,@function;)
 
 __camellia_enc_blk16:
        /* input:
@@ -853,10 +860,10 @@ __camellia_enc_blk16:
                     %xmm15, %rax, %rcx, 24);
 
        jmp .Lenc_done;
-.size __camellia_enc_blk16,.-__camellia_enc_blk16;
+ELF(.size __camellia_enc_blk16,.-__camellia_enc_blk16;)
 
 .align 8
-.type   __camellia_dec_blk16,@function;
+ELF(.type   __camellia_dec_blk16,@function;)
 
 __camellia_dec_blk16:
        /* input:
@@ -938,7 +945,7 @@ __camellia_dec_blk16:
              ((key_table + (24) * 8) + 4)(CTX));
 
        jmp .Ldec_max24;
-.size __camellia_dec_blk16,.-__camellia_dec_blk16;
+ELF(.size __camellia_dec_blk16,.-__camellia_dec_blk16;)
 
 #define inc_le128(x, minus_one, tmp) \
        vpcmpeqq minus_one, x, tmp; \
@@ -948,7 +955,7 @@ __camellia_dec_blk16:
 
 .align 8
 .globl _gcry_camellia_aesni_avx_ctr_enc
-.type   _gcry_camellia_aesni_avx_ctr_enc,@function;
+ELF(.type   _gcry_camellia_aesni_avx_ctr_enc,@function;)
 
 _gcry_camellia_aesni_avx_ctr_enc:
        /* input:
@@ -1062,11 +1069,11 @@ _gcry_camellia_aesni_avx_ctr_enc:
 
        leave;
        ret;
-.size _gcry_camellia_aesni_avx_ctr_enc,.-_gcry_camellia_aesni_avx_ctr_enc;
+ELF(.size _gcry_camellia_aesni_avx_ctr_enc,.-_gcry_camellia_aesni_avx_ctr_enc;)
 
 .align 8
 .globl _gcry_camellia_aesni_avx_cbc_dec
-.type   _gcry_camellia_aesni_avx_cbc_dec,@function;
+ELF(.type   _gcry_camellia_aesni_avx_cbc_dec,@function;)
 
 _gcry_camellia_aesni_avx_cbc_dec:
        /* input:
@@ -1130,11 +1137,11 @@ _gcry_camellia_aesni_avx_cbc_dec:
 
        leave;
        ret;
-.size _gcry_camellia_aesni_avx_cbc_dec,.-_gcry_camellia_aesni_avx_cbc_dec;
+ELF(.size _gcry_camellia_aesni_avx_cbc_dec,.-_gcry_camellia_aesni_avx_cbc_dec;)
 
 .align 8
 .globl _gcry_camellia_aesni_avx_cfb_dec
-.type   _gcry_camellia_aesni_avx_cfb_dec,@function;
+ELF(.type   _gcry_camellia_aesni_avx_cfb_dec,@function;)
 
 _gcry_camellia_aesni_avx_cfb_dec:
        /* input:
@@ -1202,7 +1209,429 @@ _gcry_camellia_aesni_avx_cfb_dec:
 
        leave;
        ret;
-.size _gcry_camellia_aesni_avx_cfb_dec,.-_gcry_camellia_aesni_avx_cfb_dec;
+ELF(.size _gcry_camellia_aesni_avx_cfb_dec,.-_gcry_camellia_aesni_avx_cfb_dec;)
+
+.align 8
+.globl _gcry_camellia_aesni_avx_ocb_enc
+ELF(.type   _gcry_camellia_aesni_avx_ocb_enc,@function;)
+
+_gcry_camellia_aesni_avx_ocb_enc:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (16 blocks)
+        *      %rdx: src (16 blocks)
+        *      %rcx: offset
+        *      %r8 : checksum
+        *      %r9 : L pointers (void *L[16])
+        */
+
+       pushq %rbp;
+       movq %rsp, %rbp;
+
+       vzeroupper;
+
+       subq $(16 * 16 + 4 * 8), %rsp;
+       andq $~31, %rsp;
+       movq %rsp, %rax;
+
+       movq %r10, (16 * 16 + 0 * 8)(%rax);
+       movq %r11, (16 * 16 + 1 * 8)(%rax);
+       movq %r12, (16 * 16 + 2 * 8)(%rax);
+       movq %r13, (16 * 16 + 3 * 8)(%rax);
+
+       vmovdqu (%rcx), %xmm14;
+       vmovdqu (%r8), %xmm15;
+
+       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+       /* Checksum_i = Checksum_{i-1} xor P_i  */
+       /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)  */
+
+#define OCB_INPUT(n, lreg, xreg) \
+         vmovdqu (n * 16)(%rdx), xreg; \
+         vpxor (lreg), %xmm14, %xmm14; \
+         vpxor xreg, %xmm15, %xmm15; \
+         vpxor xreg, %xmm14, xreg; \
+         vmovdqu %xmm14, (n * 16)(%rsi);
+       movq (0 * 8)(%r9), %r10;
+       movq (1 * 8)(%r9), %r11;
+       movq (2 * 8)(%r9), %r12;
+       movq (3 * 8)(%r9), %r13;
+       OCB_INPUT(0, %r10, %xmm0);
+       vmovdqu %xmm0, (15 * 16)(%rax);
+       OCB_INPUT(1, %r11, %xmm0);
+       vmovdqu %xmm0, (14 * 16)(%rax);
+       OCB_INPUT(2, %r12, %xmm13);
+       OCB_INPUT(3, %r13, %xmm12);
+       movq (4 * 8)(%r9), %r10;
+       movq (5 * 8)(%r9), %r11;
+       movq (6 * 8)(%r9), %r12;
+       movq (7 * 8)(%r9), %r13;
+       OCB_INPUT(4, %r10, %xmm11);
+       OCB_INPUT(5, %r11, %xmm10);
+       OCB_INPUT(6, %r12, %xmm9);
+       OCB_INPUT(7, %r13, %xmm8);
+       movq (8 * 8)(%r9), %r10;
+       movq (9 * 8)(%r9), %r11;
+       movq (10 * 8)(%r9), %r12;
+       movq (11 * 8)(%r9), %r13;
+       OCB_INPUT(8, %r10, %xmm7);
+       OCB_INPUT(9, %r11, %xmm6);
+       OCB_INPUT(10, %r12, %xmm5);
+       OCB_INPUT(11, %r13, %xmm4);
+       movq (12 * 8)(%r9), %r10;
+       movq (13 * 8)(%r9), %r11;
+       movq (14 * 8)(%r9), %r12;
+       movq (15 * 8)(%r9), %r13;
+       OCB_INPUT(12, %r10, %xmm3);
+       OCB_INPUT(13, %r11, %xmm2);
+       OCB_INPUT(14, %r12, %xmm1);
+       OCB_INPUT(15, %r13, %xmm0);
+#undef OCB_INPUT
+
+       vmovdqu %xmm14, (%rcx);
+       vmovdqu %xmm15, (%r8);
+
+       /* inpack16_pre: */
+       vmovq (key_table)(CTX), %xmm15;
+       vpshufb .Lpack_bswap RIP, %xmm15, %xmm15;
+       vpxor %xmm0, %xmm15, %xmm0;
+       vpxor %xmm1, %xmm15, %xmm1;
+       vpxor %xmm2, %xmm15, %xmm2;
+       vpxor %xmm3, %xmm15, %xmm3;
+       vpxor %xmm4, %xmm15, %xmm4;
+       vpxor %xmm5, %xmm15, %xmm5;
+       vpxor %xmm6, %xmm15, %xmm6;
+       vpxor %xmm7, %xmm15, %xmm7;
+       vpxor %xmm8, %xmm15, %xmm8;
+       vpxor %xmm9, %xmm15, %xmm9;
+       vpxor %xmm10, %xmm15, %xmm10;
+       vpxor %xmm11, %xmm15, %xmm11;
+       vpxor %xmm12, %xmm15, %xmm12;
+       vpxor %xmm13, %xmm15, %xmm13;
+       vpxor 14 * 16(%rax), %xmm15, %xmm14;
+       vpxor 15 * 16(%rax), %xmm15, %xmm15;
+
+       call __camellia_enc_blk16;
+
+       vpxor 0 * 16(%rsi), %xmm7, %xmm7;
+       vpxor 1 * 16(%rsi), %xmm6, %xmm6;
+       vpxor 2 * 16(%rsi), %xmm5, %xmm5;
+       vpxor 3 * 16(%rsi), %xmm4, %xmm4;
+       vpxor 4 * 16(%rsi), %xmm3, %xmm3;
+       vpxor 5 * 16(%rsi), %xmm2, %xmm2;
+       vpxor 6 * 16(%rsi), %xmm1, %xmm1;
+       vpxor 7 * 16(%rsi), %xmm0, %xmm0;
+       vpxor 8 * 16(%rsi), %xmm15, %xmm15;
+       vpxor 9 * 16(%rsi), %xmm14, %xmm14;
+       vpxor 10 * 16(%rsi), %xmm13, %xmm13;
+       vpxor 11 * 16(%rsi), %xmm12, %xmm12;
+       vpxor 12 * 16(%rsi), %xmm11, %xmm11;
+       vpxor 13 * 16(%rsi), %xmm10, %xmm10;
+       vpxor 14 * 16(%rsi), %xmm9, %xmm9;
+       vpxor 15 * 16(%rsi), %xmm8, %xmm8;
+
+       write_output(%xmm7, %xmm6, %xmm5, %xmm4, %xmm3, %xmm2, %xmm1, %xmm0,
+                    %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
+                    %xmm8, %rsi);
+
+       vzeroall;
+
+       movq (16 * 16 + 0 * 8)(%rax), %r10;
+       movq (16 * 16 + 1 * 8)(%rax), %r11;
+       movq (16 * 16 + 2 * 8)(%rax), %r12;
+       movq (16 * 16 + 3 * 8)(%rax), %r13;
+
+       leave;
+       ret;
+ELF(.size _gcry_camellia_aesni_avx_ocb_enc,.-_gcry_camellia_aesni_avx_ocb_enc;)
+
+.align 8
+.globl _gcry_camellia_aesni_avx_ocb_dec
+ELF(.type   _gcry_camellia_aesni_avx_ocb_dec,@function;)
+
+_gcry_camellia_aesni_avx_ocb_dec:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (16 blocks)
+        *      %rdx: src (16 blocks)
+        *      %rcx: offset
+        *      %r8 : checksum
+        *      %r9 : L pointers (void *L[16])
+        */
+
+       pushq %rbp;
+       movq %rsp, %rbp;
+
+       vzeroupper;
+
+       subq $(16 * 16 + 4 * 8), %rsp;
+       andq $~31, %rsp;
+       movq %rsp, %rax;
+
+       movq %r10, (16 * 16 + 0 * 8)(%rax);
+       movq %r11, (16 * 16 + 1 * 8)(%rax);
+       movq %r12, (16 * 16 + 2 * 8)(%rax);
+       movq %r13, (16 * 16 + 3 * 8)(%rax);
+
+       vmovdqu (%rcx), %xmm15;
+
+       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+       /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i)  */
+
+#define OCB_INPUT(n, lreg, xreg) \
+         vmovdqu (n * 16)(%rdx), xreg; \
+         vpxor (lreg), %xmm15, %xmm15; \
+         vpxor xreg, %xmm15, xreg; \
+         vmovdqu %xmm15, (n * 16)(%rsi);
+       movq (0 * 8)(%r9), %r10;
+       movq (1 * 8)(%r9), %r11;
+       movq (2 * 8)(%r9), %r12;
+       movq (3 * 8)(%r9), %r13;
+       OCB_INPUT(0, %r10, %xmm0);
+       vmovdqu %xmm0, (15 * 16)(%rax);
+       OCB_INPUT(1, %r11, %xmm14);
+       OCB_INPUT(2, %r12, %xmm13);
+       OCB_INPUT(3, %r13, %xmm12);
+       movq (4 * 8)(%r9), %r10;
+       movq (5 * 8)(%r9), %r11;
+       movq (6 * 8)(%r9), %r12;
+       movq (7 * 8)(%r9), %r13;
+       OCB_INPUT(4, %r10, %xmm11);
+       OCB_INPUT(5, %r11, %xmm10);
+       OCB_INPUT(6, %r12, %xmm9);
+       OCB_INPUT(7, %r13, %xmm8);
+       movq (8 * 8)(%r9), %r10;
+       movq (9 * 8)(%r9), %r11;
+       movq (10 * 8)(%r9), %r12;
+       movq (11 * 8)(%r9), %r13;
+       OCB_INPUT(8, %r10, %xmm7);
+       OCB_INPUT(9, %r11, %xmm6);
+       OCB_INPUT(10, %r12, %xmm5);
+       OCB_INPUT(11, %r13, %xmm4);
+       movq (12 * 8)(%r9), %r10;
+       movq (13 * 8)(%r9), %r11;
+       movq (14 * 8)(%r9), %r12;
+       movq (15 * 8)(%r9), %r13;
+       OCB_INPUT(12, %r10, %xmm3);
+       OCB_INPUT(13, %r11, %xmm2);
+       OCB_INPUT(14, %r12, %xmm1);
+       OCB_INPUT(15, %r13, %xmm0);
+#undef OCB_INPUT
+
+       vmovdqu %xmm15, (%rcx);
+
+       movq %r8, %r10;
+
+       cmpl $128, key_bitlength(CTX);
+       movl $32, %r8d;
+       movl $24, %r9d;
+       cmovel %r9d, %r8d; /* max */
+
+       /* inpack16_pre: */
+       vmovq (key_table)(CTX, %r8, 8), %xmm15;
+       vpshufb .Lpack_bswap RIP, %xmm15, %xmm15;
+       vpxor %xmm0, %xmm15, %xmm0;
+       vpxor %xmm1, %xmm15, %xmm1;
+       vpxor %xmm2, %xmm15, %xmm2;
+       vpxor %xmm3, %xmm15, %xmm3;
+       vpxor %xmm4, %xmm15, %xmm4;
+       vpxor %xmm5, %xmm15, %xmm5;
+       vpxor %xmm6, %xmm15, %xmm6;
+       vpxor %xmm7, %xmm15, %xmm7;
+       vpxor %xmm8, %xmm15, %xmm8;
+       vpxor %xmm9, %xmm15, %xmm9;
+       vpxor %xmm10, %xmm15, %xmm10;
+       vpxor %xmm11, %xmm15, %xmm11;
+       vpxor %xmm12, %xmm15, %xmm12;
+       vpxor %xmm13, %xmm15, %xmm13;
+       vpxor %xmm14, %xmm15, %xmm14;
+       vpxor 15 * 16(%rax), %xmm15, %xmm15;
+
+       call __camellia_dec_blk16;
+
+       vpxor 0 * 16(%rsi), %xmm7, %xmm7;
+       vpxor 1 * 16(%rsi), %xmm6, %xmm6;
+       vpxor 2 * 16(%rsi), %xmm5, %xmm5;
+       vpxor 3 * 16(%rsi), %xmm4, %xmm4;
+       vpxor 4 * 16(%rsi), %xmm3, %xmm3;
+       vpxor 5 * 16(%rsi), %xmm2, %xmm2;
+       vpxor 6 * 16(%rsi), %xmm1, %xmm1;
+       vpxor 7 * 16(%rsi), %xmm0, %xmm0;
+       vmovdqu %xmm7, (7 * 16)(%rax);
+       vpxor 8 * 16(%rsi), %xmm15, %xmm15;
+       vpxor 9 * 16(%rsi), %xmm14, %xmm14;
+       vpxor 10 * 16(%rsi), %xmm13, %xmm13;
+       vpxor 11 * 16(%rsi), %xmm12, %xmm12;
+       vpxor 12 * 16(%rsi), %xmm11, %xmm11;
+       vpxor 13 * 16(%rsi), %xmm10, %xmm10;
+       vpxor 14 * 16(%rsi), %xmm9, %xmm9;
+       vpxor 15 * 16(%rsi), %xmm8, %xmm8;
+
+       /* Checksum_i = Checksum_{i-1} xor P_i  */
+
+       vpxor (%r10), %xmm7, %xmm7;
+       vpxor %xmm6, %xmm7, %xmm7;
+       vpxor %xmm5, %xmm7, %xmm7;
+       vpxor %xmm4, %xmm7, %xmm7;
+       vpxor %xmm3, %xmm7, %xmm7;
+       vpxor %xmm2, %xmm7, %xmm7;
+       vpxor %xmm1, %xmm7, %xmm7;
+       vpxor %xmm0, %xmm7, %xmm7;
+       vpxor %xmm15, %xmm7, %xmm7;
+       vpxor %xmm14, %xmm7, %xmm7;
+       vpxor %xmm13, %xmm7, %xmm7;
+       vpxor %xmm12, %xmm7, %xmm7;
+       vpxor %xmm11, %xmm7, %xmm7;
+       vpxor %xmm10, %xmm7, %xmm7;
+       vpxor %xmm9, %xmm7, %xmm7;
+       vpxor %xmm8, %xmm7, %xmm7;
+       vmovdqu %xmm7, (%r10);
+       vmovdqu (7 * 16)(%rax), %xmm7;
+
+       write_output(%xmm7, %xmm6, %xmm5, %xmm4, %xmm3, %xmm2, %xmm1, %xmm0,
+                    %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
+                    %xmm8, %rsi);
+
+       vzeroall;
+
+       movq (16 * 16 + 0 * 8)(%rax), %r10;
+       movq (16 * 16 + 1 * 8)(%rax), %r11;
+       movq (16 * 16 + 2 * 8)(%rax), %r12;
+       movq (16 * 16 + 3 * 8)(%rax), %r13;
+
+       leave;
+       ret;
+ELF(.size _gcry_camellia_aesni_avx_ocb_dec,.-_gcry_camellia_aesni_avx_ocb_dec;)
+
+.align 8
+.globl _gcry_camellia_aesni_avx_ocb_auth
+ELF(.type   _gcry_camellia_aesni_avx_ocb_auth,@function;)
+
+_gcry_camellia_aesni_avx_ocb_auth:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: abuf (16 blocks)
+        *      %rdx: offset
+        *      %rcx: checksum
+        *      %r8 : L pointers (void *L[16])
+        */
+
+       pushq %rbp;
+       movq %rsp, %rbp;
+
+       vzeroupper;
+
+       subq $(16 * 16 + 4 * 8), %rsp;
+       andq $~31, %rsp;
+       movq %rsp, %rax;
+
+       movq %r10, (16 * 16 + 0 * 8)(%rax);
+       movq %r11, (16 * 16 + 1 * 8)(%rax);
+       movq %r12, (16 * 16 + 2 * 8)(%rax);
+       movq %r13, (16 * 16 + 3 * 8)(%rax);
+
+       vmovdqu (%rdx), %xmm15;
+
+       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+       /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i)  */
+
+#define OCB_INPUT(n, lreg, xreg) \
+         vmovdqu (n * 16)(%rsi), xreg; \
+         vpxor (lreg), %xmm15, %xmm15; \
+         vpxor xreg, %xmm15, xreg;
+
+       movq (0 * 8)(%r8), %r10;
+       movq (1 * 8)(%r8), %r11;
+       movq (2 * 8)(%r8), %r12;
+       movq (3 * 8)(%r8), %r13;
+       OCB_INPUT(0, %r10, %xmm0);
+       vmovdqu %xmm0, (15 * 16)(%rax);
+       OCB_INPUT(1, %r11, %xmm14);
+       OCB_INPUT(2, %r12, %xmm13);
+       OCB_INPUT(3, %r13, %xmm12);
+       movq (4 * 8)(%r8), %r10;
+       movq (5 * 8)(%r8), %r11;
+       movq (6 * 8)(%r8), %r12;
+       movq (7 * 8)(%r8), %r13;
+       OCB_INPUT(4, %r10, %xmm11);
+       OCB_INPUT(5, %r11, %xmm10);
+       OCB_INPUT(6, %r12, %xmm9);
+       OCB_INPUT(7, %r13, %xmm8);
+       movq (8 * 8)(%r8), %r10;
+       movq (9 * 8)(%r8), %r11;
+       movq (10 * 8)(%r8), %r12;
+       movq (11 * 8)(%r8), %r13;
+       OCB_INPUT(8, %r10, %xmm7);
+       OCB_INPUT(9, %r11, %xmm6);
+       OCB_INPUT(10, %r12, %xmm5);
+       OCB_INPUT(11, %r13, %xmm4);
+       movq (12 * 8)(%r8), %r10;
+       movq (13 * 8)(%r8), %r11;
+       movq (14 * 8)(%r8), %r12;
+       movq (15 * 8)(%r8), %r13;
+       OCB_INPUT(12, %r10, %xmm3);
+       OCB_INPUT(13, %r11, %xmm2);
+       OCB_INPUT(14, %r12, %xmm1);
+       OCB_INPUT(15, %r13, %xmm0);
+#undef OCB_INPUT
+
+       vmovdqu %xmm15, (%rdx);
+
+       movq %rcx, %r10;
+
+       /* inpack16_pre: */
+       vmovq (key_table)(CTX), %xmm15;
+       vpshufb .Lpack_bswap RIP, %xmm15, %xmm15;
+       vpxor %xmm0, %xmm15, %xmm0;
+       vpxor %xmm1, %xmm15, %xmm1;
+       vpxor %xmm2, %xmm15, %xmm2;
+       vpxor %xmm3, %xmm15, %xmm3;
+       vpxor %xmm4, %xmm15, %xmm4;
+       vpxor %xmm5, %xmm15, %xmm5;
+       vpxor %xmm6, %xmm15, %xmm6;
+       vpxor %xmm7, %xmm15, %xmm7;
+       vpxor %xmm8, %xmm15, %xmm8;
+       vpxor %xmm9, %xmm15, %xmm9;
+       vpxor %xmm10, %xmm15, %xmm10;
+       vpxor %xmm11, %xmm15, %xmm11;
+       vpxor %xmm12, %xmm15, %xmm12;
+       vpxor %xmm13, %xmm15, %xmm13;
+       vpxor %xmm14, %xmm15, %xmm14;
+       vpxor 15 * 16(%rax), %xmm15, %xmm15;
+
+       call __camellia_enc_blk16;
+
+       vpxor %xmm7, %xmm6, %xmm6;
+       vpxor %xmm5, %xmm4, %xmm4;
+       vpxor %xmm3, %xmm2, %xmm2;
+       vpxor %xmm1, %xmm0, %xmm0;
+       vpxor %xmm15, %xmm14, %xmm14;
+       vpxor %xmm13, %xmm12, %xmm12;
+       vpxor %xmm11, %xmm10, %xmm10;
+       vpxor %xmm9, %xmm8, %xmm8;
+
+       vpxor %xmm6, %xmm4, %xmm4;
+       vpxor %xmm2, %xmm0, %xmm0;
+       vpxor %xmm14, %xmm12, %xmm12;
+       vpxor %xmm10, %xmm8, %xmm8;
+
+       vpxor %xmm4, %xmm0, %xmm0;
+       vpxor %xmm12, %xmm8, %xmm8;
+
+       vpxor %xmm0, %xmm8, %xmm0;
+       vpxor (%r10), %xmm0, %xmm0;
+       vmovdqu %xmm0, (%r10);
+
+       vzeroall;
+
+       movq (16 * 16 + 0 * 8)(%rax), %r10;
+       movq (16 * 16 + 1 * 8)(%rax), %r11;
+       movq (16 * 16 + 2 * 8)(%rax), %r12;
+       movq (16 * 16 + 3 * 8)(%rax), %r13;
+
+       leave;
+       ret;
+ELF(.size _gcry_camellia_aesni_avx_ocb_auth,.-_gcry_camellia_aesni_avx_ocb_auth;)
 
 /*
  * IN:
@@ -1309,7 +1738,7 @@ _gcry_camellia_aesni_avx_cfb_dec:
 .text
 
 .align 8
-.type  __camellia_avx_setup128,@function;
+ELF(.type  __camellia_avx_setup128,@function;)
 __camellia_avx_setup128:
        /* input:
         *      %rdi: ctx, CTX; subkey storage at key_table(CTX)
@@ -1650,10 +2079,10 @@ __camellia_avx_setup128:
        vzeroall;
 
        ret;
-.size __camellia_avx_setup128,.-__camellia_avx_setup128;
+ELF(.size __camellia_avx_setup128,.-__camellia_avx_setup128;)
 
 .align 8
-.type  __camellia_avx_setup256,@function;
+ELF(.type  __camellia_avx_setup256,@function;)
 
 __camellia_avx_setup256:
        /* input:
@@ -2127,11 +2556,11 @@ __camellia_avx_setup256:
        vzeroall;
 
        ret;
-.size __camellia_avx_setup256,.-__camellia_avx_setup256;
+ELF(.size __camellia_avx_setup256,.-__camellia_avx_setup256;)
 
 .align 8
 .globl _gcry_camellia_aesni_avx_keygen
-.type  _gcry_camellia_aesni_avx_keygen,@function;
+ELF(.type  _gcry_camellia_aesni_avx_keygen,@function;)
 
 _gcry_camellia_aesni_avx_keygen:
        /* input:
@@ -2159,7 +2588,7 @@ _gcry_camellia_aesni_avx_keygen:
        vpor %xmm2, %xmm1, %xmm1;
 
        jmp __camellia_avx_setup256;
-.size _gcry_camellia_aesni_avx_keygen,.-_gcry_camellia_aesni_avx_keygen;
+ELF(.size _gcry_camellia_aesni_avx_keygen,.-_gcry_camellia_aesni_avx_keygen;)
 
 #endif /*defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX_SUPPORT)*/
 #endif /*__x86_64*/
index 1a89ff4..26381df 100644 (file)
@@ -1,6 +1,6 @@
 /* camellia-avx2-aesni-amd64.S  -  AES-NI/AVX2 implementation of Camellia cipher
  *
- * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013-2015 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
@@ -20,7 +20,8 @@
 
 #ifdef __x86_64
 #include <config.h>
-#if defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && \
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
     defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX2_SUPPORT)
 
 #ifdef __PIC__
 #  define RIP
 #endif
 
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
+
 #define CAMELLIA_TABLE_BYTE_LEN 272
 
 /* struct CAMELLIA_context: */
 .text
 
 .align 8
-.type   __camellia_enc_blk32,@function;
+ELF(.type   __camellia_enc_blk32,@function;)
 
 __camellia_enc_blk32:
        /* input:
@@ -832,10 +839,10 @@ __camellia_enc_blk32:
                     %ymm15, %rax, %rcx, 24);
 
        jmp .Lenc_done;
-.size __camellia_enc_blk32,.-__camellia_enc_blk32;
+ELF(.size __camellia_enc_blk32,.-__camellia_enc_blk32;)
 
 .align 8
-.type   __camellia_dec_blk32,@function;
+ELF(.type   __camellia_dec_blk32,@function;)
 
 __camellia_dec_blk32:
        /* input:
@@ -917,7 +924,7 @@ __camellia_dec_blk32:
              ((key_table + (24) * 8) + 4)(CTX));
 
        jmp .Ldec_max24;
-.size __camellia_dec_blk32,.-__camellia_dec_blk32;
+ELF(.size __camellia_dec_blk32,.-__camellia_dec_blk32;)
 
 #define inc_le128(x, minus_one, tmp) \
        vpcmpeqq minus_one, x, tmp; \
@@ -927,7 +934,7 @@ __camellia_dec_blk32:
 
 .align 8
 .globl _gcry_camellia_aesni_avx2_ctr_enc
-.type   _gcry_camellia_aesni_avx2_ctr_enc,@function;
+ELF(.type   _gcry_camellia_aesni_avx2_ctr_enc,@function;)
 
 _gcry_camellia_aesni_avx2_ctr_enc:
        /* input:
@@ -1111,17 +1118,17 @@ _gcry_camellia_aesni_avx2_ctr_enc:
 
        leave;
        ret;
-.size _gcry_camellia_aesni_avx2_ctr_enc,.-_gcry_camellia_aesni_avx2_ctr_enc;
+ELF(.size _gcry_camellia_aesni_avx2_ctr_enc,.-_gcry_camellia_aesni_avx2_ctr_enc;)
 
 .align 8
 .globl _gcry_camellia_aesni_avx2_cbc_dec
-.type   _gcry_camellia_aesni_avx2_cbc_dec,@function;
+ELF(.type   _gcry_camellia_aesni_avx2_cbc_dec,@function;)
 
 _gcry_camellia_aesni_avx2_cbc_dec:
        /* input:
         *      %rdi: ctx, CTX
-        *      %rsi: dst (16 blocks)
-        *      %rdx: src (16 blocks)
+        *      %rsi: dst (32 blocks)
+        *      %rdx: src (32 blocks)
         *      %rcx: iv
         */
 
@@ -1183,17 +1190,17 @@ _gcry_camellia_aesni_avx2_cbc_dec:
 
        leave;
        ret;
-.size _gcry_camellia_aesni_avx2_cbc_dec,.-_gcry_camellia_aesni_avx2_cbc_dec;
+ELF(.size _gcry_camellia_aesni_avx2_cbc_dec,.-_gcry_camellia_aesni_avx2_cbc_dec;)
 
 .align 8
 .globl _gcry_camellia_aesni_avx2_cfb_dec
-.type   _gcry_camellia_aesni_avx2_cfb_dec,@function;
+ELF(.type   _gcry_camellia_aesni_avx2_cfb_dec,@function;)
 
 _gcry_camellia_aesni_avx2_cfb_dec:
        /* input:
         *      %rdi: ctx, CTX
-        *      %rsi: dst (16 blocks)
-        *      %rdx: src (16 blocks)
+        *      %rsi: dst (32 blocks)
+        *      %rdx: src (32 blocks)
         *      %rcx: iv
         */
 
@@ -1257,7 +1264,500 @@ _gcry_camellia_aesni_avx2_cfb_dec:
 
        leave;
        ret;
-.size _gcry_camellia_aesni_avx2_cfb_dec,.-_gcry_camellia_aesni_avx2_cfb_dec;
+ELF(.size _gcry_camellia_aesni_avx2_cfb_dec,.-_gcry_camellia_aesni_avx2_cfb_dec;)
+
+.align 8
+.globl _gcry_camellia_aesni_avx2_ocb_enc
+ELF(.type   _gcry_camellia_aesni_avx2_ocb_enc,@function;)
+
+_gcry_camellia_aesni_avx2_ocb_enc:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (32 blocks)
+        *      %rdx: src (32 blocks)
+        *      %rcx: offset
+        *      %r8 : checksum
+        *      %r9 : L pointers (void *L[32])
+        */
+
+       pushq %rbp;
+       movq %rsp, %rbp;
+
+       vzeroupper;
+
+       subq $(16 * 32 + 4 * 8), %rsp;
+       andq $~63, %rsp;
+       movq %rsp, %rax;
+
+       movq %r10, (16 * 32 + 0 * 8)(%rax);
+       movq %r11, (16 * 32 + 1 * 8)(%rax);
+       movq %r12, (16 * 32 + 2 * 8)(%rax);
+       movq %r13, (16 * 32 + 3 * 8)(%rax);
+
+       vmovdqu (%rcx), %xmm14;
+       vmovdqu (%r8), %xmm13;
+
+       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+       /* Checksum_i = Checksum_{i-1} xor P_i  */
+       /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)  */
+
+#define OCB_INPUT(n, l0reg, l1reg, yreg) \
+         vmovdqu (n * 32)(%rdx), yreg; \
+         vpxor (l0reg), %xmm14, %xmm15; \
+         vpxor (l1reg), %xmm15, %xmm14; \
+         vinserti128 $1, %xmm14, %ymm15, %ymm15; \
+         vpxor yreg, %ymm13, %ymm13; \
+         vpxor yreg, %ymm15, yreg; \
+         vmovdqu %ymm15, (n * 32)(%rsi);
+
+       movq (0 * 8)(%r9), %r10;
+       movq (1 * 8)(%r9), %r11;
+       movq (2 * 8)(%r9), %r12;
+       movq (3 * 8)(%r9), %r13;
+       OCB_INPUT(0, %r10, %r11, %ymm0);
+       vmovdqu %ymm0, (15 * 32)(%rax);
+       OCB_INPUT(1, %r12, %r13, %ymm0);
+       vmovdqu %ymm0, (14 * 32)(%rax);
+       movq (4 * 8)(%r9), %r10;
+       movq (5 * 8)(%r9), %r11;
+       movq (6 * 8)(%r9), %r12;
+       movq (7 * 8)(%r9), %r13;
+       OCB_INPUT(2, %r10, %r11, %ymm0);
+       vmovdqu %ymm0, (13 * 32)(%rax);
+       OCB_INPUT(3, %r12, %r13, %ymm12);
+       movq (8 * 8)(%r9), %r10;
+       movq (9 * 8)(%r9), %r11;
+       movq (10 * 8)(%r9), %r12;
+       movq (11 * 8)(%r9), %r13;
+       OCB_INPUT(4, %r10, %r11, %ymm11);
+       OCB_INPUT(5, %r12, %r13, %ymm10);
+       movq (12 * 8)(%r9), %r10;
+       movq (13 * 8)(%r9), %r11;
+       movq (14 * 8)(%r9), %r12;
+       movq (15 * 8)(%r9), %r13;
+       OCB_INPUT(6, %r10, %r11, %ymm9);
+       OCB_INPUT(7, %r12, %r13, %ymm8);
+       movq (16 * 8)(%r9), %r10;
+       movq (17 * 8)(%r9), %r11;
+       movq (18 * 8)(%r9), %r12;
+       movq (19 * 8)(%r9), %r13;
+       OCB_INPUT(8, %r10, %r11, %ymm7);
+       OCB_INPUT(9, %r12, %r13, %ymm6);
+       movq (20 * 8)(%r9), %r10;
+       movq (21 * 8)(%r9), %r11;
+       movq (22 * 8)(%r9), %r12;
+       movq (23 * 8)(%r9), %r13;
+       OCB_INPUT(10, %r10, %r11, %ymm5);
+       OCB_INPUT(11, %r12, %r13, %ymm4);
+       movq (24 * 8)(%r9), %r10;
+       movq (25 * 8)(%r9), %r11;
+       movq (26 * 8)(%r9), %r12;
+       movq (27 * 8)(%r9), %r13;
+       OCB_INPUT(12, %r10, %r11, %ymm3);
+       OCB_INPUT(13, %r12, %r13, %ymm2);
+       movq (28 * 8)(%r9), %r10;
+       movq (29 * 8)(%r9), %r11;
+       movq (30 * 8)(%r9), %r12;
+       movq (31 * 8)(%r9), %r13;
+       OCB_INPUT(14, %r10, %r11, %ymm1);
+       OCB_INPUT(15, %r12, %r13, %ymm0);
+#undef OCB_INPUT
+
+       vextracti128 $1, %ymm13, %xmm15;
+       vmovdqu %xmm14, (%rcx);
+       vpxor %xmm13, %xmm15, %xmm15;
+       vmovdqu %xmm15, (%r8);
+
+       /* inpack16_pre: */
+       vpbroadcastq (key_table)(CTX), %ymm15;
+       vpshufb .Lpack_bswap RIP, %ymm15, %ymm15;
+       vpxor %ymm0, %ymm15, %ymm0;
+       vpxor %ymm1, %ymm15, %ymm1;
+       vpxor %ymm2, %ymm15, %ymm2;
+       vpxor %ymm3, %ymm15, %ymm3;
+       vpxor %ymm4, %ymm15, %ymm4;
+       vpxor %ymm5, %ymm15, %ymm5;
+       vpxor %ymm6, %ymm15, %ymm6;
+       vpxor %ymm7, %ymm15, %ymm7;
+       vpxor %ymm8, %ymm15, %ymm8;
+       vpxor %ymm9, %ymm15, %ymm9;
+       vpxor %ymm10, %ymm15, %ymm10;
+       vpxor %ymm11, %ymm15, %ymm11;
+       vpxor %ymm12, %ymm15, %ymm12;
+       vpxor 13 * 32(%rax), %ymm15, %ymm13;
+       vpxor 14 * 32(%rax), %ymm15, %ymm14;
+       vpxor 15 * 32(%rax), %ymm15, %ymm15;
+
+       call __camellia_enc_blk32;
+
+       vpxor 0 * 32(%rsi), %ymm7, %ymm7;
+       vpxor 1 * 32(%rsi), %ymm6, %ymm6;
+       vpxor 2 * 32(%rsi), %ymm5, %ymm5;
+       vpxor 3 * 32(%rsi), %ymm4, %ymm4;
+       vpxor 4 * 32(%rsi), %ymm3, %ymm3;
+       vpxor 5 * 32(%rsi), %ymm2, %ymm2;
+       vpxor 6 * 32(%rsi), %ymm1, %ymm1;
+       vpxor 7 * 32(%rsi), %ymm0, %ymm0;
+       vpxor 8 * 32(%rsi), %ymm15, %ymm15;
+       vpxor 9 * 32(%rsi), %ymm14, %ymm14;
+       vpxor 10 * 32(%rsi), %ymm13, %ymm13;
+       vpxor 11 * 32(%rsi), %ymm12, %ymm12;
+       vpxor 12 * 32(%rsi), %ymm11, %ymm11;
+       vpxor 13 * 32(%rsi), %ymm10, %ymm10;
+       vpxor 14 * 32(%rsi), %ymm9, %ymm9;
+       vpxor 15 * 32(%rsi), %ymm8, %ymm8;
+
+       write_output(%ymm7, %ymm6, %ymm5, %ymm4, %ymm3, %ymm2, %ymm1, %ymm0,
+                    %ymm15, %ymm14, %ymm13, %ymm12, %ymm11, %ymm10, %ymm9,
+                    %ymm8, %rsi);
+
+       vzeroall;
+
+       movq (16 * 32 + 0 * 8)(%rax), %r10;
+       movq (16 * 32 + 1 * 8)(%rax), %r11;
+       movq (16 * 32 + 2 * 8)(%rax), %r12;
+       movq (16 * 32 + 3 * 8)(%rax), %r13;
+
+       leave;
+       ret;
+ELF(.size _gcry_camellia_aesni_avx2_ocb_enc,.-_gcry_camellia_aesni_avx2_ocb_enc;)
+
+.align 8
+.globl _gcry_camellia_aesni_avx2_ocb_dec
+ELF(.type   _gcry_camellia_aesni_avx2_ocb_dec,@function;)
+
+_gcry_camellia_aesni_avx2_ocb_dec:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (32 blocks)
+        *      %rdx: src (32 blocks)
+        *      %rcx: offset
+        *      %r8 : checksum
+        *      %r9 : L pointers (void *L[32])
+        */
+
+       pushq %rbp;
+       movq %rsp, %rbp;
+
+       vzeroupper;
+
+       subq $(16 * 32 + 4 * 8), %rsp;
+       andq $~63, %rsp;
+       movq %rsp, %rax;
+
+       movq %r10, (16 * 32 + 0 * 8)(%rax);
+       movq %r11, (16 * 32 + 1 * 8)(%rax);
+       movq %r12, (16 * 32 + 2 * 8)(%rax);
+       movq %r13, (16 * 32 + 3 * 8)(%rax);
+
+       vmovdqu (%rcx), %xmm14;
+
+       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+       /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i)  */
+
+#define OCB_INPUT(n, l0reg, l1reg, yreg) \
+         vmovdqu (n * 32)(%rdx), yreg; \
+         vpxor (l0reg), %xmm14, %xmm15; \
+         vpxor (l1reg), %xmm15, %xmm14; \
+         vinserti128 $1, %xmm14, %ymm15, %ymm15; \
+         vpxor yreg, %ymm15, yreg; \
+         vmovdqu %ymm15, (n * 32)(%rsi);
+
+       movq (0 * 8)(%r9), %r10;
+       movq (1 * 8)(%r9), %r11;
+       movq (2 * 8)(%r9), %r12;
+       movq (3 * 8)(%r9), %r13;
+       OCB_INPUT(0, %r10, %r11, %ymm0);
+       vmovdqu %ymm0, (15 * 32)(%rax);
+       OCB_INPUT(1, %r12, %r13, %ymm0);
+       vmovdqu %ymm0, (14 * 32)(%rax);
+       movq (4 * 8)(%r9), %r10;
+       movq (5 * 8)(%r9), %r11;
+       movq (6 * 8)(%r9), %r12;
+       movq (7 * 8)(%r9), %r13;
+       OCB_INPUT(2, %r10, %r11, %ymm13);
+       OCB_INPUT(3, %r12, %r13, %ymm12);
+       movq (8 * 8)(%r9), %r10;
+       movq (9 * 8)(%r9), %r11;
+       movq (10 * 8)(%r9), %r12;
+       movq (11 * 8)(%r9), %r13;
+       OCB_INPUT(4, %r10, %r11, %ymm11);
+       OCB_INPUT(5, %r12, %r13, %ymm10);
+       movq (12 * 8)(%r9), %r10;
+       movq (13 * 8)(%r9), %r11;
+       movq (14 * 8)(%r9), %r12;
+       movq (15 * 8)(%r9), %r13;
+       OCB_INPUT(6, %r10, %r11, %ymm9);
+       OCB_INPUT(7, %r12, %r13, %ymm8);
+       movq (16 * 8)(%r9), %r10;
+       movq (17 * 8)(%r9), %r11;
+       movq (18 * 8)(%r9), %r12;
+       movq (19 * 8)(%r9), %r13;
+       OCB_INPUT(8, %r10, %r11, %ymm7);
+       OCB_INPUT(9, %r12, %r13, %ymm6);
+       movq (20 * 8)(%r9), %r10;
+       movq (21 * 8)(%r9), %r11;
+       movq (22 * 8)(%r9), %r12;
+       movq (23 * 8)(%r9), %r13;
+       OCB_INPUT(10, %r10, %r11, %ymm5);
+       OCB_INPUT(11, %r12, %r13, %ymm4);
+       movq (24 * 8)(%r9), %r10;
+       movq (25 * 8)(%r9), %r11;
+       movq (26 * 8)(%r9), %r12;
+       movq (27 * 8)(%r9), %r13;
+       OCB_INPUT(12, %r10, %r11, %ymm3);
+       OCB_INPUT(13, %r12, %r13, %ymm2);
+       movq (28 * 8)(%r9), %r10;
+       movq (29 * 8)(%r9), %r11;
+       movq (30 * 8)(%r9), %r12;
+       movq (31 * 8)(%r9), %r13;
+       OCB_INPUT(14, %r10, %r11, %ymm1);
+       OCB_INPUT(15, %r12, %r13, %ymm0);
+#undef OCB_INPUT
+
+       vmovdqu %xmm14, (%rcx);
+
+       movq %r8, %r10;
+
+       cmpl $128, key_bitlength(CTX);
+       movl $32, %r8d;
+       movl $24, %r9d;
+       cmovel %r9d, %r8d; /* max */
+
+       /* inpack16_pre: */
+       vpbroadcastq (key_table)(CTX, %r8, 8), %ymm15;
+       vpshufb .Lpack_bswap RIP, %ymm15, %ymm15;
+       vpxor %ymm0, %ymm15, %ymm0;
+       vpxor %ymm1, %ymm15, %ymm1;
+       vpxor %ymm2, %ymm15, %ymm2;
+       vpxor %ymm3, %ymm15, %ymm3;
+       vpxor %ymm4, %ymm15, %ymm4;
+       vpxor %ymm5, %ymm15, %ymm5;
+       vpxor %ymm6, %ymm15, %ymm6;
+       vpxor %ymm7, %ymm15, %ymm7;
+       vpxor %ymm8, %ymm15, %ymm8;
+       vpxor %ymm9, %ymm15, %ymm9;
+       vpxor %ymm10, %ymm15, %ymm10;
+       vpxor %ymm11, %ymm15, %ymm11;
+       vpxor %ymm12, %ymm15, %ymm12;
+       vpxor %ymm13, %ymm15, %ymm13;
+       vpxor 14 * 32(%rax), %ymm15, %ymm14;
+       vpxor 15 * 32(%rax), %ymm15, %ymm15;
+
+       call __camellia_dec_blk32;
+
+       vpxor 0 * 32(%rsi), %ymm7, %ymm7;
+       vpxor 1 * 32(%rsi), %ymm6, %ymm6;
+       vpxor 2 * 32(%rsi), %ymm5, %ymm5;
+       vpxor 3 * 32(%rsi), %ymm4, %ymm4;
+       vpxor 4 * 32(%rsi), %ymm3, %ymm3;
+       vpxor 5 * 32(%rsi), %ymm2, %ymm2;
+       vpxor 6 * 32(%rsi), %ymm1, %ymm1;
+       vpxor 7 * 32(%rsi), %ymm0, %ymm0;
+       vmovdqu %ymm7, (7 * 32)(%rax);
+       vmovdqu %ymm6, (6 * 32)(%rax);
+       vpxor 8 * 32(%rsi), %ymm15, %ymm15;
+       vpxor 9 * 32(%rsi), %ymm14, %ymm14;
+       vpxor 10 * 32(%rsi), %ymm13, %ymm13;
+       vpxor 11 * 32(%rsi), %ymm12, %ymm12;
+       vpxor 12 * 32(%rsi), %ymm11, %ymm11;
+       vpxor 13 * 32(%rsi), %ymm10, %ymm10;
+       vpxor 14 * 32(%rsi), %ymm9, %ymm9;
+       vpxor 15 * 32(%rsi), %ymm8, %ymm8;
+
+       /* Checksum_i = Checksum_{i-1} xor P_i  */
+
+       vpxor %ymm5, %ymm7, %ymm7;
+       vpxor %ymm4, %ymm6, %ymm6;
+       vpxor %ymm3, %ymm7, %ymm7;
+       vpxor %ymm2, %ymm6, %ymm6;
+       vpxor %ymm1, %ymm7, %ymm7;
+       vpxor %ymm0, %ymm6, %ymm6;
+       vpxor %ymm15, %ymm7, %ymm7;
+       vpxor %ymm14, %ymm6, %ymm6;
+       vpxor %ymm13, %ymm7, %ymm7;
+       vpxor %ymm12, %ymm6, %ymm6;
+       vpxor %ymm11, %ymm7, %ymm7;
+       vpxor %ymm10, %ymm6, %ymm6;
+       vpxor %ymm9, %ymm7, %ymm7;
+       vpxor %ymm8, %ymm6, %ymm6;
+       vpxor %ymm7, %ymm6, %ymm7;
+
+       vextracti128 $1, %ymm7, %xmm6;
+       vpxor %xmm6, %xmm7, %xmm7;
+       vpxor (%r10), %xmm7, %xmm7;
+       vmovdqu %xmm7, (%r10);
+
+       vmovdqu 7 * 32(%rax), %ymm7;
+       vmovdqu 6 * 32(%rax), %ymm6;
+
+       write_output(%ymm7, %ymm6, %ymm5, %ymm4, %ymm3, %ymm2, %ymm1, %ymm0,
+                    %ymm15, %ymm14, %ymm13, %ymm12, %ymm11, %ymm10, %ymm9,
+                    %ymm8, %rsi);
+
+       vzeroall;
+
+       movq (16 * 32 + 0 * 8)(%rax), %r10;
+       movq (16 * 32 + 1 * 8)(%rax), %r11;
+       movq (16 * 32 + 2 * 8)(%rax), %r12;
+       movq (16 * 32 + 3 * 8)(%rax), %r13;
+
+       leave;
+       ret;
+ELF(.size _gcry_camellia_aesni_avx2_ocb_dec,.-_gcry_camellia_aesni_avx2_ocb_dec;)
+
+.align 8
+.globl _gcry_camellia_aesni_avx2_ocb_auth
+ELF(.type   _gcry_camellia_aesni_avx2_ocb_auth,@function;)
+
+_gcry_camellia_aesni_avx2_ocb_auth:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: abuf (16 blocks)
+        *      %rdx: offset
+        *      %rcx: checksum
+        *      %r8 : L pointers (void *L[16])
+        */
+
+       pushq %rbp;
+       movq %rsp, %rbp;
+
+       vzeroupper;
+
+       subq $(16 * 32 + 4 * 8), %rsp;
+       andq $~63, %rsp;
+       movq %rsp, %rax;
+
+       movq %r10, (16 * 32 + 0 * 8)(%rax);
+       movq %r11, (16 * 32 + 1 * 8)(%rax);
+       movq %r12, (16 * 32 + 2 * 8)(%rax);
+       movq %r13, (16 * 32 + 3 * 8)(%rax);
+
+       vmovdqu (%rdx), %xmm14;
+
+       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+       /* Checksum_i = Checksum_{i-1} xor P_i  */
+       /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)  */
+
+#define OCB_INPUT(n, l0reg, l1reg, yreg) \
+         vmovdqu (n * 32)(%rsi), yreg; \
+         vpxor (l0reg), %xmm14, %xmm15; \
+         vpxor (l1reg), %xmm15, %xmm14; \
+         vinserti128 $1, %xmm14, %ymm15, %ymm15; \
+         vpxor yreg, %ymm15, yreg;
+
+       movq (0 * 8)(%r8), %r10;
+       movq (1 * 8)(%r8), %r11;
+       movq (2 * 8)(%r8), %r12;
+       movq (3 * 8)(%r8), %r13;
+       OCB_INPUT(0, %r10, %r11, %ymm0);
+       vmovdqu %ymm0, (15 * 32)(%rax);
+       OCB_INPUT(1, %r12, %r13, %ymm0);
+       vmovdqu %ymm0, (14 * 32)(%rax);
+       movq (4 * 8)(%r8), %r10;
+       movq (5 * 8)(%r8), %r11;
+       movq (6 * 8)(%r8), %r12;
+       movq (7 * 8)(%r8), %r13;
+       OCB_INPUT(2, %r10, %r11, %ymm13);
+       OCB_INPUT(3, %r12, %r13, %ymm12);
+       movq (8 * 8)(%r8), %r10;
+       movq (9 * 8)(%r8), %r11;
+       movq (10 * 8)(%r8), %r12;
+       movq (11 * 8)(%r8), %r13;
+       OCB_INPUT(4, %r10, %r11, %ymm11);
+       OCB_INPUT(5, %r12, %r13, %ymm10);
+       movq (12 * 8)(%r8), %r10;
+       movq (13 * 8)(%r8), %r11;
+       movq (14 * 8)(%r8), %r12;
+       movq (15 * 8)(%r8), %r13;
+       OCB_INPUT(6, %r10, %r11, %ymm9);
+       OCB_INPUT(7, %r12, %r13, %ymm8);
+       movq (16 * 8)(%r8), %r10;
+       movq (17 * 8)(%r8), %r11;
+       movq (18 * 8)(%r8), %r12;
+       movq (19 * 8)(%r8), %r13;
+       OCB_INPUT(8, %r10, %r11, %ymm7);
+       OCB_INPUT(9, %r12, %r13, %ymm6);
+       movq (20 * 8)(%r8), %r10;
+       movq (21 * 8)(%r8), %r11;
+       movq (22 * 8)(%r8), %r12;
+       movq (23 * 8)(%r8), %r13;
+       OCB_INPUT(10, %r10, %r11, %ymm5);
+       OCB_INPUT(11, %r12, %r13, %ymm4);
+       movq (24 * 8)(%r8), %r10;
+       movq (25 * 8)(%r8), %r11;
+       movq (26 * 8)(%r8), %r12;
+       movq (27 * 8)(%r8), %r13;
+       OCB_INPUT(12, %r10, %r11, %ymm3);
+       OCB_INPUT(13, %r12, %r13, %ymm2);
+       movq (28 * 8)(%r8), %r10;
+       movq (29 * 8)(%r8), %r11;
+       movq (30 * 8)(%r8), %r12;
+       movq (31 * 8)(%r8), %r13;
+       OCB_INPUT(14, %r10, %r11, %ymm1);
+       OCB_INPUT(15, %r12, %r13, %ymm0);
+#undef OCB_INPUT
+
+       vmovdqu %xmm14, (%rdx);
+
+       movq %rcx, %r10;
+
+       /* inpack16_pre: */
+       vpbroadcastq (key_table)(CTX), %ymm15;
+       vpshufb .Lpack_bswap RIP, %ymm15, %ymm15;
+       vpxor %ymm0, %ymm15, %ymm0;
+       vpxor %ymm1, %ymm15, %ymm1;
+       vpxor %ymm2, %ymm15, %ymm2;
+       vpxor %ymm3, %ymm15, %ymm3;
+       vpxor %ymm4, %ymm15, %ymm4;
+       vpxor %ymm5, %ymm15, %ymm5;
+       vpxor %ymm6, %ymm15, %ymm6;
+       vpxor %ymm7, %ymm15, %ymm7;
+       vpxor %ymm8, %ymm15, %ymm8;
+       vpxor %ymm9, %ymm15, %ymm9;
+       vpxor %ymm10, %ymm15, %ymm10;
+       vpxor %ymm11, %ymm15, %ymm11;
+       vpxor %ymm12, %ymm15, %ymm12;
+       vpxor %ymm13, %ymm15, %ymm13;
+       vpxor 14 * 32(%rax), %ymm15, %ymm14;
+       vpxor 15 * 32(%rax), %ymm15, %ymm15;
+
+       call __camellia_enc_blk32;
+
+       vpxor %ymm7, %ymm6, %ymm6;
+       vpxor %ymm5, %ymm4, %ymm4;
+       vpxor %ymm3, %ymm2, %ymm2;
+       vpxor %ymm1, %ymm0, %ymm0;
+       vpxor %ymm15, %ymm14, %ymm14;
+       vpxor %ymm13, %ymm12, %ymm12;
+       vpxor %ymm11, %ymm10, %ymm10;
+       vpxor %ymm9, %ymm8, %ymm8;
+
+       vpxor %ymm6, %ymm4, %ymm4;
+       vpxor %ymm2, %ymm0, %ymm0;
+       vpxor %ymm14, %ymm12, %ymm12;
+       vpxor %ymm10, %ymm8, %ymm8;
+
+       vpxor %ymm4, %ymm0, %ymm0;
+       vpxor %ymm12, %ymm8, %ymm8;
+
+       vpxor %ymm0, %ymm8, %ymm0;
+
+       vextracti128 $1, %ymm0, %xmm1;
+       vpxor (%r10), %xmm0, %xmm0;
+       vpxor %xmm0, %xmm1, %xmm0;
+       vmovdqu %xmm0, (%r10);
+
+       vzeroall;
+
+       movq (16 * 32 + 0 * 8)(%rax), %r10;
+       movq (16 * 32 + 1 * 8)(%rax), %r11;
+       movq (16 * 32 + 2 * 8)(%rax), %r12;
+       movq (16 * 32 + 3 * 8)(%rax), %r13;
+
+       leave;
+       ret;
+ELF(.size _gcry_camellia_aesni_avx2_ocb_auth,.-_gcry_camellia_aesni_avx2_ocb_auth;)
 
 #endif /*defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX2_SUPPORT)*/
 #endif /*__x86_64*/
index cdeaf8b..a3d87d1 100644 (file)
@@ -1,6 +1,6 @@
 /* camellia-arm.S  -  ARM assembly implementation of Camellia cipher
  *
- * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
index f18d135..dfddb4a 100644 (file)
@@ -63,6 +63,7 @@
 #include "cipher.h"
 #include "camellia.h"
 #include "bufhelp.h"
+#include "cipher-internal.h"
 #include "cipher-selftest.h"
 
 /* Helper macro to force alignment to 16 bytes.  */
@@ -75,7 +76,8 @@
 /* USE_AESNI inidicates whether to compile with Intel AES-NI/AVX code. */
 #undef USE_AESNI_AVX
 #if defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX_SUPPORT)
-# if defined(__x86_64__) && defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS)
+# if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
 #  define USE_AESNI_AVX 1
 # endif
 #endif
@@ -83,7 +85,8 @@
 /* USE_AESNI_AVX2 inidicates whether to compile with Intel AES-NI/AVX2 code. */
 #undef USE_AESNI_AVX2
 #if defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX2_SUPPORT)
-# if defined(__x86_64__) && defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS)
+# if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
 #  define USE_AESNI_AVX2 1
 # endif
 #endif
@@ -100,6 +103,20 @@ typedef struct
 #endif /*USE_AESNI_AVX2*/
 } CAMELLIA_context;
 
+/* Assembly implementations use SystemV ABI, ABI conversion and additional
+ * stack to store XMM6-XMM15 needed on Win64. */
+#undef ASM_FUNC_ABI
+#undef ASM_EXTRA_STACK
+#if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2)
+# ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+#  define ASM_FUNC_ABI __attribute__((sysv_abi))
+#  define ASM_EXTRA_STACK (10 * 16)
+# else
+#  define ASM_FUNC_ABI
+#  define ASM_EXTRA_STACK 0
+# endif
+#endif
+
 #ifdef USE_AESNI_AVX
 /* Assembler implementations of Camellia using AES-NI and AVX.  Process data
    in 16 block same time.
@@ -107,21 +124,41 @@ typedef struct
 extern void _gcry_camellia_aesni_avx_ctr_enc(CAMELLIA_context *ctx,
                                             unsigned char *out,
                                             const unsigned char *in,
-                                            unsigned char *ctr);
+                                            unsigned char *ctr) ASM_FUNC_ABI;
 
 extern void _gcry_camellia_aesni_avx_cbc_dec(CAMELLIA_context *ctx,
                                             unsigned char *out,
                                             const unsigned char *in,
-                                            unsigned char *iv);
+                                            unsigned char *iv) ASM_FUNC_ABI;
 
 extern void _gcry_camellia_aesni_avx_cfb_dec(CAMELLIA_context *ctx,
                                             unsigned char *out,
                                             const unsigned char *in,
-                                            unsigned char *iv);
+                                            unsigned char *iv) ASM_FUNC_ABI;
+
+extern void _gcry_camellia_aesni_avx_ocb_enc(CAMELLIA_context *ctx,
+                                            unsigned char *out,
+                                            const unsigned char *in,
+                                            unsigned char *offset,
+                                            unsigned char *checksum,
+                                            const u64 Ls[16]) ASM_FUNC_ABI;
+
+extern void _gcry_camellia_aesni_avx_ocb_dec(CAMELLIA_context *ctx,
+                                            unsigned char *out,
+                                            const unsigned char *in,
+                                            unsigned char *offset,
+                                            unsigned char *checksum,
+                                            const u64 Ls[16]) ASM_FUNC_ABI;
+
+extern void _gcry_camellia_aesni_avx_ocb_auth(CAMELLIA_context *ctx,
+                                            const unsigned char *abuf,
+                                            unsigned char *offset,
+                                            unsigned char *checksum,
+                                            const u64 Ls[16]) ASM_FUNC_ABI;
 
 extern void _gcry_camellia_aesni_avx_keygen(CAMELLIA_context *ctx,
                                            const unsigned char *key,
-                                           unsigned int keylen);
+                                           unsigned int keylen) ASM_FUNC_ABI;
 #endif
 
 #ifdef USE_AESNI_AVX2
@@ -131,17 +168,37 @@ extern void _gcry_camellia_aesni_avx_keygen(CAMELLIA_context *ctx,
 extern void _gcry_camellia_aesni_avx2_ctr_enc(CAMELLIA_context *ctx,
                                              unsigned char *out,
                                              const unsigned char *in,
-                                             unsigned char *ctr);
+                                             unsigned char *ctr) ASM_FUNC_ABI;
 
 extern void _gcry_camellia_aesni_avx2_cbc_dec(CAMELLIA_context *ctx,
                                              unsigned char *out,
                                              const unsigned char *in,
-                                             unsigned char *iv);
+                                             unsigned char *iv) ASM_FUNC_ABI;
 
 extern void _gcry_camellia_aesni_avx2_cfb_dec(CAMELLIA_context *ctx,
                                              unsigned char *out,
                                              const unsigned char *in,
-                                             unsigned char *iv);
+                                             unsigned char *iv) ASM_FUNC_ABI;
+
+extern void _gcry_camellia_aesni_avx2_ocb_enc(CAMELLIA_context *ctx,
+                                             unsigned char *out,
+                                             const unsigned char *in,
+                                             unsigned char *offset,
+                                             unsigned char *checksum,
+                                             const u64 Ls[32]) ASM_FUNC_ABI;
+
+extern void _gcry_camellia_aesni_avx2_ocb_dec(CAMELLIA_context *ctx,
+                                             unsigned char *out,
+                                             const unsigned char *in,
+                                             unsigned char *offset,
+                                             unsigned char *checksum,
+                                             const u64 Ls[32]) ASM_FUNC_ABI;
+
+extern void _gcry_camellia_aesni_avx2_ocb_auth(CAMELLIA_context *ctx,
+                                              const unsigned char *abuf,
+                                              unsigned char *offset,
+                                              unsigned char *checksum,
+                                              const u64 Ls[32]) ASM_FUNC_ABI;
 #endif
 
 static const char *selftest(void);
@@ -318,7 +375,7 @@ _gcry_camellia_ctr_enc(void *context, unsigned char *ctr,
       if (did_use_aesni_avx2)
         {
           int avx2_burn_stack_depth = 32 * CAMELLIA_BLOCK_SIZE + 16 +
-                                        2 * sizeof(void *);
+                                        2 * sizeof(void *) + ASM_EXTRA_STACK;
 
           if (burn_stack_depth < avx2_burn_stack_depth)
             burn_stack_depth = avx2_burn_stack_depth;
@@ -347,8 +404,11 @@ _gcry_camellia_ctr_enc(void *context, unsigned char *ctr,
 
       if (did_use_aesni_avx)
         {
-          if (burn_stack_depth < 16 * CAMELLIA_BLOCK_SIZE + 2 * sizeof(void *))
-            burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE + 2 * sizeof(void *);
+          int avx_burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE +
+                                       2 * sizeof(void *) + ASM_EXTRA_STACK;
+
+          if (burn_stack_depth < avx_burn_stack_depth)
+            burn_stack_depth = avx_burn_stack_depth;
         }
 
       /* Use generic code to handle smaller chunks... */
@@ -409,7 +469,7 @@ _gcry_camellia_cbc_dec(void *context, unsigned char *iv,
       if (did_use_aesni_avx2)
         {
           int avx2_burn_stack_depth = 32 * CAMELLIA_BLOCK_SIZE + 16 +
-                                        2 * sizeof(void *);
+                                        2 * sizeof(void *) + ASM_EXTRA_STACK;;
 
           if (burn_stack_depth < avx2_burn_stack_depth)
             burn_stack_depth = avx2_burn_stack_depth;
@@ -437,8 +497,11 @@ _gcry_camellia_cbc_dec(void *context, unsigned char *iv,
 
       if (did_use_aesni_avx)
         {
-          if (burn_stack_depth < 16 * CAMELLIA_BLOCK_SIZE + 2 * sizeof(void *))
-            burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE + 2 * sizeof(void *);
+          int avx_burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE +
+                                       2 * sizeof(void *) + ASM_EXTRA_STACK;
+
+          if (burn_stack_depth < avx_burn_stack_depth)
+            burn_stack_depth = avx_burn_stack_depth;
         }
 
       /* Use generic code to handle smaller chunks... */
@@ -491,7 +554,7 @@ _gcry_camellia_cfb_dec(void *context, unsigned char *iv,
       if (did_use_aesni_avx2)
         {
           int avx2_burn_stack_depth = 32 * CAMELLIA_BLOCK_SIZE + 16 +
-                                        2 * sizeof(void *);
+                                        2 * sizeof(void *) + ASM_EXTRA_STACK;
 
           if (burn_stack_depth < avx2_burn_stack_depth)
             burn_stack_depth = avx2_burn_stack_depth;
@@ -519,8 +582,11 @@ _gcry_camellia_cfb_dec(void *context, unsigned char *iv,
 
       if (did_use_aesni_avx)
         {
-          if (burn_stack_depth < 16 * CAMELLIA_BLOCK_SIZE + 2 * sizeof(void *))
-            burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE + 2 * sizeof(void *);
+          int avx_burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE +
+                                       2 * sizeof(void *) + ASM_EXTRA_STACK;
+
+          if (burn_stack_depth < avx_burn_stack_depth)
+            burn_stack_depth = avx_burn_stack_depth;
         }
 
       /* Use generic code to handle smaller chunks... */
@@ -538,6 +604,310 @@ _gcry_camellia_cfb_dec(void *context, unsigned char *iv,
   _gcry_burn_stack(burn_stack_depth);
 }
 
+/* Bulk encryption/decryption of complete blocks in OCB mode. */
+size_t
+_gcry_camellia_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
+                         const void *inbuf_arg, size_t nblocks, int encrypt)
+{
+#if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2)
+  CAMELLIA_context *ctx = (void *)&c->context.c;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  unsigned char l_tmp[CAMELLIA_BLOCK_SIZE];
+  int burn_stack_depth;
+  u64 blkn = c->u_mode.ocb.data_nblocks;
+
+  burn_stack_depth = encrypt ? CAMELLIA_encrypt_stack_burn_size :
+                             CAMELLIA_decrypt_stack_burn_size;
+#else
+  (void)c;
+  (void)outbuf_arg;
+  (void)inbuf_arg;
+  (void)encrypt;
+#endif
+
+#ifdef USE_AESNI_AVX2
+  if (ctx->use_aesni_avx2)
+    {
+      int did_use_aesni_avx2 = 0;
+      u64 Ls[32];
+      unsigned int n = 32 - (blkn % 32);
+      u64 *l;
+      int i;
+
+      if (nblocks >= 32)
+       {
+         for (i = 0; i < 32; i += 8)
+           {
+             /* Use u64 to store pointers for x32 support (assembly function
+              * assumes 64-bit pointers). */
+             Ls[(i + 0 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+             Ls[(i + 1 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+             Ls[(i + 2 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+             Ls[(i + 3 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
+             Ls[(i + 4 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+             Ls[(i + 5 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+             Ls[(i + 6 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+           }
+
+         Ls[(7 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
+         Ls[(15 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[4];
+         Ls[(23 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
+         l = &Ls[(31 + n) % 32];
+
+         /* Process data in 32 block chunks. */
+         while (nblocks >= 32)
+           {
+             /* l_tmp will be used only every 65536-th block. */
+             blkn += 32;
+             *l = (uintptr_t)(void *)ocb_get_l(c, l_tmp, blkn - blkn % 32);
+
+             if (encrypt)
+               _gcry_camellia_aesni_avx2_ocb_enc(ctx, outbuf, inbuf, c->u_iv.iv,
+                                                 c->u_ctr.ctr, Ls);
+             else
+               _gcry_camellia_aesni_avx2_ocb_dec(ctx, outbuf, inbuf, c->u_iv.iv,
+                                                 c->u_ctr.ctr, Ls);
+
+             nblocks -= 32;
+             outbuf += 32 * CAMELLIA_BLOCK_SIZE;
+             inbuf  += 32 * CAMELLIA_BLOCK_SIZE;
+             did_use_aesni_avx2 = 1;
+           }
+       }
+
+      if (did_use_aesni_avx2)
+       {
+         int avx2_burn_stack_depth = 32 * CAMELLIA_BLOCK_SIZE +
+                                     2 * sizeof(void *) + ASM_EXTRA_STACK;
+
+         if (burn_stack_depth < avx2_burn_stack_depth)
+           burn_stack_depth = avx2_burn_stack_depth;
+       }
+
+      /* Use generic code to handle smaller chunks... */
+    }
+#endif
+
+#ifdef USE_AESNI_AVX
+  if (ctx->use_aesni_avx)
+    {
+      int did_use_aesni_avx = 0;
+      u64 Ls[16];
+      unsigned int n = 16 - (blkn % 16);
+      u64 *l;
+      int i;
+
+      if (nblocks >= 16)
+       {
+         for (i = 0; i < 16; i += 8)
+           {
+             /* Use u64 to store pointers for x32 support (assembly function
+              * assumes 64-bit pointers). */
+             Ls[(i + 0 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+             Ls[(i + 1 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+             Ls[(i + 2 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+             Ls[(i + 3 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
+             Ls[(i + 4 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+             Ls[(i + 5 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+             Ls[(i + 6 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+           }
+
+         Ls[(7 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
+         l = &Ls[(15 + n) % 16];
+
+         /* Process data in 16 block chunks. */
+         while (nblocks >= 16)
+           {
+             /* l_tmp will be used only every 65536-th block. */
+             blkn += 16;
+             *l = (uintptr_t)(void *)ocb_get_l(c, l_tmp, blkn - blkn % 16);
+
+             if (encrypt)
+               _gcry_camellia_aesni_avx_ocb_enc(ctx, outbuf, inbuf, c->u_iv.iv,
+                                               c->u_ctr.ctr, Ls);
+             else
+               _gcry_camellia_aesni_avx_ocb_dec(ctx, outbuf, inbuf, c->u_iv.iv,
+                                               c->u_ctr.ctr, Ls);
+
+             nblocks -= 16;
+             outbuf += 16 * CAMELLIA_BLOCK_SIZE;
+             inbuf  += 16 * CAMELLIA_BLOCK_SIZE;
+             did_use_aesni_avx = 1;
+           }
+       }
+
+      if (did_use_aesni_avx)
+       {
+         int avx_burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE +
+                                     2 * sizeof(void *) + ASM_EXTRA_STACK;
+
+         if (burn_stack_depth < avx_burn_stack_depth)
+           burn_stack_depth = avx_burn_stack_depth;
+       }
+
+      /* Use generic code to handle smaller chunks... */
+    }
+#endif
+
+#if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2)
+  c->u_mode.ocb.data_nblocks = blkn;
+
+  wipememory(&l_tmp, sizeof(l_tmp));
+
+  if (burn_stack_depth)
+    _gcry_burn_stack (burn_stack_depth + 4 * sizeof(void *));
+#endif
+
+  return nblocks;
+}
+
+/* Bulk authentication of complete blocks in OCB mode. */
+size_t
+_gcry_camellia_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
+                        size_t nblocks)
+{
+#if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2)
+  CAMELLIA_context *ctx = (void *)&c->context.c;
+  const unsigned char *abuf = abuf_arg;
+  unsigned char l_tmp[CAMELLIA_BLOCK_SIZE];
+  int burn_stack_depth;
+  u64 blkn = c->u_mode.ocb.aad_nblocks;
+
+  burn_stack_depth = CAMELLIA_encrypt_stack_burn_size;
+#else
+  (void)c;
+  (void)abuf_arg;
+#endif
+
+#ifdef USE_AESNI_AVX2
+  if (ctx->use_aesni_avx2)
+    {
+      int did_use_aesni_avx2 = 0;
+      u64 Ls[32];
+      unsigned int n = 32 - (blkn % 32);
+      u64 *l;
+      int i;
+
+      if (nblocks >= 32)
+       {
+         for (i = 0; i < 32; i += 8)
+           {
+             /* Use u64 to store pointers for x32 support (assembly function
+              * assumes 64-bit pointers). */
+             Ls[(i + 0 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+             Ls[(i + 1 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+             Ls[(i + 2 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+             Ls[(i + 3 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
+             Ls[(i + 4 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+             Ls[(i + 5 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+             Ls[(i + 6 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+           }
+
+         Ls[(7 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
+         Ls[(15 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[4];
+         Ls[(23 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
+         l = &Ls[(31 + n) % 32];
+
+         /* Process data in 32 block chunks. */
+         while (nblocks >= 32)
+           {
+             /* l_tmp will be used only every 65536-th block. */
+             blkn += 32;
+             *l = (uintptr_t)(void *)ocb_get_l(c, l_tmp, blkn - blkn % 32);
+
+             _gcry_camellia_aesni_avx2_ocb_auth(ctx, abuf,
+                                                c->u_mode.ocb.aad_offset,
+                                                c->u_mode.ocb.aad_sum, Ls);
+
+             nblocks -= 32;
+             abuf += 32 * CAMELLIA_BLOCK_SIZE;
+             did_use_aesni_avx2 = 1;
+           }
+       }
+
+      if (did_use_aesni_avx2)
+       {
+         int avx2_burn_stack_depth = 32 * CAMELLIA_BLOCK_SIZE +
+                                     2 * sizeof(void *) + ASM_EXTRA_STACK;
+
+         if (burn_stack_depth < avx2_burn_stack_depth)
+           burn_stack_depth = avx2_burn_stack_depth;
+       }
+
+      /* Use generic code to handle smaller chunks... */
+    }
+#endif
+
+#ifdef USE_AESNI_AVX
+  if (ctx->use_aesni_avx)
+    {
+      int did_use_aesni_avx = 0;
+      u64 Ls[16];
+      unsigned int n = 16 - (blkn % 16);
+      u64 *l;
+      int i;
+
+      if (nblocks >= 16)
+       {
+         for (i = 0; i < 16; i += 8)
+           {
+             /* Use u64 to store pointers for x32 support (assembly function
+              * assumes 64-bit pointers). */
+             Ls[(i + 0 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+             Ls[(i + 1 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+             Ls[(i + 2 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+             Ls[(i + 3 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
+             Ls[(i + 4 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+             Ls[(i + 5 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+             Ls[(i + 6 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+           }
+
+         Ls[(7 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
+         l = &Ls[(15 + n) % 16];
+
+         /* Process data in 16 block chunks. */
+         while (nblocks >= 16)
+           {
+             /* l_tmp will be used only every 65536-th block. */
+             blkn += 16;
+             *l = (uintptr_t)(void *)ocb_get_l(c, l_tmp, blkn - blkn % 16);
+
+             _gcry_camellia_aesni_avx_ocb_auth(ctx, abuf,
+                                               c->u_mode.ocb.aad_offset,
+                                               c->u_mode.ocb.aad_sum, Ls);
+
+             nblocks -= 16;
+             abuf += 16 * CAMELLIA_BLOCK_SIZE;
+             did_use_aesni_avx = 1;
+           }
+       }
+
+      if (did_use_aesni_avx)
+       {
+         int avx_burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE +
+                                     2 * sizeof(void *) + ASM_EXTRA_STACK;
+
+         if (burn_stack_depth < avx_burn_stack_depth)
+           burn_stack_depth = avx_burn_stack_depth;
+       }
+
+      /* Use generic code to handle smaller chunks... */
+    }
+#endif
+
+#if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2)
+  c->u_mode.ocb.aad_nblocks = blkn;
+
+  wipememory(&l_tmp, sizeof(l_tmp));
+
+  if (burn_stack_depth)
+    _gcry_burn_stack (burn_stack_depth + 4 * sizeof(void *));
+#endif
+
+  return nblocks;
+}
+
 /* Run the self-tests for CAMELLIA-CTR-128, tests IV increment of bulk CTR
    encryption.  Returns NULL on success. */
 static const char*
index c3b819d..a5f078e 100644 (file)
@@ -1,6 +1,6 @@
 /* cast5-amd64.S  -  AMD64 assembly implementation of CAST5 cipher
  *
- * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
 
 #ifdef __x86_64
 #include <config.h>
-#if defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && defined(USE_CAST5)
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && defined(USE_CAST5)
 
-#ifdef __PIC__
-#  define RIP %rip
+#if defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS) || !defined(__PIC__)
+#  define GET_EXTERN_POINTER(name, reg) leaq name, reg
+#else
 #  define GET_EXTERN_POINTER(name, reg) movq name@GOTPCREL(%rip), reg
+#endif
+
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
 #else
-#  define RIP
-#  define GET_EXTERN_POINTER(name, reg) leaq name, reg
+# define ELF(...) /*_*/
 #endif
 
 .text
 
 .align 8
 .globl _gcry_cast5_amd64_encrypt_block
-.type   _gcry_cast5_amd64_encrypt_block,@function;
+ELF(.type   _gcry_cast5_amd64_encrypt_block,@function;)
 
 _gcry_cast5_amd64_encrypt_block:
        /* input:
@@ -216,11 +221,11 @@ _gcry_cast5_amd64_encrypt_block:
        popq %rbx;
        popq %rbp;
        ret;
-.size _gcry_cast5_amd64_encrypt_block,.-_gcry_cast5_amd64_encrypt_block;
+ELF(.size _gcry_cast5_amd64_encrypt_block,.-_gcry_cast5_amd64_encrypt_block;)
 
 .align 8
 .globl _gcry_cast5_amd64_decrypt_block
-.type   _gcry_cast5_amd64_decrypt_block,@function;
+ELF(.type   _gcry_cast5_amd64_decrypt_block,@function;)
 
 _gcry_cast5_amd64_decrypt_block:
        /* input:
@@ -256,7 +261,7 @@ _gcry_cast5_amd64_decrypt_block:
        popq %rbx;
        popq %rbp;
        ret;
-.size _gcry_cast5_amd64_decrypt_block,.-_gcry_cast5_amd64_decrypt_block;
+ELF(.size _gcry_cast5_amd64_decrypt_block,.-_gcry_cast5_amd64_decrypt_block;)
 
 /**********************************************************************
   4-way cast5, four blocks parallel
@@ -359,7 +364,7 @@ _gcry_cast5_amd64_decrypt_block:
        rorq $32,               d;
 
 .align 8
-.type   __cast5_enc_blk4,@function;
+ELF(.type   __cast5_enc_blk4,@function;)
 
 __cast5_enc_blk4:
        /* input:
@@ -384,10 +389,10 @@ __cast5_enc_blk4:
 
        outbswap_block4(RLR0, RLR1, RLR2, RLR3);
        ret;
-.size __cast5_enc_blk4,.-__cast5_enc_blk4;
+ELF(.size __cast5_enc_blk4,.-__cast5_enc_blk4;)
 
 .align 8
-.type   __cast5_dec_blk4,@function;
+ELF(.type   __cast5_dec_blk4,@function;)
 
 __cast5_dec_blk4:
        /* input:
@@ -414,11 +419,11 @@ __cast5_dec_blk4:
 
        outbswap_block4(RLR0, RLR1, RLR2, RLR3);
        ret;
-.size __cast5_dec_blk4,.-__cast5_dec_blk4;
+ELF(.size __cast5_dec_blk4,.-__cast5_dec_blk4;)
 
 .align 8
 .globl _gcry_cast5_amd64_ctr_enc
-.type   _gcry_cast5_amd64_ctr_enc,@function;
+ELF(.type   _gcry_cast5_amd64_ctr_enc,@function;)
 _gcry_cast5_amd64_ctr_enc:
        /* input:
         *      %rdi: ctx, CTX
@@ -472,11 +477,11 @@ _gcry_cast5_amd64_ctr_enc:
        popq %rbx;
        popq %rbp;
        ret
-.size _gcry_cast5_amd64_ctr_enc,.-_gcry_cast5_amd64_ctr_enc;
+ELF(.size _gcry_cast5_amd64_ctr_enc,.-_gcry_cast5_amd64_ctr_enc;)
 
 .align 8
 .globl _gcry_cast5_amd64_cbc_dec
-.type   _gcry_cast5_amd64_cbc_dec,@function;
+ELF(.type   _gcry_cast5_amd64_cbc_dec,@function;)
 _gcry_cast5_amd64_cbc_dec:
        /* input:
         *      %rdi: ctx, CTX
@@ -526,11 +531,11 @@ _gcry_cast5_amd64_cbc_dec:
        popq %rbp;
        ret;
 
-.size _gcry_cast5_amd64_cbc_dec,.-_gcry_cast5_amd64_cbc_dec;
+ELF(.size _gcry_cast5_amd64_cbc_dec,.-_gcry_cast5_amd64_cbc_dec;)
 
 .align 8
 .globl _gcry_cast5_amd64_cfb_dec
-.type   _gcry_cast5_amd64_cfb_dec,@function;
+ELF(.type   _gcry_cast5_amd64_cfb_dec,@function;)
 _gcry_cast5_amd64_cfb_dec:
        /* input:
         *      %rdi: ctx, CTX
@@ -581,7 +586,7 @@ _gcry_cast5_amd64_cfb_dec:
        popq %rbp;
        ret;
 
-.size _gcry_cast5_amd64_cfb_dec,.-_gcry_cast5_amd64_cfb_dec;
+ELF(.size _gcry_cast5_amd64_cfb_dec,.-_gcry_cast5_amd64_cfb_dec;)
 
 #endif /*defined(USE_CAST5)*/
 #endif /*__x86_64*/
index db96db4..76ddd2e 100644 (file)
@@ -1,6 +1,6 @@
 /* cast5-arm.S  -  ARM assembly implementation of CAST5 cipher
  *
- * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
index 115e1e6..94dcee7 100644 (file)
@@ -48,7 +48,8 @@
 
 /* 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)
+#if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+    defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
 # define USE_AMD64_ASM 1
 #endif
 
@@ -372,16 +373,72 @@ extern void _gcry_cast5_amd64_cbc_dec(CAST5_context *ctx, byte *out,
 extern void _gcry_cast5_amd64_cfb_dec(CAST5_context *ctx, byte *out,
                                      const byte *in, byte *iv);
 
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+static inline void
+call_sysv_fn (const void *fn, const void *arg1, const void *arg2,
+              const void *arg3, const void *arg4)
+{
+  /* Call SystemV ABI function without storing non-volatile XMM registers,
+   * as target function does not use vector instruction sets. */
+  asm volatile ("callq *%0\n\t"
+                : "+a" (fn),
+                  "+D" (arg1),
+                  "+S" (arg2),
+                  "+d" (arg3),
+                  "+c" (arg4)
+                :
+                : "cc", "memory", "r8", "r9", "r10", "r11");
+}
+#endif
+
 static void
 do_encrypt_block (CAST5_context *context, byte *outbuf, const byte *inbuf)
 {
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+  call_sysv_fn (_gcry_cast5_amd64_encrypt_block, context, outbuf, inbuf, NULL);
+#else
   _gcry_cast5_amd64_encrypt_block (context, outbuf, inbuf);
+#endif
 }
 
 static void
 do_decrypt_block (CAST5_context *context, byte *outbuf, const byte *inbuf)
 {
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+  call_sysv_fn (_gcry_cast5_amd64_decrypt_block, context, outbuf, inbuf, NULL);
+#else
   _gcry_cast5_amd64_decrypt_block (context, outbuf, inbuf);
+#endif
+}
+
+static void
+cast5_amd64_ctr_enc(CAST5_context *ctx, byte *out, const byte *in, byte *ctr)
+{
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+  call_sysv_fn (_gcry_cast5_amd64_ctr_enc, ctx, out, in, ctr);
+#else
+  _gcry_cast5_amd64_ctr_enc (ctx, out, in, ctr);
+#endif
+}
+
+static void
+cast5_amd64_cbc_dec(CAST5_context *ctx, byte *out, const byte *in, byte *iv)
+{
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+  call_sysv_fn (_gcry_cast5_amd64_cbc_dec, ctx, out, in, iv);
+#else
+  _gcry_cast5_amd64_cbc_dec (ctx, out, in, iv);
+#endif
+}
+
+static void
+cast5_amd64_cfb_dec(CAST5_context *ctx, byte *out, const byte *in, byte *iv)
+{
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+  call_sysv_fn (_gcry_cast5_amd64_cfb_dec, ctx, out, in, iv);
+#else
+  _gcry_cast5_amd64_cfb_dec (ctx, out, in, iv);
+#endif
 }
 
 static unsigned int
@@ -396,7 +453,7 @@ static unsigned int
 decrypt_block (void *context, byte *outbuf, const byte *inbuf)
 {
   CAST5_context *c = (CAST5_context *) context;
-  _gcry_cast5_amd64_decrypt_block (c, outbuf, inbuf);
+  do_decrypt_block (c, outbuf, inbuf);
   return /*burn_stack*/ (2*8);
 }
 
@@ -582,7 +639,7 @@ _gcry_cast5_ctr_enc(void *context, unsigned char *ctr, void *outbuf_arg,
     /* Process data in 4 block chunks. */
     while (nblocks >= 4)
       {
-        _gcry_cast5_amd64_ctr_enc(ctx, outbuf, inbuf, ctr);
+        cast5_amd64_ctr_enc(ctx, outbuf, inbuf, ctr);
 
         nblocks -= 4;
         outbuf += 4 * CAST5_BLOCKSIZE;
@@ -651,7 +708,7 @@ _gcry_cast5_cbc_dec(void *context, unsigned char *iv, void *outbuf_arg,
     /* Process data in 4 block chunks. */
     while (nblocks >= 4)
       {
-        _gcry_cast5_amd64_cbc_dec(ctx, outbuf, inbuf, iv);
+        cast5_amd64_cbc_dec(ctx, outbuf, inbuf, iv);
 
         nblocks -= 4;
         outbuf += 4 * CAST5_BLOCKSIZE;
@@ -710,7 +767,7 @@ _gcry_cast5_cfb_dec(void *context, unsigned char *iv, void *outbuf_arg,
     /* Process data in 4 block chunks. */
     while (nblocks >= 4)
       {
-        _gcry_cast5_amd64_cfb_dec(ctx, outbuf, inbuf, iv);
+        cast5_amd64_cfb_dec(ctx, outbuf, inbuf, iv);
 
         nblocks -= 4;
         outbuf += 4 * CAST5_BLOCKSIZE;
diff --git a/cipher/chacha20-armv7-neon.S b/cipher/chacha20-armv7-neon.S
new file mode 100644 (file)
index 0000000..1a395ba
--- /dev/null
@@ -0,0 +1,710 @@
+/* chacha20-armv7-neon.S - ARM/NEON accelerated chacha20 blocks function
+ *
+ * Copyright (C) 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Based on public domain implementation by Andrew Moon at
+ *  https://github.com/floodyberry/chacha-opt
+ */
+
+#include <config.h>
+
+#if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) && \
+    defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \
+    defined(HAVE_GCC_INLINE_ASM_NEON) && defined(USE_CHACHA20)
+
+.syntax unified
+.fpu neon
+.arm
+
+.text
+
+.globl _gcry_chacha20_armv7_neon_blocks
+.type  _gcry_chacha20_armv7_neon_blocks,%function;
+_gcry_chacha20_armv7_neon_blocks:
+.Lchacha_blocks_neon_local:
+       tst r3, r3
+       beq .Lchacha_blocks_neon_nobytes
+       vstmdb sp!, {q4,q5,q6,q7}
+       stmfd sp!, {r4-r12, r14}
+       mov r8, sp
+       sub sp, sp, #196
+       and sp, sp, #0xffffffe0
+       str r0, [sp, #60]
+       str r1, [sp, #48]
+       str r2, [sp, #40]
+       str r3, [sp, #52]
+       str r8, [sp, #192]
+       add r1, sp, #64
+       ldmia r0!, {r4-r11}
+       stmia r1!, {r4-r11}
+       ldmia r0!, {r4-r11}
+       stmia r1!, {r4-r11}
+       mov r4, #20
+       str r4, [sp, #44]
+       cmp r3, #256
+       blo .Lchacha_blocks_neon_mainloop2
+.Lchacha_blocks_neon_mainloop1:
+       ldr r0, [sp, #44]
+       str r0, [sp, #0]
+       add r1, sp, #(64)
+       mov r2, #1
+       veor q12, q12
+       vld1.32 {q0,q1}, [r1,:128]!
+       vld1.32 {q2,q3}, [r1,:128]
+       vmov.32 d24[0], r2
+       vadd.u64 q3, q3, q12
+       vmov q4, q0
+       vmov q5, q1
+       vmov q6, q2
+       vadd.u64 q7, q3, q12
+       vmov q8, q0
+       vmov q9, q1
+       vmov q10, q2
+       vadd.u64 q11, q7, q12
+       add r0, sp, #64
+       ldm r0, {r0-r12}
+       ldr r14, [sp, #(64 +60)]
+       str r6, [sp, #8]
+       str r11, [sp, #12]
+       str r14, [sp, #28]
+       ldr r11, [sp, #(64 +52)]
+       ldr r14, [sp, #(64 +56)]
+.Lchacha_blocks_neon_rounds1:
+       ldr r6, [sp, #0]
+       vadd.i32 q0, q0, q1
+       add r0, r0, r4
+       vadd.i32 q4, q4, q5
+       add r1, r1, r5
+       vadd.i32 q8, q8, q9
+       eor r12, r12, r0
+       veor q12, q3, q0
+       eor r11, r11, r1
+       veor q13, q7, q4
+       ror r12, r12, #16
+       veor q14, q11, q8
+       ror r11, r11, #16
+       vrev32.16 q3, q12
+       subs r6, r6, #2
+       vrev32.16 q7, q13
+       add r8, r8, r12
+       vrev32.16 q11, q14
+       add r9, r9, r11
+       vadd.i32 q2, q2, q3
+       eor r4, r4, r8
+       vadd.i32 q6, q6, q7
+       eor r5, r5, r9
+       vadd.i32 q10, q10, q11
+       str r6, [sp, #0]
+       veor q12, q1, q2
+       ror r4, r4, #20
+       veor q13, q5, q6
+       ror r5, r5, #20
+       veor q14, q9, q10
+       add r0, r0, r4
+       vshl.i32 q1, q12, #12
+       add r1, r1, r5
+       vshl.i32 q5, q13, #12
+       ldr r6, [sp, #8]
+       vshl.i32 q9, q14, #12
+       eor r12, r12, r0
+       vsri.u32 q1, q12, #20
+       eor r11, r11, r1
+       vsri.u32 q5, q13, #20
+       ror r12, r12, #24
+       vsri.u32 q9, q14, #20
+       ror r11, r11, #24
+       vadd.i32 q0, q0, q1
+       add r8, r8, r12
+       vadd.i32 q4, q4, q5
+       add r9, r9, r11
+       vadd.i32 q8, q8, q9
+       eor r4, r4, r8
+       veor q12, q3, q0
+       eor r5, r5, r9
+       veor q13, q7, q4
+       str r11, [sp, #20]
+       veor q14, q11, q8
+       ror r4, r4, #25
+       vshl.i32 q3, q12, #8
+       ror r5, r5, #25
+       vshl.i32 q7, q13, #8
+       str r4, [sp, #4]
+       vshl.i32 q11, q14, #8
+       ldr r4, [sp, #28]
+       vsri.u32 q3, q12, #24
+       add r2, r2, r6
+       vsri.u32 q7, q13, #24
+       add r3, r3, r7
+       vsri.u32 q11, q14, #24
+       ldr r11, [sp, #12]
+       vadd.i32 q2, q2, q3
+       eor r14, r14, r2
+       vadd.i32 q6, q6, q7
+       eor r4, r4, r3
+       vadd.i32 q10, q10, q11
+       ror r14, r14, #16
+       veor q12, q1, q2
+       ror r4, r4, #16
+       veor q13, q5, q6
+       add r10, r10, r14
+       veor q14, q9, q10
+       add r11, r11, r4
+       vshl.i32 q1, q12, #7
+       eor r6, r6, r10
+       vshl.i32 q5, q13, #7
+       eor r7, r7, r11
+       vshl.i32 q9, q14, #7
+       ror r6, r6, #20
+       vsri.u32 q1, q12, #25
+       ror r7, r7, #20
+       vsri.u32 q5, q13, #25
+       add r2, r2, r6
+       vsri.u32 q9, q14, #25
+       add r3, r3, r7
+       vext.32 q3, q3, q3, #3
+       eor r14, r14, r2
+       vext.32 q7, q7, q7, #3
+       eor r4, r4, r3
+       vext.32 q11, q11, q11, #3
+       ror r14, r14, #24
+       vext.32 q1, q1, q1, #1
+       ror r4, r4, #24
+       vext.32 q5, q5, q5, #1
+       add r10, r10, r14
+       vext.32 q9, q9, q9, #1
+       add r11, r11, r4
+       vext.32 q2, q2, q2, #2
+       eor r6, r6, r10
+       vext.32 q6, q6, q6, #2
+       eor r7, r7, r11
+       vext.32 q10, q10, q10, #2
+       ror r6, r6, #25
+       vadd.i32 q0, q0, q1
+       ror r7, r7, #25
+       vadd.i32 q4, q4, q5
+       add r0, r0, r5
+       vadd.i32 q8, q8, q9
+       add r1, r1, r6
+       veor q12, q3, q0
+       eor r4, r4, r0
+       veor q13, q7, q4
+       eor r12, r12, r1
+       veor q14, q11, q8
+       ror r4, r4, #16
+       vrev32.16 q3, q12
+       ror r12, r12, #16
+       vrev32.16 q7, q13
+       add r10, r10, r4
+       vrev32.16 q11, q14
+       add r11, r11, r12
+       vadd.i32 q2, q2, q3
+       eor r5, r5, r10
+       vadd.i32 q6, q6, q7
+       eor r6, r6, r11
+       vadd.i32 q10, q10, q11
+       ror r5, r5, #20
+       veor q12, q1, q2
+       ror r6, r6, #20
+       veor q13, q5, q6
+       add r0, r0, r5
+       veor q14, q9, q10
+       add r1, r1, r6
+       vshl.i32 q1, q12, #12
+       eor r4, r4, r0
+       vshl.i32 q5, q13, #12
+       eor r12, r12, r1
+       vshl.i32 q9, q14, #12
+       ror r4, r4, #24
+       vsri.u32 q1, q12, #20
+       ror r12, r12, #24
+       vsri.u32 q5, q13, #20
+       add r10, r10, r4
+       vsri.u32 q9, q14, #20
+       add r11, r11, r12
+       vadd.i32 q0, q0, q1
+       eor r5, r5, r10
+       vadd.i32 q4, q4, q5
+       eor r6, r6, r11
+       vadd.i32 q8, q8, q9
+       str r11, [sp, #12]
+       veor q12, q3, q0
+       ror r5, r5, #25
+       veor q13, q7, q4
+       ror r6, r6, #25
+       veor q14, q11, q8
+       str r4, [sp, #28]
+       vshl.i32 q3, q12, #8
+       ldr r4, [sp, #4]
+       vshl.i32 q7, q13, #8
+       add r2, r2, r7
+       vshl.i32 q11, q14, #8
+       add r3, r3, r4
+       vsri.u32 q3, q12, #24
+       ldr r11, [sp, #20]
+       vsri.u32 q7, q13, #24
+       eor r11, r11, r2
+       vsri.u32 q11, q14, #24
+       eor r14, r14, r3
+       vadd.i32 q2, q2, q3
+       ror r11, r11, #16
+       vadd.i32 q6, q6, q7
+       ror r14, r14, #16
+       vadd.i32 q10, q10, q11
+       add r8, r8, r11
+       veor q12, q1, q2
+       add r9, r9, r14
+       veor q13, q5, q6
+       eor r7, r7, r8
+       veor q14, q9, q10
+       eor r4, r4, r9
+       vshl.i32 q1, q12, #7
+       ror r7, r7, #20
+       vshl.i32 q5, q13, #7
+       ror r4, r4, #20
+       vshl.i32 q9, q14, #7
+       str r6, [sp, #8]
+       vsri.u32 q1, q12, #25
+       add r2, r2, r7
+       vsri.u32 q5, q13, #25
+       add r3, r3, r4
+       vsri.u32 q9, q14, #25
+       eor r11, r11, r2
+       vext.32 q3, q3, q3, #1
+       eor r14, r14, r3
+       vext.32 q7, q7, q7, #1
+       ror r11, r11, #24
+       vext.32 q11, q11, q11, #1
+       ror r14, r14, #24
+       vext.32 q1, q1, q1, #3
+       add r8, r8, r11
+       vext.32 q5, q5, q5, #3
+       add r9, r9, r14
+       vext.32 q9, q9, q9, #3
+       eor r7, r7, r8
+       vext.32 q2, q2, q2, #2
+       eor r4, r4, r9
+       vext.32 q6, q6, q6, #2
+       ror r7, r7, #25
+       vext.32 q10, q10, q10, #2
+       ror r4, r4, #25
+       bne .Lchacha_blocks_neon_rounds1
+       str r8, [sp, #0]
+       str r9, [sp, #4]
+       str r10, [sp, #8]
+       str r12, [sp, #16]
+       str r11, [sp, #20]
+       str r14, [sp, #24]
+       add r9, sp, #64
+       vld1.32 {q12,q13}, [r9,:128]!
+       ldr r12, [sp, #48]
+       vld1.32 {q14,q15}, [r9,:128]
+       ldr r14, [sp, #40]
+       vadd.i32 q0, q0, q12
+       ldr r8, [sp, #(64 +0)]
+       vadd.i32 q4, q4, q12
+       ldr r9, [sp, #(64 +4)]
+       vadd.i32 q8, q8, q12
+       ldr r10, [sp, #(64 +8)]
+       vadd.i32 q1, q1, q13
+       ldr r11, [sp, #(64 +12)]
+       vadd.i32 q5, q5, q13
+       add r0, r0, r8
+       vadd.i32 q9, q9, q13
+       add r1, r1, r9
+       vadd.i32 q2, q2, q14
+       add r2, r2, r10
+       vadd.i32 q6, q6, q14
+       ldr r8, [sp, #(64 +16)]
+       vadd.i32 q10, q10, q14
+       add r3, r3, r11
+       veor q14, q14, q14
+       ldr r9, [sp, #(64 +20)]
+       mov r11, #1
+       add r4, r4, r8
+       vmov.32 d28[0], r11
+       ldr r10, [sp, #(64 +24)]
+       vadd.u64 q12, q14, q15
+       add r5, r5, r9
+       vadd.u64 q13, q14, q12
+       ldr r11, [sp, #(64 +28)]
+       vadd.u64 q14, q14, q13
+       add r6, r6, r10
+       vadd.i32 q3, q3, q12
+       tst r12, r12
+       vadd.i32 q7, q7, q13
+       add r7, r7, r11
+       vadd.i32 q11, q11, q14
+       beq .Lchacha_blocks_neon_nomessage11
+       ldmia r12!, {r8-r11}
+       eor r0, r0, r8
+       eor r1, r1, r9
+       eor r2, r2, r10
+       ldr r8, [r12, #0]
+       eor r3, r3, r11
+       ldr r9, [r12, #4]
+       eor r4, r4, r8
+       ldr r10, [r12, #8]
+       eor r5, r5, r9
+       ldr r11, [r12, #12]
+       eor r6, r6, r10
+       add r12, r12, #16
+       eor r7, r7, r11
+.Lchacha_blocks_neon_nomessage11:
+       stmia r14!, {r0-r7}
+       ldm sp, {r0-r7}
+       ldr r8, [sp, #(64 +32)]
+       ldr r9, [sp, #(64 +36)]
+       ldr r10, [sp, #(64 +40)]
+       ldr r11, [sp, #(64 +44)]
+       add r0, r0, r8
+       add r1, r1, r9
+       add r2, r2, r10
+       ldr r8, [sp, #(64 +48)]
+       add r3, r3, r11
+       ldr r9, [sp, #(64 +52)]
+       add r4, r4, r8
+       ldr r10, [sp, #(64 +56)]
+       add r5, r5, r9
+       ldr r11, [sp, #(64 +60)]
+       add r6, r6, r10
+       adds r8, r8, #4
+       add r7, r7, r11
+       adc r9, r9, #0
+       str r8, [sp, #(64 +48)]
+       tst r12, r12
+       str r9, [sp, #(64 +52)]
+       beq .Lchacha_blocks_neon_nomessage12
+       ldmia r12!, {r8-r11}
+       eor r0, r0, r8
+       eor r1, r1, r9
+       eor r2, r2, r10
+       ldr r8, [r12, #0]
+       eor r3, r3, r11
+       ldr r9, [r12, #4]
+       eor r4, r4, r8
+       ldr r10, [r12, #8]
+       eor r5, r5, r9
+       ldr r11, [r12, #12]
+       eor r6, r6, r10
+       add r12, r12, #16
+       eor r7, r7, r11
+.Lchacha_blocks_neon_nomessage12:
+       stmia r14!, {r0-r7}
+       beq .Lchacha_blocks_neon_nomessage13
+       vld1.32 {q12,q13}, [r12]!
+       vld1.32 {q14,q15}, [r12]!
+       veor q0, q0, q12
+       veor q1, q1, q13
+       veor q2, q2, q14
+       veor q3, q3, q15
+.Lchacha_blocks_neon_nomessage13:
+       vst1.32 {q0,q1}, [r14]!
+       vst1.32 {q2,q3}, [r14]!
+       beq .Lchacha_blocks_neon_nomessage14
+       vld1.32 {q12,q13}, [r12]!
+       vld1.32 {q14,q15}, [r12]!
+       veor q4, q4, q12
+       veor q5, q5, q13
+       veor q6, q6, q14
+       veor q7, q7, q15
+.Lchacha_blocks_neon_nomessage14:
+       vst1.32 {q4,q5}, [r14]!
+       vst1.32 {q6,q7}, [r14]!
+       beq .Lchacha_blocks_neon_nomessage15
+       vld1.32 {q12,q13}, [r12]!
+       vld1.32 {q14,q15}, [r12]!
+       veor q8, q8, q12
+       veor q9, q9, q13
+       veor q10, q10, q14
+       veor q11, q11, q15
+.Lchacha_blocks_neon_nomessage15:
+       vst1.32 {q8,q9}, [r14]!
+       vst1.32 {q10,q11}, [r14]!
+       str r12, [sp, #48]
+       str r14, [sp, #40]
+       ldr r3, [sp, #52]
+       sub r3, r3, #256
+       cmp r3, #256
+       str r3, [sp, #52]
+       bhs .Lchacha_blocks_neon_mainloop1
+       tst r3, r3
+       beq .Lchacha_blocks_neon_done
+.Lchacha_blocks_neon_mainloop2:
+       ldr r3, [sp, #52]
+       ldr r1, [sp, #48]
+       cmp r3, #64
+       bhs .Lchacha_blocks_neon_noswap1
+       add r4, sp, #128
+       mov r5, r4
+       tst r1, r1
+       beq .Lchacha_blocks_neon_nocopy1
+.Lchacha_blocks_neon_copyinput1:
+       subs r3, r3, #1
+       ldrb r0, [r1], #1
+       strb r0, [r4], #1
+       bne .Lchacha_blocks_neon_copyinput1
+       str r5, [sp, #48]
+.Lchacha_blocks_neon_nocopy1:
+       ldr r4, [sp, #40]
+       str r5, [sp, #40]
+       str r4, [sp, #56]
+.Lchacha_blocks_neon_noswap1:
+       ldr r0, [sp, #44]
+       str r0, [sp, #0]
+       add r0, sp, #64
+       ldm r0, {r0-r12}
+       ldr r14, [sp, #(64 +60)]
+       str r6, [sp, #8]
+       str r11, [sp, #12]
+       str r14, [sp, #28]
+       ldr r11, [sp, #(64 +52)]
+       ldr r14, [sp, #(64 +56)]
+.Lchacha_blocks_neon_rounds2:
+       ldr r6, [sp, #0]
+       add r0, r0, r4
+       add r1, r1, r5
+       eor r12, r12, r0
+       eor r11, r11, r1
+       ror r12, r12, #16
+       ror r11, r11, #16
+       subs r6, r6, #2
+       add r8, r8, r12
+       add r9, r9, r11
+       eor r4, r4, r8
+       eor r5, r5, r9
+       str r6, [sp, #0]
+       ror r4, r4, #20
+       ror r5, r5, #20
+       add r0, r0, r4
+       add r1, r1, r5
+       ldr r6, [sp, #8]
+       eor r12, r12, r0
+       eor r11, r11, r1
+       ror r12, r12, #24
+       ror r11, r11, #24
+       add r8, r8, r12
+       add r9, r9, r11
+       eor r4, r4, r8
+       eor r5, r5, r9
+       str r11, [sp, #20]
+       ror r4, r4, #25
+       ror r5, r5, #25
+       str r4, [sp, #4]
+       ldr r4, [sp, #28]
+       add r2, r2, r6
+       add r3, r3, r7
+       ldr r11, [sp, #12]
+       eor r14, r14, r2
+       eor r4, r4, r3
+       ror r14, r14, #16
+       ror r4, r4, #16
+       add r10, r10, r14
+       add r11, r11, r4
+       eor r6, r6, r10
+       eor r7, r7, r11
+       ror r6, r6, #20
+       ror r7, r7, #20
+       add r2, r2, r6
+       add r3, r3, r7
+       eor r14, r14, r2
+       eor r4, r4, r3
+       ror r14, r14, #24
+       ror r4, r4, #24
+       add r10, r10, r14
+       add r11, r11, r4
+       eor r6, r6, r10
+       eor r7, r7, r11
+       ror r6, r6, #25
+       ror r7, r7, #25
+       add r0, r0, r5
+       add r1, r1, r6
+       eor r4, r4, r0
+       eor r12, r12, r1
+       ror r4, r4, #16
+       ror r12, r12, #16
+       add r10, r10, r4
+       add r11, r11, r12
+       eor r5, r5, r10
+       eor r6, r6, r11
+       ror r5, r5, #20
+       ror r6, r6, #20
+       add r0, r0, r5
+       add r1, r1, r6
+       eor r4, r4, r0
+       eor r12, r12, r1
+       ror r4, r4, #24
+       ror r12, r12, #24
+       add r10, r10, r4
+       add r11, r11, r12
+       eor r5, r5, r10
+       eor r6, r6, r11
+       str r11, [sp, #12]
+       ror r5, r5, #25
+       ror r6, r6, #25
+       str r4, [sp, #28]
+       ldr r4, [sp, #4]
+       add r2, r2, r7
+       add r3, r3, r4
+       ldr r11, [sp, #20]
+       eor r11, r11, r2
+       eor r14, r14, r3
+       ror r11, r11, #16
+       ror r14, r14, #16
+       add r8, r8, r11
+       add r9, r9, r14
+       eor r7, r7, r8
+       eor r4, r4, r9
+       ror r7, r7, #20
+       ror r4, r4, #20
+       str r6, [sp, #8]
+       add r2, r2, r7
+       add r3, r3, r4
+       eor r11, r11, r2
+       eor r14, r14, r3
+       ror r11, r11, #24
+       ror r14, r14, #24
+       add r8, r8, r11
+       add r9, r9, r14
+       eor r7, r7, r8
+       eor r4, r4, r9
+       ror r7, r7, #25
+       ror r4, r4, #25
+       bne .Lchacha_blocks_neon_rounds2
+       str r8, [sp, #0]
+       str r9, [sp, #4]
+       str r10, [sp, #8]
+       str r12, [sp, #16]
+       str r11, [sp, #20]
+       str r14, [sp, #24]
+       ldr r12, [sp, #48]
+       ldr r14, [sp, #40]
+       ldr r8, [sp, #(64 +0)]
+       ldr r9, [sp, #(64 +4)]
+       ldr r10, [sp, #(64 +8)]
+       ldr r11, [sp, #(64 +12)]
+       add r0, r0, r8
+       add r1, r1, r9
+       add r2, r2, r10
+       ldr r8, [sp, #(64 +16)]
+       add r3, r3, r11
+       ldr r9, [sp, #(64 +20)]
+       add r4, r4, r8
+       ldr r10, [sp, #(64 +24)]
+       add r5, r5, r9
+       ldr r11, [sp, #(64 +28)]
+       add r6, r6, r10
+       tst r12, r12
+       add r7, r7, r11
+       beq .Lchacha_blocks_neon_nomessage21
+       ldmia r12!, {r8-r11}
+       eor r0, r0, r8
+       eor r1, r1, r9
+       eor r2, r2, r10
+       ldr r8, [r12, #0]
+       eor r3, r3, r11
+       ldr r9, [r12, #4]
+       eor r4, r4, r8
+       ldr r10, [r12, #8]
+       eor r5, r5, r9
+       ldr r11, [r12, #12]
+       eor r6, r6, r10
+       add r12, r12, #16
+       eor r7, r7, r11
+.Lchacha_blocks_neon_nomessage21:
+       stmia r14!, {r0-r7}
+       ldm sp, {r0-r7}
+       ldr r8, [sp, #(64 +32)]
+       ldr r9, [sp, #(64 +36)]
+       ldr r10, [sp, #(64 +40)]
+       ldr r11, [sp, #(64 +44)]
+       add r0, r0, r8
+       add r1, r1, r9
+       add r2, r2, r10
+       ldr r8, [sp, #(64 +48)]
+       add r3, r3, r11
+       ldr r9, [sp, #(64 +52)]
+       add r4, r4, r8
+       ldr r10, [sp, #(64 +56)]
+       add r5, r5, r9
+       ldr r11, [sp, #(64 +60)]
+       add r6, r6, r10
+       adds r8, r8, #1
+       add r7, r7, r11
+       adc r9, r9, #0
+       str r8, [sp, #(64 +48)]
+       tst r12, r12
+       str r9, [sp, #(64 +52)]
+       beq .Lchacha_blocks_neon_nomessage22
+       ldmia r12!, {r8-r11}
+       eor r0, r0, r8
+       eor r1, r1, r9
+       eor r2, r2, r10
+       ldr r8, [r12, #0]
+       eor r3, r3, r11
+       ldr r9, [r12, #4]
+       eor r4, r4, r8
+       ldr r10, [r12, #8]
+       eor r5, r5, r9
+       ldr r11, [r12, #12]
+       eor r6, r6, r10
+       add r12, r12, #16
+       eor r7, r7, r11
+.Lchacha_blocks_neon_nomessage22:
+       stmia r14!, {r0-r7}
+       str r12, [sp, #48]
+       str r14, [sp, #40]
+       ldr r3, [sp, #52]
+       cmp r3, #64
+       sub r4, r3, #64
+       str r4, [sp, #52]
+       bhi .Lchacha_blocks_neon_mainloop2
+       cmp r3, #64
+       beq .Lchacha_blocks_neon_nocopy2
+       ldr r1, [sp, #56]
+       sub r14, r14, #64
+.Lchacha_blocks_neon_copyinput2:
+       subs r3, r3, #1
+       ldrb r0, [r14], #1
+       strb r0, [r1], #1
+       bne .Lchacha_blocks_neon_copyinput2
+.Lchacha_blocks_neon_nocopy2:
+.Lchacha_blocks_neon_done:
+       ldr r7, [sp, #60]
+       ldr r8, [sp, #(64 +48)]
+       ldr r9, [sp, #(64 +52)]
+       str r8, [r7, #(48 + 0)]
+       str r9, [r7, #(48 + 4)]
+       mov r12, sp
+       stmia r12!, {r0-r7}
+       add r12, r12, #48
+       stmia r12!, {r0-r7}
+       sub r0, sp, #8
+       ldr sp, [sp, #192]
+       ldmfd sp!, {r4-r12, r14}
+       vldm sp!, {q4-q7}
+       sub r0, sp, r0
+       bx lr
+.Lchacha_blocks_neon_nobytes:
+       mov r0, #0;
+       bx lr
+.ltorg
+.size _gcry_chacha20_armv7_neon_blocks,.-_gcry_chacha20_armv7_neon_blocks;
+
+#endif
diff --git a/cipher/chacha20-avx2-amd64.S b/cipher/chacha20-avx2-amd64.S
new file mode 100644 (file)
index 0000000..12bed35
--- /dev/null
@@ -0,0 +1,957 @@
+/* chacha20-avx2-amd64.S  -  AMD64/AVX2 implementation of ChaCha20
+ *
+ * Copyright (C) 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Based on public domain implementation by Andrew Moon at
+ *  https://github.com/floodyberry/chacha-opt
+ */
+
+#ifdef __x86_64__
+#include <config.h>
+
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
+    defined(ENABLE_AVX2_SUPPORT) && USE_CHACHA20
+
+#ifdef __PIC__
+#  define RIP (%rip)
+#else
+#  define RIP
+#endif
+
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
+
+.text
+
+.align 8
+.globl _gcry_chacha20_amd64_avx2_blocks
+ELF(.type  _gcry_chacha20_amd64_avx2_blocks,@function;)
+_gcry_chacha20_amd64_avx2_blocks:
+.Lchacha_blocks_avx2_local:
+       vzeroupper
+       pushq %rbx
+       pushq %rbp
+       pushq %r12
+       pushq %r13
+       pushq %r14
+       movq %rsp, %rbp
+       andq $~63, %rsp
+       subq $512, %rsp
+       leaq .LC RIP, %rax
+       vmovdqu 0(%rax), %xmm6
+       vmovdqu 16(%rax), %xmm7
+       vmovdqu 0(%rdi), %xmm8
+       vmovdqu 16(%rdi), %xmm9
+       vmovdqu 32(%rdi), %xmm10
+       vmovdqu 48(%rdi), %xmm11
+       movl $20, %eax
+       movq $1, %r9
+       vmovdqa %xmm8, 0(%rsp)
+       vmovdqa %xmm9, 16(%rsp)
+       vmovdqa %xmm10, 32(%rsp)
+       vmovdqa %xmm11, 48(%rsp)
+       movq %rax, 64(%rsp)
+       vmovdqa %xmm6, 448(%rsp)
+       vmovdqa %xmm6, 464(%rsp)
+       vmovdqa %xmm7, 480(%rsp)
+       vmovdqa %xmm7, 496(%rsp)
+       cmpq $512, %rcx
+       jae .Lchacha_blocks_avx2_atleast512
+       cmp $256, %rcx
+       jae .Lchacha_blocks_avx2_atleast256
+       jmp .Lchacha_blocks_avx2_below256
+       .p2align 6,,63
+.Lchacha_blocks_avx2_atleast512:
+       movq 48(%rsp), %rax
+       leaq 1(%rax), %r8
+       leaq 2(%rax), %r9
+       leaq 3(%rax), %r10
+       leaq 4(%rax), %rbx
+       leaq 5(%rax), %r11
+       leaq 6(%rax), %r12
+       leaq 7(%rax), %r13
+       leaq 8(%rax), %r14
+       movl %eax, 128(%rsp)
+       movl %r8d, 4+128(%rsp)
+       movl %r9d, 8+128(%rsp)
+       movl %r10d, 12+128(%rsp)
+       movl %ebx, 16+128(%rsp)
+       movl %r11d, 20+128(%rsp)
+       movl %r12d, 24+128(%rsp)
+       movl %r13d, 28+128(%rsp)
+       shrq $32, %rax
+       shrq $32, %r8
+       shrq $32, %r9
+       shrq $32, %r10
+       shrq $32, %rbx
+       shrq $32, %r11
+       shrq $32, %r12
+       shrq $32, %r13
+       movl %eax, 160(%rsp)
+       movl %r8d, 4+160(%rsp)
+       movl %r9d, 8+160(%rsp)
+       movl %r10d, 12+160(%rsp)
+       movl %ebx, 16+160(%rsp)
+       movl %r11d, 20+160(%rsp)
+       movl %r12d, 24+160(%rsp)
+       movl %r13d, 28+160(%rsp)
+       movq %r14, 48(%rsp)
+       movq 64(%rsp), %rax
+       vpbroadcastd 0(%rsp), %ymm0
+       vpbroadcastd 4+0(%rsp), %ymm1
+       vpbroadcastd 8+0(%rsp), %ymm2
+       vpbroadcastd 12+0(%rsp), %ymm3
+       vpbroadcastd 16(%rsp), %ymm4
+       vpbroadcastd 4+16(%rsp), %ymm5
+       vpbroadcastd 8+16(%rsp), %ymm6
+       vpbroadcastd 12+16(%rsp), %ymm7
+       vpbroadcastd 32(%rsp), %ymm8
+       vpbroadcastd 4+32(%rsp), %ymm9
+       vpbroadcastd 8+32(%rsp), %ymm10
+       vpbroadcastd 12+32(%rsp), %ymm11
+       vpbroadcastd 8+48(%rsp), %ymm14
+       vpbroadcastd 12+48(%rsp), %ymm15
+       vmovdqa 128(%rsp), %ymm12
+       vmovdqa 160(%rsp), %ymm13
+.Lchacha_blocks_avx2_mainloop1:
+       vpaddd %ymm0, %ymm4, %ymm0
+       vpaddd %ymm1, %ymm5, %ymm1
+       vpxor %ymm12, %ymm0, %ymm12
+       vpxor %ymm13, %ymm1, %ymm13
+       vpaddd %ymm2, %ymm6, %ymm2
+       vpaddd %ymm3, %ymm7, %ymm3
+       vpxor %ymm14, %ymm2, %ymm14
+       vpxor %ymm15, %ymm3, %ymm15
+       vpshufb 448(%rsp), %ymm12, %ymm12
+       vpshufb 448(%rsp), %ymm13, %ymm13
+       vpaddd %ymm8, %ymm12, %ymm8
+       vpaddd %ymm9, %ymm13, %ymm9
+       vpshufb 448(%rsp), %ymm14, %ymm14
+       vpshufb 448(%rsp), %ymm15, %ymm15
+       vpaddd %ymm10, %ymm14, %ymm10
+       vpaddd %ymm11, %ymm15, %ymm11
+       vmovdqa %ymm12, 96(%rsp)
+       vpxor %ymm4, %ymm8, %ymm4
+       vpxor %ymm5, %ymm9, %ymm5
+       vpslld $ 12, %ymm4, %ymm12
+       vpsrld $20, %ymm4, %ymm4
+       vpxor %ymm4, %ymm12, %ymm4
+       vpslld $ 12, %ymm5, %ymm12
+       vpsrld $20, %ymm5, %ymm5
+       vpxor %ymm5, %ymm12, %ymm5
+       vpxor %ymm6, %ymm10, %ymm6
+       vpxor %ymm7, %ymm11, %ymm7
+       vpslld $ 12, %ymm6, %ymm12
+       vpsrld $20, %ymm6, %ymm6
+       vpxor %ymm6, %ymm12, %ymm6
+       vpslld $ 12, %ymm7, %ymm12
+       vpsrld $20, %ymm7, %ymm7
+       vpxor %ymm7, %ymm12, %ymm7
+       vpaddd %ymm0, %ymm4, %ymm0
+       vpaddd %ymm1, %ymm5, %ymm1
+       vpxor 96(%rsp), %ymm0, %ymm12
+       vpxor %ymm13, %ymm1, %ymm13
+       vpaddd %ymm2, %ymm6, %ymm2
+       vpaddd %ymm3, %ymm7, %ymm3
+       vpxor %ymm14, %ymm2, %ymm14
+       vpxor %ymm15, %ymm3, %ymm15
+       vpshufb 480(%rsp), %ymm12, %ymm12
+       vpshufb 480(%rsp), %ymm13, %ymm13
+       vpaddd %ymm8, %ymm12, %ymm8
+       vpaddd %ymm9, %ymm13, %ymm9
+       vpshufb 480(%rsp), %ymm14, %ymm14
+       vpshufb 480(%rsp), %ymm15, %ymm15
+       vpaddd %ymm10, %ymm14, %ymm10
+       vpaddd %ymm11, %ymm15, %ymm11
+       vmovdqa %ymm12, 96(%rsp)
+       vpxor %ymm4, %ymm8, %ymm4
+       vpxor %ymm5, %ymm9, %ymm5
+       vpslld $ 7, %ymm4, %ymm12
+       vpsrld $25, %ymm4, %ymm4
+       vpxor %ymm4, %ymm12, %ymm4
+       vpslld $ 7, %ymm5, %ymm12
+       vpsrld $25, %ymm5, %ymm5
+       vpxor %ymm5, %ymm12, %ymm5
+       vpxor %ymm6, %ymm10, %ymm6
+       vpxor %ymm7, %ymm11, %ymm7
+       vpslld $ 7, %ymm6, %ymm12
+       vpsrld $25, %ymm6, %ymm6
+       vpxor %ymm6, %ymm12, %ymm6
+       vpslld $ 7, %ymm7, %ymm12
+       vpsrld $25, %ymm7, %ymm7
+       vpxor %ymm7, %ymm12, %ymm7
+       vpaddd %ymm0, %ymm5, %ymm0
+       vpaddd %ymm1, %ymm6, %ymm1
+       vpxor %ymm15, %ymm0, %ymm15
+       vpxor 96(%rsp), %ymm1, %ymm12
+       vpaddd %ymm2, %ymm7, %ymm2
+       vpaddd %ymm3, %ymm4, %ymm3
+       vpxor %ymm13, %ymm2, %ymm13
+       vpxor %ymm14, %ymm3, %ymm14
+       vpshufb 448(%rsp), %ymm15, %ymm15
+       vpshufb 448(%rsp), %ymm12, %ymm12
+       vpaddd %ymm10, %ymm15, %ymm10
+       vpaddd %ymm11, %ymm12, %ymm11
+       vpshufb 448(%rsp), %ymm13, %ymm13
+       vpshufb 448(%rsp), %ymm14, %ymm14
+       vpaddd %ymm8, %ymm13, %ymm8
+       vpaddd %ymm9, %ymm14, %ymm9
+       vmovdqa %ymm15, 96(%rsp)
+       vpxor %ymm5, %ymm10, %ymm5
+       vpxor %ymm6, %ymm11, %ymm6
+       vpslld $ 12, %ymm5, %ymm15
+       vpsrld $20, %ymm5, %ymm5
+       vpxor %ymm5, %ymm15, %ymm5
+       vpslld $ 12, %ymm6, %ymm15
+       vpsrld $20, %ymm6, %ymm6
+       vpxor %ymm6, %ymm15, %ymm6
+       vpxor %ymm7, %ymm8, %ymm7
+       vpxor %ymm4, %ymm9, %ymm4
+       vpslld $ 12, %ymm7, %ymm15
+       vpsrld $20, %ymm7, %ymm7
+       vpxor %ymm7, %ymm15, %ymm7
+       vpslld $ 12, %ymm4, %ymm15
+       vpsrld $20, %ymm4, %ymm4
+       vpxor %ymm4, %ymm15, %ymm4
+       vpaddd %ymm0, %ymm5, %ymm0
+       vpaddd %ymm1, %ymm6, %ymm1
+       vpxor 96(%rsp), %ymm0, %ymm15
+       vpxor %ymm12, %ymm1, %ymm12
+       vpaddd %ymm2, %ymm7, %ymm2
+       vpaddd %ymm3, %ymm4, %ymm3
+       vpxor %ymm13, %ymm2, %ymm13
+       vpxor %ymm14, %ymm3, %ymm14
+       vpshufb 480(%rsp), %ymm15, %ymm15
+       vpshufb 480(%rsp), %ymm12, %ymm12
+       vpaddd %ymm10, %ymm15, %ymm10
+       vpaddd %ymm11, %ymm12, %ymm11
+       vpshufb 480(%rsp), %ymm13, %ymm13
+       vpshufb 480(%rsp), %ymm14, %ymm14
+       vpaddd %ymm8, %ymm13, %ymm8
+       vpaddd %ymm9, %ymm14, %ymm9
+       vmovdqa %ymm15, 96(%rsp)
+       vpxor %ymm5, %ymm10, %ymm5
+       vpxor %ymm6, %ymm11, %ymm6
+       vpslld $ 7, %ymm5, %ymm15
+       vpsrld $25, %ymm5, %ymm5
+       vpxor %ymm5, %ymm15, %ymm5
+       vpslld $ 7, %ymm6, %ymm15
+       vpsrld $25, %ymm6, %ymm6
+       vpxor %ymm6, %ymm15, %ymm6
+       vpxor %ymm7, %ymm8, %ymm7
+       vpxor %ymm4, %ymm9, %ymm4
+       vpslld $ 7, %ymm7, %ymm15
+       vpsrld $25, %ymm7, %ymm7
+       vpxor %ymm7, %ymm15, %ymm7
+       vpslld $ 7, %ymm4, %ymm15
+       vpsrld $25, %ymm4, %ymm4
+       vpxor %ymm4, %ymm15, %ymm4
+       vmovdqa 96(%rsp), %ymm15
+       subq $2, %rax
+       jnz .Lchacha_blocks_avx2_mainloop1
+       vmovdqa %ymm8, 192(%rsp)
+       vmovdqa %ymm9, 224(%rsp)
+       vmovdqa %ymm10, 256(%rsp)
+       vmovdqa %ymm11, 288(%rsp)
+       vmovdqa %ymm12, 320(%rsp)
+       vmovdqa %ymm13, 352(%rsp)
+       vmovdqa %ymm14, 384(%rsp)
+       vmovdqa %ymm15, 416(%rsp)
+       vpbroadcastd 0(%rsp), %ymm8
+       vpbroadcastd 4+0(%rsp), %ymm9
+       vpbroadcastd 8+0(%rsp), %ymm10
+       vpbroadcastd 12+0(%rsp), %ymm11
+       vpbroadcastd 16(%rsp), %ymm12
+       vpbroadcastd 4+16(%rsp), %ymm13
+       vpbroadcastd 8+16(%rsp), %ymm14
+       vpbroadcastd 12+16(%rsp), %ymm15
+       vpaddd %ymm8, %ymm0, %ymm0
+       vpaddd %ymm9, %ymm1, %ymm1
+       vpaddd %ymm10, %ymm2, %ymm2
+       vpaddd %ymm11, %ymm3, %ymm3
+       vpaddd %ymm12, %ymm4, %ymm4
+       vpaddd %ymm13, %ymm5, %ymm5
+       vpaddd %ymm14, %ymm6, %ymm6
+       vpaddd %ymm15, %ymm7, %ymm7
+       vpunpckldq %ymm1, %ymm0, %ymm8
+       vpunpckldq %ymm3, %ymm2, %ymm9
+       vpunpckhdq %ymm1, %ymm0, %ymm12
+       vpunpckhdq %ymm3, %ymm2, %ymm13
+       vpunpckldq %ymm5, %ymm4, %ymm10
+       vpunpckldq %ymm7, %ymm6, %ymm11
+       vpunpckhdq %ymm5, %ymm4, %ymm14
+       vpunpckhdq %ymm7, %ymm6, %ymm15
+       vpunpcklqdq %ymm9, %ymm8, %ymm0
+       vpunpcklqdq %ymm11, %ymm10, %ymm1
+       vpunpckhqdq %ymm9, %ymm8, %ymm2
+       vpunpckhqdq %ymm11, %ymm10, %ymm3
+       vpunpcklqdq %ymm13, %ymm12, %ymm4
+       vpunpcklqdq %ymm15, %ymm14, %ymm5
+       vpunpckhqdq %ymm13, %ymm12, %ymm6
+       vpunpckhqdq %ymm15, %ymm14, %ymm7
+       vperm2i128 $0x20, %ymm1, %ymm0, %ymm8
+       vperm2i128 $0x20, %ymm3, %ymm2, %ymm9
+       vperm2i128 $0x31, %ymm1, %ymm0, %ymm12
+       vperm2i128 $0x31, %ymm3, %ymm2, %ymm13
+       vperm2i128 $0x20, %ymm5, %ymm4, %ymm10
+       vperm2i128 $0x20, %ymm7, %ymm6, %ymm11
+       vperm2i128 $0x31, %ymm5, %ymm4, %ymm14
+       vperm2i128 $0x31, %ymm7, %ymm6, %ymm15
+       andq %rsi, %rsi
+       jz .Lchacha_blocks_avx2_noinput1
+       vpxor 0(%rsi), %ymm8, %ymm8
+       vpxor 64(%rsi), %ymm9, %ymm9
+       vpxor 128(%rsi), %ymm10, %ymm10
+       vpxor 192(%rsi), %ymm11, %ymm11
+       vpxor 256(%rsi), %ymm12, %ymm12
+       vpxor 320(%rsi), %ymm13, %ymm13
+       vpxor 384(%rsi), %ymm14, %ymm14
+       vpxor 448(%rsi), %ymm15, %ymm15
+       vmovdqu %ymm8, 0(%rdx)
+       vmovdqu %ymm9, 64(%rdx)
+       vmovdqu %ymm10, 128(%rdx)
+       vmovdqu %ymm11, 192(%rdx)
+       vmovdqu %ymm12, 256(%rdx)
+       vmovdqu %ymm13, 320(%rdx)
+       vmovdqu %ymm14, 384(%rdx)
+       vmovdqu %ymm15, 448(%rdx)
+       vmovdqa 192(%rsp), %ymm0
+       vmovdqa 224(%rsp), %ymm1
+       vmovdqa 256(%rsp), %ymm2
+       vmovdqa 288(%rsp), %ymm3
+       vmovdqa 320(%rsp), %ymm4
+       vmovdqa 352(%rsp), %ymm5
+       vmovdqa 384(%rsp), %ymm6
+       vmovdqa 416(%rsp), %ymm7
+       vpbroadcastd 32(%rsp), %ymm8
+       vpbroadcastd 4+32(%rsp), %ymm9
+       vpbroadcastd 8+32(%rsp), %ymm10
+       vpbroadcastd 12+32(%rsp), %ymm11
+       vmovdqa 128(%rsp), %ymm12
+       vmovdqa 160(%rsp), %ymm13
+       vpbroadcastd 8+48(%rsp), %ymm14
+       vpbroadcastd 12+48(%rsp), %ymm15
+       vpaddd %ymm8, %ymm0, %ymm0
+       vpaddd %ymm9, %ymm1, %ymm1
+       vpaddd %ymm10, %ymm2, %ymm2
+       vpaddd %ymm11, %ymm3, %ymm3
+       vpaddd %ymm12, %ymm4, %ymm4
+       vpaddd %ymm13, %ymm5, %ymm5
+       vpaddd %ymm14, %ymm6, %ymm6
+       vpaddd %ymm15, %ymm7, %ymm7
+       vpunpckldq %ymm1, %ymm0, %ymm8
+       vpunpckldq %ymm3, %ymm2, %ymm9
+       vpunpckhdq %ymm1, %ymm0, %ymm12
+       vpunpckhdq %ymm3, %ymm2, %ymm13
+       vpunpckldq %ymm5, %ymm4, %ymm10
+       vpunpckldq %ymm7, %ymm6, %ymm11
+       vpunpckhdq %ymm5, %ymm4, %ymm14
+       vpunpckhdq %ymm7, %ymm6, %ymm15
+       vpunpcklqdq %ymm9, %ymm8, %ymm0
+       vpunpcklqdq %ymm11, %ymm10, %ymm1
+       vpunpckhqdq %ymm9, %ymm8, %ymm2
+       vpunpckhqdq %ymm11, %ymm10, %ymm3
+       vpunpcklqdq %ymm13, %ymm12, %ymm4
+       vpunpcklqdq %ymm15, %ymm14, %ymm5
+       vpunpckhqdq %ymm13, %ymm12, %ymm6
+       vpunpckhqdq %ymm15, %ymm14, %ymm7
+       vperm2i128 $0x20, %ymm1, %ymm0, %ymm8
+       vperm2i128 $0x20, %ymm3, %ymm2, %ymm9
+       vperm2i128 $0x31, %ymm1, %ymm0, %ymm12
+       vperm2i128 $0x31, %ymm3, %ymm2, %ymm13
+       vperm2i128 $0x20, %ymm5, %ymm4, %ymm10
+       vperm2i128 $0x20, %ymm7, %ymm6, %ymm11
+       vperm2i128 $0x31, %ymm5, %ymm4, %ymm14
+       vperm2i128 $0x31, %ymm7, %ymm6, %ymm15
+       vpxor 32(%rsi), %ymm8, %ymm8
+       vpxor 96(%rsi), %ymm9, %ymm9
+       vpxor 160(%rsi), %ymm10, %ymm10
+       vpxor 224(%rsi), %ymm11, %ymm11
+       vpxor 288(%rsi), %ymm12, %ymm12
+       vpxor 352(%rsi), %ymm13, %ymm13
+       vpxor 416(%rsi), %ymm14, %ymm14
+       vpxor 480(%rsi), %ymm15, %ymm15
+       vmovdqu %ymm8, 32(%rdx)
+       vmovdqu %ymm9, 96(%rdx)
+       vmovdqu %ymm10, 160(%rdx)
+       vmovdqu %ymm11, 224(%rdx)
+       vmovdqu %ymm12, 288(%rdx)
+       vmovdqu %ymm13, 352(%rdx)
+       vmovdqu %ymm14, 416(%rdx)
+       vmovdqu %ymm15, 480(%rdx)
+       addq $512, %rsi
+       jmp .Lchacha_blocks_avx2_mainloop1_cont
+.Lchacha_blocks_avx2_noinput1:
+       vmovdqu %ymm8, 0(%rdx)
+       vmovdqu %ymm9, 64(%rdx)
+       vmovdqu %ymm10, 128(%rdx)
+       vmovdqu %ymm11, 192(%rdx)
+       vmovdqu %ymm12, 256(%rdx)
+       vmovdqu %ymm13, 320(%rdx)
+       vmovdqu %ymm14, 384(%rdx)
+       vmovdqu %ymm15, 448(%rdx)
+       vmovdqa 192(%rsp), %ymm0
+       vmovdqa 224(%rsp), %ymm1
+       vmovdqa 256(%rsp), %ymm2
+       vmovdqa 288(%rsp), %ymm3
+       vmovdqa 320(%rsp), %ymm4
+       vmovdqa 352(%rsp), %ymm5
+       vmovdqa 384(%rsp), %ymm6
+       vmovdqa 416(%rsp), %ymm7
+       vpbroadcastd 32(%rsp), %ymm8
+       vpbroadcastd 4+32(%rsp), %ymm9
+       vpbroadcastd 8+32(%rsp), %ymm10
+       vpbroadcastd 12+32(%rsp), %ymm11
+       vmovdqa 128(%rsp), %ymm12
+       vmovdqa 160(%rsp), %ymm13
+       vpbroadcastd 8+48(%rsp), %ymm14
+       vpbroadcastd 12+48(%rsp), %ymm15
+       vpaddd %ymm8, %ymm0, %ymm0
+       vpaddd %ymm9, %ymm1, %ymm1
+       vpaddd %ymm10, %ymm2, %ymm2
+       vpaddd %ymm11, %ymm3, %ymm3
+       vpaddd %ymm12, %ymm4, %ymm4
+       vpaddd %ymm13, %ymm5, %ymm5
+       vpaddd %ymm14, %ymm6, %ymm6
+       vpaddd %ymm15, %ymm7, %ymm7
+       vpunpckldq %ymm1, %ymm0, %ymm8
+       vpunpckldq %ymm3, %ymm2, %ymm9
+       vpunpckhdq %ymm1, %ymm0, %ymm12
+       vpunpckhdq %ymm3, %ymm2, %ymm13
+       vpunpckldq %ymm5, %ymm4, %ymm10
+       vpunpckldq %ymm7, %ymm6, %ymm11
+       vpunpckhdq %ymm5, %ymm4, %ymm14
+       vpunpckhdq %ymm7, %ymm6, %ymm15
+       vpunpcklqdq %ymm9, %ymm8, %ymm0
+       vpunpcklqdq %ymm11, %ymm10, %ymm1
+       vpunpckhqdq %ymm9, %ymm8, %ymm2
+       vpunpckhqdq %ymm11, %ymm10, %ymm3
+       vpunpcklqdq %ymm13, %ymm12, %ymm4
+       vpunpcklqdq %ymm15, %ymm14, %ymm5
+       vpunpckhqdq %ymm13, %ymm12, %ymm6
+       vpunpckhqdq %ymm15, %ymm14, %ymm7
+       vperm2i128 $0x20, %ymm1, %ymm0, %ymm8
+       vperm2i128 $0x20, %ymm3, %ymm2, %ymm9
+       vperm2i128 $0x31, %ymm1, %ymm0, %ymm12
+       vperm2i128 $0x31, %ymm3, %ymm2, %ymm13
+       vperm2i128 $0x20, %ymm5, %ymm4, %ymm10
+       vperm2i128 $0x20, %ymm7, %ymm6, %ymm11
+       vperm2i128 $0x31, %ymm5, %ymm4, %ymm14
+       vperm2i128 $0x31, %ymm7, %ymm6, %ymm15
+       vmovdqu %ymm8, 32(%rdx)
+       vmovdqu %ymm9, 96(%rdx)
+       vmovdqu %ymm10, 160(%rdx)
+       vmovdqu %ymm11, 224(%rdx)
+       vmovdqu %ymm12, 288(%rdx)
+       vmovdqu %ymm13, 352(%rdx)
+       vmovdqu %ymm14, 416(%rdx)
+       vmovdqu %ymm15, 480(%rdx)
+.Lchacha_blocks_avx2_mainloop1_cont:
+       addq $512, %rdx
+       subq $512, %rcx
+       cmp $512, %rcx
+       jae .Lchacha_blocks_avx2_atleast512
+       cmp $256, %rcx
+       jb .Lchacha_blocks_avx2_below256_fixup
+.Lchacha_blocks_avx2_atleast256:
+       movq 48(%rsp), %rax
+       leaq 1(%rax), %r8
+       leaq 2(%rax), %r9
+       leaq 3(%rax), %r10
+       leaq 4(%rax), %rbx
+       movl %eax, 128(%rsp)
+       movl %r8d, 4+128(%rsp)
+       movl %r9d, 8+128(%rsp)
+       movl %r10d, 12+128(%rsp)
+       shrq $32, %rax
+       shrq $32, %r8
+       shrq $32, %r9
+       shrq $32, %r10
+       movl %eax, 160(%rsp)
+       movl %r8d, 4+160(%rsp)
+       movl %r9d, 8+160(%rsp)
+       movl %r10d, 12+160(%rsp)
+       movq %rbx, 48(%rsp)
+       movq 64(%rsp), %rax
+       vpbroadcastd 0(%rsp), %xmm0
+       vpbroadcastd 4+0(%rsp), %xmm1
+       vpbroadcastd 8+0(%rsp), %xmm2
+       vpbroadcastd 12+0(%rsp), %xmm3
+       vpbroadcastd 16(%rsp), %xmm4
+       vpbroadcastd 4+16(%rsp), %xmm5
+       vpbroadcastd 8+16(%rsp), %xmm6
+       vpbroadcastd 12+16(%rsp), %xmm7
+       vpbroadcastd 32(%rsp), %xmm8
+       vpbroadcastd 4+32(%rsp), %xmm9
+       vpbroadcastd 8+32(%rsp), %xmm10
+       vpbroadcastd 12+32(%rsp), %xmm11
+       vmovdqa 128(%rsp), %xmm12
+       vmovdqa 160(%rsp), %xmm13
+       vpbroadcastd 8+48(%rsp), %xmm14
+       vpbroadcastd 12+48(%rsp), %xmm15
+.Lchacha_blocks_avx2_mainloop2:
+       vpaddd %xmm0, %xmm4, %xmm0
+       vpaddd %xmm1, %xmm5, %xmm1
+       vpxor %xmm12, %xmm0, %xmm12
+       vpxor %xmm13, %xmm1, %xmm13
+       vpaddd %xmm2, %xmm6, %xmm2
+       vpaddd %xmm3, %xmm7, %xmm3
+       vpxor %xmm14, %xmm2, %xmm14
+       vpxor %xmm15, %xmm3, %xmm15
+       vpshufb 448(%rsp), %xmm12, %xmm12
+       vpshufb 448(%rsp), %xmm13, %xmm13
+       vpaddd %xmm8, %xmm12, %xmm8
+       vpaddd %xmm9, %xmm13, %xmm9
+       vpshufb 448(%rsp), %xmm14, %xmm14
+       vpshufb 448(%rsp), %xmm15, %xmm15
+       vpaddd %xmm10, %xmm14, %xmm10
+       vpaddd %xmm11, %xmm15, %xmm11
+       vmovdqa %xmm12, 96(%rsp)
+       vpxor %xmm4, %xmm8, %xmm4
+       vpxor %xmm5, %xmm9, %xmm5
+       vpslld $ 12, %xmm4, %xmm12
+       vpsrld $20, %xmm4, %xmm4
+       vpxor %xmm4, %xmm12, %xmm4
+       vpslld $ 12, %xmm5, %xmm12
+       vpsrld $20, %xmm5, %xmm5
+       vpxor %xmm5, %xmm12, %xmm5
+       vpxor %xmm6, %xmm10, %xmm6
+       vpxor %xmm7, %xmm11, %xmm7
+       vpslld $ 12, %xmm6, %xmm12
+       vpsrld $20, %xmm6, %xmm6
+       vpxor %xmm6, %xmm12, %xmm6
+       vpslld $ 12, %xmm7, %xmm12
+       vpsrld $20, %xmm7, %xmm7
+       vpxor %xmm7, %xmm12, %xmm7
+       vpaddd %xmm0, %xmm4, %xmm0
+       vpaddd %xmm1, %xmm5, %xmm1
+       vpxor 96(%rsp), %xmm0, %xmm12
+       vpxor %xmm13, %xmm1, %xmm13
+       vpaddd %xmm2, %xmm6, %xmm2
+       vpaddd %xmm3, %xmm7, %xmm3
+       vpxor %xmm14, %xmm2, %xmm14
+       vpxor %xmm15, %xmm3, %xmm15
+       vpshufb 480(%rsp), %xmm12, %xmm12
+       vpshufb 480(%rsp), %xmm13, %xmm13
+       vpaddd %xmm8, %xmm12, %xmm8
+       vpaddd %xmm9, %xmm13, %xmm9
+       vpshufb 480(%rsp), %xmm14, %xmm14
+       vpshufb 480(%rsp), %xmm15, %xmm15
+       vpaddd %xmm10, %xmm14, %xmm10
+       vpaddd %xmm11, %xmm15, %xmm11
+       vmovdqa %xmm12, 96(%rsp)
+       vpxor %xmm4, %xmm8, %xmm4
+       vpxor %xmm5, %xmm9, %xmm5
+       vpslld $ 7, %xmm4, %xmm12
+       vpsrld $25, %xmm4, %xmm4
+       vpxor %xmm4, %xmm12, %xmm4
+       vpslld $ 7, %xmm5, %xmm12
+       vpsrld $25, %xmm5, %xmm5
+       vpxor %xmm5, %xmm12, %xmm5
+       vpxor %xmm6, %xmm10, %xmm6
+       vpxor %xmm7, %xmm11, %xmm7
+       vpslld $ 7, %xmm6, %xmm12
+       vpsrld $25, %xmm6, %xmm6
+       vpxor %xmm6, %xmm12, %xmm6
+       vpslld $ 7, %xmm7, %xmm12
+       vpsrld $25, %xmm7, %xmm7
+       vpxor %xmm7, %xmm12, %xmm7
+       vpaddd %xmm0, %xmm5, %xmm0
+       vpaddd %xmm1, %xmm6, %xmm1
+       vpxor %xmm15, %xmm0, %xmm15
+       vpxor 96(%rsp), %xmm1, %xmm12
+       vpaddd %xmm2, %xmm7, %xmm2
+       vpaddd %xmm3, %xmm4, %xmm3
+       vpxor %xmm13, %xmm2, %xmm13
+       vpxor %xmm14, %xmm3, %xmm14
+       vpshufb 448(%rsp), %xmm15, %xmm15
+       vpshufb 448(%rsp), %xmm12, %xmm12
+       vpaddd %xmm10, %xmm15, %xmm10
+       vpaddd %xmm11, %xmm12, %xmm11
+       vpshufb 448(%rsp), %xmm13, %xmm13
+       vpshufb 448(%rsp), %xmm14, %xmm14
+       vpaddd %xmm8, %xmm13, %xmm8
+       vpaddd %xmm9, %xmm14, %xmm9
+       vmovdqa %xmm15, 96(%rsp)
+       vpxor %xmm5, %xmm10, %xmm5
+       vpxor %xmm6, %xmm11, %xmm6
+       vpslld $ 12, %xmm5, %xmm15
+       vpsrld $20, %xmm5, %xmm5
+       vpxor %xmm5, %xmm15, %xmm5
+       vpslld $ 12, %xmm6, %xmm15
+       vpsrld $20, %xmm6, %xmm6
+       vpxor %xmm6, %xmm15, %xmm6
+       vpxor %xmm7, %xmm8, %xmm7
+       vpxor %xmm4, %xmm9, %xmm4
+       vpslld $ 12, %xmm7, %xmm15
+       vpsrld $20, %xmm7, %xmm7
+       vpxor %xmm7, %xmm15, %xmm7
+       vpslld $ 12, %xmm4, %xmm15
+       vpsrld $20, %xmm4, %xmm4
+       vpxor %xmm4, %xmm15, %xmm4
+       vpaddd %xmm0, %xmm5, %xmm0
+       vpaddd %xmm1, %xmm6, %xmm1
+       vpxor 96(%rsp), %xmm0, %xmm15
+       vpxor %xmm12, %xmm1, %xmm12
+       vpaddd %xmm2, %xmm7, %xmm2
+       vpaddd %xmm3, %xmm4, %xmm3
+       vpxor %xmm13, %xmm2, %xmm13
+       vpxor %xmm14, %xmm3, %xmm14
+       vpshufb 480(%rsp), %xmm15, %xmm15
+       vpshufb 480(%rsp), %xmm12, %xmm12
+       vpaddd %xmm10, %xmm15, %xmm10
+       vpaddd %xmm11, %xmm12, %xmm11
+       vpshufb 480(%rsp), %xmm13, %xmm13
+       vpshufb 480(%rsp), %xmm14, %xmm14
+       vpaddd %xmm8, %xmm13, %xmm8
+       vpaddd %xmm9, %xmm14, %xmm9
+       vmovdqa %xmm15, 96(%rsp)
+       vpxor %xmm5, %xmm10, %xmm5
+       vpxor %xmm6, %xmm11, %xmm6
+       vpslld $ 7, %xmm5, %xmm15
+       vpsrld $25, %xmm5, %xmm5
+       vpxor %xmm5, %xmm15, %xmm5
+       vpslld $ 7, %xmm6, %xmm15
+       vpsrld $25, %xmm6, %xmm6
+       vpxor %xmm6, %xmm15, %xmm6
+       vpxor %xmm7, %xmm8, %xmm7
+       vpxor %xmm4, %xmm9, %xmm4
+       vpslld $ 7, %xmm7, %xmm15
+       vpsrld $25, %xmm7, %xmm7
+       vpxor %xmm7, %xmm15, %xmm7
+       vpslld $ 7, %xmm4, %xmm15
+       vpsrld $25, %xmm4, %xmm4
+       vpxor %xmm4, %xmm15, %xmm4
+       vmovdqa 96(%rsp), %xmm15
+       subq $2, %rax
+       jnz .Lchacha_blocks_avx2_mainloop2
+       vmovdqa %xmm8, 192(%rsp)
+       vmovdqa %xmm9, 208(%rsp)
+       vmovdqa %xmm10, 224(%rsp)
+       vmovdqa %xmm11, 240(%rsp)
+       vmovdqa %xmm12, 256(%rsp)
+       vmovdqa %xmm13, 272(%rsp)
+       vmovdqa %xmm14, 288(%rsp)
+       vmovdqa %xmm15, 304(%rsp)
+       vpbroadcastd 0(%rsp), %xmm8
+       vpbroadcastd 4+0(%rsp), %xmm9
+       vpbroadcastd 8+0(%rsp), %xmm10
+       vpbroadcastd 12+0(%rsp), %xmm11
+       vpbroadcastd 16(%rsp), %xmm12
+       vpbroadcastd 4+16(%rsp), %xmm13
+       vpbroadcastd 8+16(%rsp), %xmm14
+       vpbroadcastd 12+16(%rsp), %xmm15
+       vpaddd %xmm8, %xmm0, %xmm0
+       vpaddd %xmm9, %xmm1, %xmm1
+       vpaddd %xmm10, %xmm2, %xmm2
+       vpaddd %xmm11, %xmm3, %xmm3
+       vpaddd %xmm12, %xmm4, %xmm4
+       vpaddd %xmm13, %xmm5, %xmm5
+       vpaddd %xmm14, %xmm6, %xmm6
+       vpaddd %xmm15, %xmm7, %xmm7
+       vpunpckldq %xmm1, %xmm0, %xmm8
+       vpunpckldq %xmm3, %xmm2, %xmm9
+       vpunpckhdq %xmm1, %xmm0, %xmm12
+       vpunpckhdq %xmm3, %xmm2, %xmm13
+       vpunpckldq %xmm5, %xmm4, %xmm10
+       vpunpckldq %xmm7, %xmm6, %xmm11
+       vpunpckhdq %xmm5, %xmm4, %xmm14
+       vpunpckhdq %xmm7, %xmm6, %xmm15
+       vpunpcklqdq %xmm9, %xmm8, %xmm0
+       vpunpcklqdq %xmm11, %xmm10, %xmm1
+       vpunpckhqdq %xmm9, %xmm8, %xmm2
+       vpunpckhqdq %xmm11, %xmm10, %xmm3
+       vpunpcklqdq %xmm13, %xmm12, %xmm4
+       vpunpcklqdq %xmm15, %xmm14, %xmm5
+       vpunpckhqdq %xmm13, %xmm12, %xmm6
+       vpunpckhqdq %xmm15, %xmm14, %xmm7
+       andq %rsi, %rsi
+       jz .Lchacha_blocks_avx2_noinput2
+       vpxor 0(%rsi), %xmm0, %xmm0
+       vpxor 16(%rsi), %xmm1, %xmm1
+       vpxor 64(%rsi), %xmm2, %xmm2
+       vpxor 80(%rsi), %xmm3, %xmm3
+       vpxor 128(%rsi), %xmm4, %xmm4
+       vpxor 144(%rsi), %xmm5, %xmm5
+       vpxor 192(%rsi), %xmm6, %xmm6
+       vpxor 208(%rsi), %xmm7, %xmm7
+       vmovdqu %xmm0, 0(%rdx)
+       vmovdqu %xmm1, 16(%rdx)
+       vmovdqu %xmm2, 64(%rdx)
+       vmovdqu %xmm3, 80(%rdx)
+       vmovdqu %xmm4, 128(%rdx)
+       vmovdqu %xmm5, 144(%rdx)
+       vmovdqu %xmm6, 192(%rdx)
+       vmovdqu %xmm7, 208(%rdx)
+       vmovdqa 192(%rsp), %xmm0
+       vmovdqa 208(%rsp), %xmm1
+       vmovdqa 224(%rsp), %xmm2
+       vmovdqa 240(%rsp), %xmm3
+       vmovdqa 256(%rsp), %xmm4
+       vmovdqa 272(%rsp), %xmm5
+       vmovdqa 288(%rsp), %xmm6
+       vmovdqa 304(%rsp), %xmm7
+       vpbroadcastd 32(%rsp), %xmm8
+       vpbroadcastd 4+32(%rsp), %xmm9
+       vpbroadcastd 8+32(%rsp), %xmm10
+       vpbroadcastd 12+32(%rsp), %xmm11
+       vmovdqa 128(%rsp), %xmm12
+       vmovdqa 160(%rsp), %xmm13
+       vpbroadcastd 8+48(%rsp), %xmm14
+       vpbroadcastd 12+48(%rsp), %xmm15
+       vpaddd %xmm8, %xmm0, %xmm0
+       vpaddd %xmm9, %xmm1, %xmm1
+       vpaddd %xmm10, %xmm2, %xmm2
+       vpaddd %xmm11, %xmm3, %xmm3
+       vpaddd %xmm12, %xmm4, %xmm4
+       vpaddd %xmm13, %xmm5, %xmm5
+       vpaddd %xmm14, %xmm6, %xmm6
+       vpaddd %xmm15, %xmm7, %xmm7
+       vpunpckldq %xmm1, %xmm0, %xmm8
+       vpunpckldq %xmm3, %xmm2, %xmm9
+       vpunpckhdq %xmm1, %xmm0, %xmm12
+       vpunpckhdq %xmm3, %xmm2, %xmm13
+       vpunpckldq %xmm5, %xmm4, %xmm10
+       vpunpckldq %xmm7, %xmm6, %xmm11
+       vpunpckhdq %xmm5, %xmm4, %xmm14
+       vpunpckhdq %xmm7, %xmm6, %xmm15
+       vpunpcklqdq %xmm9, %xmm8, %xmm0
+       vpunpcklqdq %xmm11, %xmm10, %xmm1
+       vpunpckhqdq %xmm9, %xmm8, %xmm2
+       vpunpckhqdq %xmm11, %xmm10, %xmm3
+       vpunpcklqdq %xmm13, %xmm12, %xmm4
+       vpunpcklqdq %xmm15, %xmm14, %xmm5
+       vpunpckhqdq %xmm13, %xmm12, %xmm6
+       vpunpckhqdq %xmm15, %xmm14, %xmm7
+       vpxor 32(%rsi), %xmm0, %xmm0
+       vpxor 48(%rsi), %xmm1, %xmm1
+       vpxor 96(%rsi), %xmm2, %xmm2
+       vpxor 112(%rsi), %xmm3, %xmm3
+       vpxor 160(%rsi), %xmm4, %xmm4
+       vpxor 176(%rsi), %xmm5, %xmm5
+       vpxor 224(%rsi), %xmm6, %xmm6
+       vpxor 240(%rsi), %xmm7, %xmm7
+       vmovdqu %xmm0, 32(%rdx)
+       vmovdqu %xmm1, 48(%rdx)
+       vmovdqu %xmm2, 96(%rdx)
+       vmovdqu %xmm3, 112(%rdx)
+       vmovdqu %xmm4, 160(%rdx)
+       vmovdqu %xmm5, 176(%rdx)
+       vmovdqu %xmm6, 224(%rdx)
+       vmovdqu %xmm7, 240(%rdx)
+       addq $256, %rsi
+       jmp .Lchacha_blocks_avx2_mainloop2_cont
+.Lchacha_blocks_avx2_noinput2:
+       vmovdqu %xmm0, 0(%rdx)
+       vmovdqu %xmm1, 16(%rdx)
+       vmovdqu %xmm2, 64(%rdx)
+       vmovdqu %xmm3, 80(%rdx)
+       vmovdqu %xmm4, 128(%rdx)
+       vmovdqu %xmm5, 144(%rdx)
+       vmovdqu %xmm6, 192(%rdx)
+       vmovdqu %xmm7, 208(%rdx)
+       vmovdqa 192(%rsp), %xmm0
+       vmovdqa 208(%rsp), %xmm1
+       vmovdqa 224(%rsp), %xmm2
+       vmovdqa 240(%rsp), %xmm3
+       vmovdqa 256(%rsp), %xmm4
+       vmovdqa 272(%rsp), %xmm5
+       vmovdqa 288(%rsp), %xmm6
+       vmovdqa 304(%rsp), %xmm7
+       vpbroadcastd 32(%rsp), %xmm8
+       vpbroadcastd 4+32(%rsp), %xmm9
+       vpbroadcastd 8+32(%rsp), %xmm10
+       vpbroadcastd 12+32(%rsp), %xmm11
+       vmovdqa 128(%rsp), %xmm12
+       vmovdqa 160(%rsp), %xmm13
+       vpbroadcastd 8+48(%rsp), %xmm14
+       vpbroadcastd 12+48(%rsp), %xmm15
+       vpaddd %xmm8, %xmm0, %xmm0
+       vpaddd %xmm9, %xmm1, %xmm1
+       vpaddd %xmm10, %xmm2, %xmm2
+       vpaddd %xmm11, %xmm3, %xmm3
+       vpaddd %xmm12, %xmm4, %xmm4
+       vpaddd %xmm13, %xmm5, %xmm5
+       vpaddd %xmm14, %xmm6, %xmm6
+       vpaddd %xmm15, %xmm7, %xmm7
+       vpunpckldq %xmm1, %xmm0, %xmm8
+       vpunpckldq %xmm3, %xmm2, %xmm9
+       vpunpckhdq %xmm1, %xmm0, %xmm12
+       vpunpckhdq %xmm3, %xmm2, %xmm13
+       vpunpckldq %xmm5, %xmm4, %xmm10
+       vpunpckldq %xmm7, %xmm6, %xmm11
+       vpunpckhdq %xmm5, %xmm4, %xmm14
+       vpunpckhdq %xmm7, %xmm6, %xmm15
+       vpunpcklqdq %xmm9, %xmm8, %xmm0
+       vpunpcklqdq %xmm11, %xmm10, %xmm1
+       vpunpckhqdq %xmm9, %xmm8, %xmm2
+       vpunpckhqdq %xmm11, %xmm10, %xmm3
+       vpunpcklqdq %xmm13, %xmm12, %xmm4
+       vpunpcklqdq %xmm15, %xmm14, %xmm5
+       vpunpckhqdq %xmm13, %xmm12, %xmm6
+       vpunpckhqdq %xmm15, %xmm14, %xmm7
+       vmovdqu %xmm0, 32(%rdx)
+       vmovdqu %xmm1, 48(%rdx)
+       vmovdqu %xmm2, 96(%rdx)
+       vmovdqu %xmm3, 112(%rdx)
+       vmovdqu %xmm4, 160(%rdx)
+       vmovdqu %xmm5, 176(%rdx)
+       vmovdqu %xmm6, 224(%rdx)
+       vmovdqu %xmm7, 240(%rdx)
+.Lchacha_blocks_avx2_mainloop2_cont:
+       addq $256, %rdx
+       subq $256, %rcx
+       cmp $256, %rcx
+       jae .Lchacha_blocks_avx2_atleast256
+.Lchacha_blocks_avx2_below256_fixup:
+       vmovdqa 448(%rsp), %xmm6
+       vmovdqa 480(%rsp), %xmm7
+       vmovdqa 0(%rsp), %xmm8
+       vmovdqa 16(%rsp), %xmm9
+       vmovdqa 32(%rsp), %xmm10
+       vmovdqa 48(%rsp), %xmm11
+       movq $1, %r9
+.Lchacha_blocks_avx2_below256:
+       vmovq %r9, %xmm5
+       andq %rcx, %rcx
+       jz .Lchacha_blocks_avx2_done
+       cmpq $64, %rcx
+       jae .Lchacha_blocks_avx2_above63
+       movq %rdx, %r9
+       andq %rsi, %rsi
+       jz .Lchacha_blocks_avx2_noinput3
+       movq %rcx, %r10
+       movq %rsp, %rdx
+       addq %r10, %rsi
+       addq %r10, %rdx
+       negq %r10
+.Lchacha_blocks_avx2_copyinput:
+       movb (%rsi, %r10), %al
+       movb %al, (%rdx, %r10)
+       incq %r10
+       jnz .Lchacha_blocks_avx2_copyinput
+       movq %rsp, %rsi
+.Lchacha_blocks_avx2_noinput3:
+       movq %rsp, %rdx
+.Lchacha_blocks_avx2_above63:
+       vmovdqa %xmm8, %xmm0
+       vmovdqa %xmm9, %xmm1
+       vmovdqa %xmm10, %xmm2
+       vmovdqa %xmm11, %xmm3
+       movq 64(%rsp), %rax
+.Lchacha_blocks_avx2_mainloop3:
+       vpaddd %xmm0, %xmm1, %xmm0
+       vpxor %xmm3, %xmm0, %xmm3
+       vpshufb %xmm6, %xmm3, %xmm3
+       vpaddd %xmm2, %xmm3, %xmm2
+       vpxor %xmm1, %xmm2, %xmm1
+       vpslld $12, %xmm1, %xmm4
+       vpsrld $20, %xmm1, %xmm1
+       vpxor %xmm1, %xmm4, %xmm1
+       vpaddd %xmm0, %xmm1, %xmm0
+       vpxor %xmm3, %xmm0, %xmm3
+       vpshufb %xmm7, %xmm3, %xmm3
+       vpshufd $0x93, %xmm0, %xmm0
+       vpaddd %xmm2, %xmm3, %xmm2
+       vpshufd $0x4e, %xmm3, %xmm3
+       vpxor %xmm1, %xmm2, %xmm1
+       vpshufd $0x39, %xmm2, %xmm2
+       vpslld $7, %xmm1, %xmm4
+       vpsrld $25, %xmm1, %xmm1
+       vpxor %xmm1, %xmm4, %xmm1
+       vpaddd %xmm0, %xmm1, %xmm0
+       vpxor %xmm3, %xmm0, %xmm3
+       vpshufb %xmm6, %xmm3, %xmm3
+       vpaddd %xmm2, %xmm3, %xmm2
+       vpxor %xmm1, %xmm2, %xmm1
+       vpslld $12, %xmm1, %xmm4
+       vpsrld $20, %xmm1, %xmm1
+       vpxor %xmm1, %xmm4, %xmm1
+       vpaddd %xmm0, %xmm1, %xmm0
+       vpxor %xmm3, %xmm0, %xmm3
+       vpshufb %xmm7, %xmm3, %xmm3
+       vpshufd $0x39, %xmm0, %xmm0
+       vpaddd %xmm2, %xmm3, %xmm2
+       vpshufd $0x4e, %xmm3, %xmm3
+       vpxor %xmm1, %xmm2, %xmm1
+       vpshufd $0x93, %xmm2, %xmm2
+       vpslld $7, %xmm1, %xmm4
+       vpsrld $25, %xmm1, %xmm1
+       vpxor %xmm1, %xmm4, %xmm1
+       subq $2, %rax
+       jnz .Lchacha_blocks_avx2_mainloop3
+       vpaddd %xmm0, %xmm8, %xmm0
+       vpaddd %xmm1, %xmm9, %xmm1
+       vpaddd %xmm2, %xmm10, %xmm2
+       vpaddd %xmm3, %xmm11, %xmm3
+       andq %rsi, %rsi
+       jz .Lchacha_blocks_avx2_noinput4
+       vpxor 0(%rsi), %xmm0, %xmm0
+       vpxor 16(%rsi), %xmm1, %xmm1
+       vpxor 32(%rsi), %xmm2, %xmm2
+       vpxor 48(%rsi), %xmm3, %xmm3
+       addq $64, %rsi
+.Lchacha_blocks_avx2_noinput4:
+       vmovdqu %xmm0, 0(%rdx)
+       vmovdqu %xmm1, 16(%rdx)
+       vmovdqu %xmm2, 32(%rdx)
+       vmovdqu %xmm3, 48(%rdx)
+       vpaddq %xmm11, %xmm5, %xmm11
+       cmpq $64, %rcx
+       jbe .Lchacha_blocks_avx2_mainloop3_finishup
+       addq $64, %rdx
+       subq $64, %rcx
+       jmp .Lchacha_blocks_avx2_below256
+.Lchacha_blocks_avx2_mainloop3_finishup:
+       cmpq $64, %rcx
+       je .Lchacha_blocks_avx2_done
+       addq %rcx, %r9
+       addq %rcx, %rdx
+       negq %rcx
+.Lchacha_blocks_avx2_copyoutput:
+       movb (%rdx, %rcx), %al
+       movb %al, (%r9, %rcx)
+       incq %rcx
+       jnz .Lchacha_blocks_avx2_copyoutput
+.Lchacha_blocks_avx2_done:
+       vmovdqu %xmm11, 48(%rdi)
+       movq %rbp, %rsp
+       popq %r14
+       popq %r13
+       popq %r12
+       popq %rbp
+       popq %rbx
+       vzeroall
+       movl $(63 + 512), %eax
+       ret
+ELF(.size _gcry_chacha20_amd64_avx2_blocks,.-_gcry_chacha20_amd64_avx2_blocks;)
+
+.data
+.align 16
+.LC:
+.byte 2,3,0,1,6,7,4,5,10,11,8,9,14,15,12,13       /* pshufb rotate by 16 */
+.byte 3,0,1,2,7,4,5,6,11,8,9,10,15,12,13,14       /* pshufb rotate by 8 */
+
+#endif /*defined(USE_CHACHA20)*/
+#endif /*__x86_64*/
diff --git a/cipher/chacha20-sse2-amd64.S b/cipher/chacha20-sse2-amd64.S
new file mode 100644 (file)
index 0000000..2b9842c
--- /dev/null
@@ -0,0 +1,659 @@
+/* chacha20-sse2-amd64.S  -  AMD64/SSE2 implementation of ChaCha20
+ *
+ * Copyright (C) 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Based on public domain implementation by Andrew Moon at
+ *  https://github.com/floodyberry/chacha-opt
+ */
+
+#ifdef __x86_64__
+#include <config.h>
+
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && USE_CHACHA20
+
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
+
+.text
+
+.align 8
+.globl _gcry_chacha20_amd64_sse2_blocks
+ELF(.type  _gcry_chacha20_amd64_sse2_blocks,@function;)
+_gcry_chacha20_amd64_sse2_blocks:
+.Lchacha_blocks_sse2_local:
+       pushq %rbx
+       pushq %rbp
+       movq %rsp, %rbp
+       andq $~63, %rsp
+       subq $512, %rsp
+       movdqu (%rdi), %xmm8
+       movdqu 16(%rdi), %xmm9
+       movdqu 32(%rdi), %xmm10
+       movdqu 48(%rdi), %xmm11
+       movq $20, %rax
+       movq $1, %r9
+       movdqa %xmm8, 0(%rsp)
+       movdqa %xmm9, 16(%rsp)
+       movdqa %xmm10, 32(%rsp)
+       movdqa %xmm11, 48(%rsp)
+       movq %rax, 64(%rsp)
+       cmpq $256, %rcx
+       jb .Lchacha_blocks_sse2_below256
+       pshufd $0x00, %xmm8, %xmm0
+       pshufd $0x55, %xmm8, %xmm1
+       pshufd $0xaa, %xmm8, %xmm2
+       pshufd $0xff, %xmm8, %xmm3
+       movdqa %xmm0, 128(%rsp)
+       movdqa %xmm1, 144(%rsp)
+       movdqa %xmm2, 160(%rsp)
+       movdqa %xmm3, 176(%rsp)
+       pshufd $0x00, %xmm9, %xmm0
+       pshufd $0x55, %xmm9, %xmm1
+       pshufd $0xaa, %xmm9, %xmm2
+       pshufd $0xff, %xmm9, %xmm3
+       movdqa %xmm0, 192(%rsp)
+       movdqa %xmm1, 208(%rsp)
+       movdqa %xmm2, 224(%rsp)
+       movdqa %xmm3, 240(%rsp)
+       pshufd $0x00, %xmm10, %xmm0
+       pshufd $0x55, %xmm10, %xmm1
+       pshufd $0xaa, %xmm10, %xmm2
+       pshufd $0xff, %xmm10, %xmm3
+       movdqa %xmm0, 256(%rsp)
+       movdqa %xmm1, 272(%rsp)
+       movdqa %xmm2, 288(%rsp)
+       movdqa %xmm3, 304(%rsp)
+       pshufd $0xaa, %xmm11, %xmm0
+       pshufd $0xff, %xmm11, %xmm1
+       movdqa %xmm0, 352(%rsp)
+       movdqa %xmm1, 368(%rsp)
+       jmp .Lchacha_blocks_sse2_atleast256
+.p2align 6,,63
+.Lchacha_blocks_sse2_atleast256:
+       movq 48(%rsp), %rax
+       leaq 1(%rax), %r8
+       leaq 2(%rax), %r9
+       leaq 3(%rax), %r10
+       leaq 4(%rax), %rbx
+       movl %eax, 320(%rsp)
+       movl %r8d, 4+320(%rsp)
+       movl %r9d, 8+320(%rsp)
+       movl %r10d, 12+320(%rsp)
+       shrq $32, %rax
+       shrq $32, %r8
+       shrq $32, %r9
+       shrq $32, %r10
+       movl %eax, 336(%rsp)
+       movl %r8d, 4+336(%rsp)
+       movl %r9d, 8+336(%rsp)
+       movl %r10d, 12+336(%rsp)
+       movq %rbx, 48(%rsp)
+       movq 64(%rsp), %rax
+       movdqa 128(%rsp), %xmm0
+       movdqa 144(%rsp), %xmm1
+       movdqa 160(%rsp), %xmm2
+       movdqa 176(%rsp), %xmm3
+       movdqa 192(%rsp), %xmm4
+       movdqa 208(%rsp), %xmm5
+       movdqa 224(%rsp), %xmm6
+       movdqa 240(%rsp), %xmm7
+       movdqa 256(%rsp), %xmm8
+       movdqa 272(%rsp), %xmm9
+       movdqa 288(%rsp), %xmm10
+       movdqa 304(%rsp), %xmm11
+       movdqa 320(%rsp), %xmm12
+       movdqa 336(%rsp), %xmm13
+       movdqa 352(%rsp), %xmm14
+       movdqa 368(%rsp), %xmm15
+.Lchacha_blocks_sse2_mainloop1:
+       paddd %xmm4, %xmm0
+       paddd %xmm5, %xmm1
+       pxor %xmm0, %xmm12
+       pxor %xmm1, %xmm13
+       paddd %xmm6, %xmm2
+       paddd %xmm7, %xmm3
+       movdqa %xmm6, 96(%rsp)
+       pxor %xmm2, %xmm14
+       pxor %xmm3, %xmm15
+       pshuflw $0xb1,%xmm12,%xmm12
+       pshufhw $0xb1,%xmm12,%xmm12
+       pshuflw $0xb1,%xmm13,%xmm13
+       pshufhw $0xb1,%xmm13,%xmm13
+       pshuflw $0xb1,%xmm14,%xmm14
+       pshufhw $0xb1,%xmm14,%xmm14
+       pshuflw $0xb1,%xmm15,%xmm15
+       pshufhw $0xb1,%xmm15,%xmm15
+       paddd %xmm12, %xmm8
+       paddd %xmm13, %xmm9
+       paddd %xmm14, %xmm10
+       paddd %xmm15, %xmm11
+       movdqa %xmm12, 112(%rsp)
+       pxor %xmm8, %xmm4
+       pxor %xmm9, %xmm5
+       movdqa 96(%rsp), %xmm6
+       movdqa %xmm4, %xmm12
+       pslld $ 12, %xmm4
+       psrld $20, %xmm12
+       pxor %xmm12, %xmm4
+       movdqa %xmm5, %xmm12
+       pslld $ 12, %xmm5
+       psrld $20, %xmm12
+       pxor %xmm12, %xmm5
+       pxor %xmm10, %xmm6
+       pxor %xmm11, %xmm7
+       movdqa %xmm6, %xmm12
+       pslld $ 12, %xmm6
+       psrld $20, %xmm12
+       pxor %xmm12, %xmm6
+       movdqa %xmm7, %xmm12
+       pslld $ 12, %xmm7
+       psrld $20, %xmm12
+       pxor %xmm12, %xmm7
+       movdqa 112(%rsp), %xmm12
+       paddd %xmm4, %xmm0
+       paddd %xmm5, %xmm1
+       pxor %xmm0, %xmm12
+       pxor %xmm1, %xmm13
+       paddd %xmm6, %xmm2
+       paddd %xmm7, %xmm3
+       movdqa %xmm6, 96(%rsp)
+       pxor %xmm2, %xmm14
+       pxor %xmm3, %xmm15
+       movdqa %xmm12, %xmm6
+       pslld $ 8, %xmm12
+       psrld $24, %xmm6
+       pxor %xmm6, %xmm12
+       movdqa %xmm13, %xmm6
+       pslld $ 8, %xmm13
+       psrld $24, %xmm6
+       pxor %xmm6, %xmm13
+       paddd %xmm12, %xmm8
+       paddd %xmm13, %xmm9
+       movdqa %xmm14, %xmm6
+       pslld $ 8, %xmm14
+       psrld $24, %xmm6
+       pxor %xmm6, %xmm14
+       movdqa %xmm15, %xmm6
+       pslld $ 8, %xmm15
+       psrld $24, %xmm6
+       pxor %xmm6, %xmm15
+       paddd %xmm14, %xmm10
+       paddd %xmm15, %xmm11
+       movdqa %xmm12, 112(%rsp)
+       pxor %xmm8, %xmm4
+       pxor %xmm9, %xmm5
+       movdqa 96(%rsp), %xmm6
+       movdqa %xmm4, %xmm12
+       pslld $ 7, %xmm4
+       psrld $25, %xmm12
+       pxor %xmm12, %xmm4
+       movdqa %xmm5, %xmm12
+       pslld $ 7, %xmm5
+       psrld $25, %xmm12
+       pxor %xmm12, %xmm5
+       pxor %xmm10, %xmm6
+       pxor %xmm11, %xmm7
+       movdqa %xmm6, %xmm12
+       pslld $ 7, %xmm6
+       psrld $25, %xmm12
+       pxor %xmm12, %xmm6
+       movdqa %xmm7, %xmm12
+       pslld $ 7, %xmm7
+       psrld $25, %xmm12
+       pxor %xmm12, %xmm7
+       movdqa 112(%rsp), %xmm12
+       paddd %xmm5, %xmm0
+       paddd %xmm6, %xmm1
+       pxor %xmm0, %xmm15
+       pxor %xmm1, %xmm12
+       paddd %xmm7, %xmm2
+       paddd %xmm4, %xmm3
+       movdqa %xmm7, 96(%rsp)
+       pxor %xmm2, %xmm13
+       pxor %xmm3, %xmm14
+       pshuflw $0xb1,%xmm15,%xmm15
+       pshufhw $0xb1,%xmm15,%xmm15
+       pshuflw $0xb1,%xmm12,%xmm12
+       pshufhw $0xb1,%xmm12,%xmm12
+       pshuflw $0xb1,%xmm13,%xmm13
+       pshufhw $0xb1,%xmm13,%xmm13
+       pshuflw $0xb1,%xmm14,%xmm14
+       pshufhw $0xb1,%xmm14,%xmm14
+       paddd %xmm15, %xmm10
+       paddd %xmm12, %xmm11
+       paddd %xmm13, %xmm8
+       paddd %xmm14, %xmm9
+       movdqa %xmm15, 112(%rsp)
+       pxor %xmm10, %xmm5
+       pxor %xmm11, %xmm6
+       movdqa 96(%rsp), %xmm7
+       movdqa %xmm5, %xmm15
+       pslld $ 12, %xmm5
+       psrld $20, %xmm15
+       pxor %xmm15, %xmm5
+       movdqa %xmm6, %xmm15
+       pslld $ 12, %xmm6
+       psrld $20, %xmm15
+       pxor %xmm15, %xmm6
+       pxor %xmm8, %xmm7
+       pxor %xmm9, %xmm4
+       movdqa %xmm7, %xmm15
+       pslld $ 12, %xmm7
+       psrld $20, %xmm15
+       pxor %xmm15, %xmm7
+       movdqa %xmm4, %xmm15
+       pslld $ 12, %xmm4
+       psrld $20, %xmm15
+       pxor %xmm15, %xmm4
+       movdqa 112(%rsp), %xmm15
+       paddd %xmm5, %xmm0
+       paddd %xmm6, %xmm1
+       pxor %xmm0, %xmm15
+       pxor %xmm1, %xmm12
+       paddd %xmm7, %xmm2
+       paddd %xmm4, %xmm3
+       movdqa %xmm7, 96(%rsp)
+       pxor %xmm2, %xmm13
+       pxor %xmm3, %xmm14
+       movdqa %xmm15, %xmm7
+       pslld $ 8, %xmm15
+       psrld $24, %xmm7
+       pxor %xmm7, %xmm15
+       movdqa %xmm12, %xmm7
+       pslld $ 8, %xmm12
+       psrld $24, %xmm7
+       pxor %xmm7, %xmm12
+       paddd %xmm15, %xmm10
+       paddd %xmm12, %xmm11
+       movdqa %xmm13, %xmm7
+       pslld $ 8, %xmm13
+       psrld $24, %xmm7
+       pxor %xmm7, %xmm13
+       movdqa %xmm14, %xmm7
+       pslld $ 8, %xmm14
+       psrld $24, %xmm7
+       pxor %xmm7, %xmm14
+       paddd %xmm13, %xmm8
+       paddd %xmm14, %xmm9
+       movdqa %xmm15, 112(%rsp)
+       pxor %xmm10, %xmm5
+       pxor %xmm11, %xmm6
+       movdqa 96(%rsp), %xmm7
+       movdqa %xmm5, %xmm15
+       pslld $ 7, %xmm5
+       psrld $25, %xmm15
+       pxor %xmm15, %xmm5
+       movdqa %xmm6, %xmm15
+       pslld $ 7, %xmm6
+       psrld $25, %xmm15
+       pxor %xmm15, %xmm6
+       pxor %xmm8, %xmm7
+       pxor %xmm9, %xmm4
+       movdqa %xmm7, %xmm15
+       pslld $ 7, %xmm7
+       psrld $25, %xmm15
+       pxor %xmm15, %xmm7
+       movdqa %xmm4, %xmm15
+       pslld $ 7, %xmm4
+       psrld $25, %xmm15
+       pxor %xmm15, %xmm4
+       movdqa 112(%rsp), %xmm15
+       subq $2, %rax
+       jnz .Lchacha_blocks_sse2_mainloop1
+       paddd 128(%rsp), %xmm0
+       paddd 144(%rsp), %xmm1
+       paddd 160(%rsp), %xmm2
+       paddd 176(%rsp), %xmm3
+       paddd 192(%rsp), %xmm4
+       paddd 208(%rsp), %xmm5
+       paddd 224(%rsp), %xmm6
+       paddd 240(%rsp), %xmm7
+       paddd 256(%rsp), %xmm8
+       paddd 272(%rsp), %xmm9
+       paddd 288(%rsp), %xmm10
+       paddd 304(%rsp), %xmm11
+       paddd 320(%rsp), %xmm12
+       paddd 336(%rsp), %xmm13
+       paddd 352(%rsp), %xmm14
+       paddd 368(%rsp), %xmm15
+       movdqa %xmm8, 384(%rsp)
+       movdqa %xmm9, 400(%rsp)
+       movdqa %xmm10, 416(%rsp)
+       movdqa %xmm11, 432(%rsp)
+       movdqa %xmm12, 448(%rsp)
+       movdqa %xmm13, 464(%rsp)
+       movdqa %xmm14, 480(%rsp)
+       movdqa %xmm15, 496(%rsp)
+       movdqa %xmm0, %xmm8
+       movdqa %xmm2, %xmm9
+       movdqa %xmm4, %xmm10
+       movdqa %xmm6, %xmm11
+       punpckhdq %xmm1, %xmm0
+       punpckhdq %xmm3, %xmm2
+       punpckhdq %xmm5, %xmm4
+       punpckhdq %xmm7, %xmm6
+       punpckldq %xmm1, %xmm8
+       punpckldq %xmm3, %xmm9
+       punpckldq %xmm5, %xmm10
+       punpckldq %xmm7, %xmm11
+       movdqa %xmm0, %xmm1
+       movdqa %xmm4, %xmm3
+       movdqa %xmm8, %xmm5
+       movdqa %xmm10, %xmm7
+       punpckhqdq %xmm2, %xmm0
+       punpckhqdq %xmm6, %xmm4
+       punpckhqdq %xmm9, %xmm8
+       punpckhqdq %xmm11, %xmm10
+       punpcklqdq %xmm2, %xmm1
+       punpcklqdq %xmm6, %xmm3
+       punpcklqdq %xmm9, %xmm5
+       punpcklqdq %xmm11, %xmm7
+       andq %rsi, %rsi
+       jz .Lchacha_blocks_sse2_noinput1
+       movdqu 0(%rsi), %xmm2
+       movdqu 16(%rsi), %xmm6
+       movdqu 64(%rsi), %xmm9
+       movdqu 80(%rsi), %xmm11
+       movdqu 128(%rsi), %xmm12
+       movdqu 144(%rsi), %xmm13
+       movdqu 192(%rsi), %xmm14
+       movdqu 208(%rsi), %xmm15
+       pxor %xmm2, %xmm5
+       pxor %xmm6, %xmm7
+       pxor %xmm9, %xmm8
+       pxor %xmm11, %xmm10
+       pxor %xmm12, %xmm1
+       pxor %xmm13, %xmm3
+       pxor %xmm14, %xmm0
+       pxor %xmm15, %xmm4
+       movdqu %xmm5, 0(%rdx)
+       movdqu %xmm7, 16(%rdx)
+       movdqu %xmm8, 64(%rdx)
+       movdqu %xmm10, 80(%rdx)
+       movdqu %xmm1, 128(%rdx)
+       movdqu %xmm3, 144(%rdx)
+       movdqu %xmm0, 192(%rdx)
+       movdqu %xmm4, 208(%rdx)
+       movdqa 384(%rsp), %xmm0
+       movdqa 400(%rsp), %xmm1
+       movdqa 416(%rsp), %xmm2
+       movdqa 432(%rsp), %xmm3
+       movdqa 448(%rsp), %xmm4
+       movdqa 464(%rsp), %xmm5
+       movdqa 480(%rsp), %xmm6
+       movdqa 496(%rsp), %xmm7
+       movdqa %xmm0, %xmm8
+       movdqa %xmm2, %xmm9
+       movdqa %xmm4, %xmm10
+       movdqa %xmm6, %xmm11
+       punpckldq %xmm1, %xmm8
+       punpckldq %xmm3, %xmm9
+       punpckhdq %xmm1, %xmm0
+       punpckhdq %xmm3, %xmm2
+       punpckldq %xmm5, %xmm10
+       punpckldq %xmm7, %xmm11
+       punpckhdq %xmm5, %xmm4
+       punpckhdq %xmm7, %xmm6
+       movdqa %xmm8, %xmm1
+       movdqa %xmm0, %xmm3
+       movdqa %xmm10, %xmm5
+       movdqa %xmm4, %xmm7
+       punpcklqdq %xmm9, %xmm1
+       punpcklqdq %xmm11, %xmm5
+       punpckhqdq %xmm9, %xmm8
+       punpckhqdq %xmm11, %xmm10
+       punpcklqdq %xmm2, %xmm3
+       punpcklqdq %xmm6, %xmm7
+       punpckhqdq %xmm2, %xmm0
+       punpckhqdq %xmm6, %xmm4
+       movdqu 32(%rsi), %xmm2
+       movdqu 48(%rsi), %xmm6
+       movdqu 96(%rsi), %xmm9
+       movdqu 112(%rsi), %xmm11
+       movdqu 160(%rsi), %xmm12
+       movdqu 176(%rsi), %xmm13
+       movdqu 224(%rsi), %xmm14
+       movdqu 240(%rsi), %xmm15
+       pxor %xmm2, %xmm1
+       pxor %xmm6, %xmm5
+       pxor %xmm9, %xmm8
+       pxor %xmm11, %xmm10
+       pxor %xmm12, %xmm3
+       pxor %xmm13, %xmm7
+       pxor %xmm14, %xmm0
+       pxor %xmm15, %xmm4
+       movdqu %xmm1, 32(%rdx)
+       movdqu %xmm5, 48(%rdx)
+       movdqu %xmm8, 96(%rdx)
+       movdqu %xmm10, 112(%rdx)
+       movdqu %xmm3, 160(%rdx)
+       movdqu %xmm7, 176(%rdx)
+       movdqu %xmm0, 224(%rdx)
+       movdqu %xmm4, 240(%rdx)
+       addq $256, %rsi
+       jmp .Lchacha_blocks_sse2_mainloop_cont
+.Lchacha_blocks_sse2_noinput1:
+       movdqu %xmm5, 0(%rdx)
+       movdqu %xmm7, 16(%rdx)
+       movdqu %xmm8, 64(%rdx)
+       movdqu %xmm10, 80(%rdx)
+       movdqu %xmm1, 128(%rdx)
+       movdqu %xmm3, 144(%rdx)
+       movdqu %xmm0, 192(%rdx)
+       movdqu %xmm4, 208(%rdx)
+       movdqa 384(%rsp), %xmm0
+       movdqa 400(%rsp), %xmm1
+       movdqa 416(%rsp), %xmm2
+       movdqa 432(%rsp), %xmm3
+       movdqa 448(%rsp), %xmm4
+       movdqa 464(%rsp), %xmm5
+       movdqa 480(%rsp), %xmm6
+       movdqa 496(%rsp), %xmm7
+       movdqa %xmm0, %xmm8
+       movdqa %xmm2, %xmm9
+       movdqa %xmm4, %xmm10
+       movdqa %xmm6, %xmm11
+       punpckldq %xmm1, %xmm8
+       punpckldq %xmm3, %xmm9
+       punpckhdq %xmm1, %xmm0
+       punpckhdq %xmm3, %xmm2
+       punpckldq %xmm5, %xmm10
+       punpckldq %xmm7, %xmm11
+       punpckhdq %xmm5, %xmm4
+       punpckhdq %xmm7, %xmm6
+       movdqa %xmm8, %xmm1
+       movdqa %xmm0, %xmm3
+       movdqa %xmm10, %xmm5
+       movdqa %xmm4, %xmm7
+       punpcklqdq %xmm9, %xmm1
+       punpcklqdq %xmm11, %xmm5
+       punpckhqdq %xmm9, %xmm8
+       punpckhqdq %xmm11, %xmm10
+       punpcklqdq %xmm2, %xmm3
+       punpcklqdq %xmm6, %xmm7
+       punpckhqdq %xmm2, %xmm0
+       punpckhqdq %xmm6, %xmm4
+       movdqu %xmm1, 32(%rdx)
+       movdqu %xmm5, 48(%rdx)
+       movdqu %xmm8, 96(%rdx)
+       movdqu %xmm10, 112(%rdx)
+       movdqu %xmm3, 160(%rdx)
+       movdqu %xmm7, 176(%rdx)
+       movdqu %xmm0, 224(%rdx)
+       movdqu %xmm4, 240(%rdx)
+.Lchacha_blocks_sse2_mainloop_cont:
+       addq $256, %rdx
+       subq $256, %rcx
+       cmp $256, %rcx
+       jae .Lchacha_blocks_sse2_atleast256
+       movdqa 0(%rsp), %xmm8
+       movdqa 16(%rsp), %xmm9
+       movdqa 32(%rsp), %xmm10
+       movdqa 48(%rsp), %xmm11
+       movq $1, %r9
+.Lchacha_blocks_sse2_below256:
+       movq %r9, %xmm5
+       andq %rcx, %rcx
+       jz .Lchacha_blocks_sse2_done
+       cmpq $64, %rcx
+       jae .Lchacha_blocks_sse2_above63
+       movq %rdx, %r9
+       andq %rsi, %rsi
+       jz .Lchacha_blocks_sse2_noinput2
+       movq %rcx, %r10
+       movq %rsp, %rdx
+       addq %r10, %rsi
+       addq %r10, %rdx
+       negq %r10
+.Lchacha_blocks_sse2_copyinput:
+       movb (%rsi, %r10), %al
+       movb %al, (%rdx, %r10)
+       incq %r10
+       jnz .Lchacha_blocks_sse2_copyinput
+       movq %rsp, %rsi
+.Lchacha_blocks_sse2_noinput2:
+       movq %rsp, %rdx
+.Lchacha_blocks_sse2_above63:
+       movdqa %xmm8, %xmm0
+       movdqa %xmm9, %xmm1
+       movdqa %xmm10, %xmm2
+       movdqa %xmm11, %xmm3
+       movq 64(%rsp), %rax
+.Lchacha_blocks_sse2_mainloop2:
+       paddd %xmm1, %xmm0
+       pxor %xmm0, %xmm3
+       pshuflw $0xb1,%xmm3,%xmm3
+       pshufhw $0xb1,%xmm3,%xmm3
+       paddd %xmm3, %xmm2
+       pxor %xmm2, %xmm1
+       movdqa %xmm1,%xmm4
+       pslld $12, %xmm1
+       psrld $20, %xmm4
+       pxor %xmm4, %xmm1
+       paddd %xmm1, %xmm0
+       pxor %xmm0, %xmm3
+       movdqa %xmm3,%xmm4
+       pslld $8, %xmm3
+       psrld $24, %xmm4
+       pshufd $0x93,%xmm0,%xmm0
+       pxor %xmm4, %xmm3
+       paddd %xmm3, %xmm2
+       pshufd $0x4e,%xmm3,%xmm3
+       pxor %xmm2, %xmm1
+       pshufd $0x39,%xmm2,%xmm2
+       movdqa %xmm1,%xmm4
+       pslld $7, %xmm1
+       psrld $25, %xmm4
+       pxor %xmm4, %xmm1
+       subq $2, %rax
+       paddd %xmm1, %xmm0
+       pxor %xmm0, %xmm3
+       pshuflw $0xb1,%xmm3,%xmm3
+       pshufhw $0xb1,%xmm3,%xmm3
+       paddd %xmm3, %xmm2
+       pxor %xmm2, %xmm1
+       movdqa %xmm1,%xmm4
+       pslld $12, %xmm1
+       psrld $20, %xmm4
+       pxor %xmm4, %xmm1
+       paddd %xmm1, %xmm0
+       pxor %xmm0, %xmm3
+       movdqa %xmm3,%xmm4
+       pslld $8, %xmm3
+       psrld $24, %xmm4
+       pshufd $0x39,%xmm0,%xmm0
+       pxor %xmm4, %xmm3
+       paddd %xmm3, %xmm2
+       pshufd $0x4e,%xmm3,%xmm3
+       pxor %xmm2, %xmm1
+       pshufd $0x93,%xmm2,%xmm2
+       movdqa %xmm1,%xmm4
+       pslld $7, %xmm1
+       psrld $25, %xmm4
+       pxor %xmm4, %xmm1
+       jnz .Lchacha_blocks_sse2_mainloop2
+       paddd %xmm8, %xmm0
+       paddd %xmm9, %xmm1
+       paddd %xmm10, %xmm2
+       paddd %xmm11, %xmm3
+       andq %rsi, %rsi
+       jz .Lchacha_blocks_sse2_noinput3
+       movdqu 0(%rsi), %xmm12
+       movdqu 16(%rsi), %xmm13
+       movdqu 32(%rsi), %xmm14
+       movdqu 48(%rsi), %xmm15
+       pxor %xmm12, %xmm0
+       pxor %xmm13, %xmm1
+       pxor %xmm14, %xmm2
+       pxor %xmm15, %xmm3
+       addq $64, %rsi
+.Lchacha_blocks_sse2_noinput3:
+       movdqu %xmm0, 0(%rdx)
+       movdqu %xmm1, 16(%rdx)
+       movdqu %xmm2, 32(%rdx)
+       movdqu %xmm3, 48(%rdx)
+       paddq %xmm5, %xmm11
+       cmpq $64, %rcx
+       jbe .Lchacha_blocks_sse2_mainloop2_finishup
+       addq $64, %rdx
+       subq $64, %rcx
+       jmp .Lchacha_blocks_sse2_below256
+.Lchacha_blocks_sse2_mainloop2_finishup:
+       cmpq $64, %rcx
+       je .Lchacha_blocks_sse2_done
+       addq %rcx, %r9
+       addq %rcx, %rdx
+       negq %rcx
+.Lchacha_blocks_sse2_copyoutput:
+       movb (%rdx, %rcx), %al
+       movb %al, (%r9, %rcx)
+       incq %rcx
+       jnz .Lchacha_blocks_sse2_copyoutput
+.Lchacha_blocks_sse2_done:
+       movdqu %xmm11, 48(%rdi)
+       movq %rbp, %rsp
+       pxor %xmm15, %xmm15
+       pxor %xmm7, %xmm7
+       pxor %xmm14, %xmm14
+       pxor %xmm6, %xmm6
+       pxor %xmm13, %xmm13
+       pxor %xmm5, %xmm5
+       pxor %xmm12, %xmm12
+       pxor %xmm4, %xmm4
+       popq %rbp
+       popq %rbx
+       movl $(63 + 512 + 16), %eax
+       pxor %xmm11, %xmm11
+       pxor %xmm3, %xmm3
+       pxor %xmm10, %xmm10
+       pxor %xmm2, %xmm2
+       pxor %xmm9, %xmm9
+       pxor %xmm1, %xmm1
+       pxor %xmm8, %xmm8
+       pxor %xmm0, %xmm0
+       ret
+ELF(.size _gcry_chacha20_amd64_sse2_blocks,.-_gcry_chacha20_amd64_sse2_blocks;)
+
+#endif /*defined(USE_CHACHA20)*/
+#endif /*__x86_64*/
diff --git a/cipher/chacha20-ssse3-amd64.S b/cipher/chacha20-ssse3-amd64.S
new file mode 100644 (file)
index 0000000..a1a843f
--- /dev/null
@@ -0,0 +1,633 @@
+/* chacha20-ssse3-amd64.S  -  AMD64/SSSE3 implementation of ChaCha20
+ *
+ * Copyright (C) 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Based on public domain implementation by Andrew Moon at
+ *  https://github.com/floodyberry/chacha-opt
+ */
+
+#ifdef __x86_64__
+#include <config.h>
+
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
+    defined(HAVE_GCC_INLINE_ASM_SSSE3) && USE_CHACHA20
+
+#ifdef __PIC__
+#  define RIP (%rip)
+#else
+#  define RIP
+#endif
+
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
+
+.text
+
+.align 8
+.globl _gcry_chacha20_amd64_ssse3_blocks
+ELF(.type  _gcry_chacha20_amd64_ssse3_blocks,@function;)
+_gcry_chacha20_amd64_ssse3_blocks:
+.Lchacha_blocks_ssse3_local:
+       pushq %rbx
+       pushq %rbp
+       movq %rsp, %rbp
+       andq $~63, %rsp
+       subq $512, %rsp
+       leaq .LC RIP, %rax
+       movdqa 0(%rax), %xmm6
+       movdqa 16(%rax), %xmm7
+       movdqu 0(%rdi), %xmm8
+       movdqu 16(%rdi), %xmm9
+       movdqu 32(%rdi), %xmm10
+       movdqu 48(%rdi), %xmm11
+       movl $20, %eax
+       movq $1, %r9
+       movdqa %xmm8, 0(%rsp)
+       movdqa %xmm9, 16(%rsp)
+       movdqa %xmm10, 32(%rsp)
+       movdqa %xmm11, 48(%rsp)
+       movdqa %xmm6, 80(%rsp)
+       movdqa %xmm7, 96(%rsp)
+       movq %rax, 64(%rsp)
+       cmpq $256, %rcx
+       jb .Lchacha_blocks_ssse3_below256
+       pshufd $0x00, %xmm8, %xmm0
+       pshufd $0x55, %xmm8, %xmm1
+       pshufd $0xaa, %xmm8, %xmm2
+       pshufd $0xff, %xmm8, %xmm3
+       movdqa %xmm0, 128(%rsp)
+       movdqa %xmm1, 144(%rsp)
+       movdqa %xmm2, 160(%rsp)
+       movdqa %xmm3, 176(%rsp)
+       pshufd $0x00, %xmm9, %xmm0
+       pshufd $0x55, %xmm9, %xmm1
+       pshufd $0xaa, %xmm9, %xmm2
+       pshufd $0xff, %xmm9, %xmm3
+       movdqa %xmm0, 192(%rsp)
+       movdqa %xmm1, 208(%rsp)
+       movdqa %xmm2, 224(%rsp)
+       movdqa %xmm3, 240(%rsp)
+       pshufd $0x00, %xmm10, %xmm0
+       pshufd $0x55, %xmm10, %xmm1
+       pshufd $0xaa, %xmm10, %xmm2
+       pshufd $0xff, %xmm10, %xmm3
+       movdqa %xmm0, 256(%rsp)
+       movdqa %xmm1, 272(%rsp)
+       movdqa %xmm2, 288(%rsp)
+       movdqa %xmm3, 304(%rsp)
+       pshufd $0xaa, %xmm11, %xmm0
+       pshufd $0xff, %xmm11, %xmm1
+       movdqa %xmm0, 352(%rsp)
+       movdqa %xmm1, 368(%rsp)
+       jmp .Lchacha_blocks_ssse3_atleast256
+.p2align 6,,63
+       # align to 4 mod 64
+       nop;nop;nop;nop;
+.Lchacha_blocks_ssse3_atleast256:
+       movq 48(%rsp), %rax
+       leaq 1(%rax), %r8
+       leaq 2(%rax), %r9
+       leaq 3(%rax), %r10
+       leaq 4(%rax), %rbx
+       movl %eax, 320(%rsp)
+       movl %r8d, 4+320(%rsp)
+       movl %r9d, 8+320(%rsp)
+       movl %r10d, 12+320(%rsp)
+       shrq $32, %rax
+       shrq $32, %r8
+       shrq $32, %r9
+       shrq $32, %r10
+       movl %eax, 336(%rsp)
+       movl %r8d, 4+336(%rsp)
+       movl %r9d, 8+336(%rsp)
+       movl %r10d, 12+336(%rsp)
+       movq %rbx, 48(%rsp)
+       movq 64(%rsp), %rax
+       movdqa 128(%rsp), %xmm0
+       movdqa 144(%rsp), %xmm1
+       movdqa 160(%rsp), %xmm2
+       movdqa 176(%rsp), %xmm3
+       movdqa 192(%rsp), %xmm4
+       movdqa 208(%rsp), %xmm5
+       movdqa 224(%rsp), %xmm6
+       movdqa 240(%rsp), %xmm7
+       movdqa 256(%rsp), %xmm8
+       movdqa 272(%rsp), %xmm9
+       movdqa 288(%rsp), %xmm10
+       movdqa 304(%rsp), %xmm11
+       movdqa 320(%rsp), %xmm12
+       movdqa 336(%rsp), %xmm13
+       movdqa 352(%rsp), %xmm14
+       movdqa 368(%rsp), %xmm15
+.Lchacha_blocks_ssse3_mainloop1:
+       paddd %xmm4, %xmm0
+       paddd %xmm5, %xmm1
+       pxor %xmm0, %xmm12
+       pxor %xmm1, %xmm13
+       paddd %xmm6, %xmm2
+       paddd %xmm7, %xmm3
+       pxor %xmm2, %xmm14
+       pxor %xmm3, %xmm15
+       pshufb 80(%rsp), %xmm12
+       pshufb 80(%rsp), %xmm13
+       paddd %xmm12, %xmm8
+       paddd %xmm13, %xmm9
+       pshufb 80(%rsp), %xmm14
+       pshufb 80(%rsp), %xmm15
+       paddd %xmm14, %xmm10
+       paddd %xmm15, %xmm11
+       movdqa %xmm12, 112(%rsp)
+       pxor %xmm8, %xmm4
+       pxor %xmm9, %xmm5
+       movdqa %xmm4, %xmm12
+       pslld $ 12, %xmm4
+       psrld $20, %xmm12
+       pxor %xmm12, %xmm4
+       movdqa %xmm5, %xmm12
+       pslld $ 12, %xmm5
+       psrld $20, %xmm12
+       pxor %xmm12, %xmm5
+       pxor %xmm10, %xmm6
+       pxor %xmm11, %xmm7
+       movdqa %xmm6, %xmm12
+       pslld $ 12, %xmm6
+       psrld $20, %xmm12
+       pxor %xmm12, %xmm6
+       movdqa %xmm7, %xmm12
+       pslld $ 12, %xmm7
+       psrld $20, %xmm12
+       pxor %xmm12, %xmm7
+       movdqa 112(%rsp), %xmm12
+       paddd %xmm4, %xmm0
+       paddd %xmm5, %xmm1
+       pxor %xmm0, %xmm12
+       pxor %xmm1, %xmm13
+       paddd %xmm6, %xmm2
+       paddd %xmm7, %xmm3
+       pxor %xmm2, %xmm14
+       pxor %xmm3, %xmm15
+       pshufb 96(%rsp), %xmm12
+       pshufb 96(%rsp), %xmm13
+       paddd %xmm12, %xmm8
+       paddd %xmm13, %xmm9
+       pshufb 96(%rsp), %xmm14
+       pshufb 96(%rsp), %xmm15
+       paddd %xmm14, %xmm10
+       paddd %xmm15, %xmm11
+       movdqa %xmm12, 112(%rsp)
+       pxor %xmm8, %xmm4
+       pxor %xmm9, %xmm5
+       movdqa %xmm4, %xmm12
+       pslld $ 7, %xmm4
+       psrld $25, %xmm12
+       pxor %xmm12, %xmm4
+       movdqa %xmm5, %xmm12
+       pslld $ 7, %xmm5
+       psrld $25, %xmm12
+       pxor %xmm12, %xmm5
+       pxor %xmm10, %xmm6
+       pxor %xmm11, %xmm7
+       movdqa %xmm6, %xmm12
+       pslld $ 7, %xmm6
+       psrld $25, %xmm12
+       pxor %xmm12, %xmm6
+       movdqa %xmm7, %xmm12
+       pslld $ 7, %xmm7
+       psrld $25, %xmm12
+       pxor %xmm12, %xmm7
+       movdqa 112(%rsp), %xmm12
+       paddd %xmm5, %xmm0
+       paddd %xmm6, %xmm1
+       pxor %xmm0, %xmm15
+       pxor %xmm1, %xmm12
+       paddd %xmm7, %xmm2
+       paddd %xmm4, %xmm3
+       pxor %xmm2, %xmm13
+       pxor %xmm3, %xmm14
+       pshufb 80(%rsp), %xmm15
+       pshufb 80(%rsp), %xmm12
+       paddd %xmm15, %xmm10
+       paddd %xmm12, %xmm11
+       pshufb 80(%rsp), %xmm13
+       pshufb 80(%rsp), %xmm14
+       paddd %xmm13, %xmm8
+       paddd %xmm14, %xmm9
+       movdqa %xmm15, 112(%rsp)
+       pxor %xmm10, %xmm5
+       pxor %xmm11, %xmm6
+       movdqa %xmm5, %xmm15
+       pslld $ 12, %xmm5
+       psrld $20, %xmm15
+       pxor %xmm15, %xmm5
+       movdqa %xmm6, %xmm15
+       pslld $ 12, %xmm6
+       psrld $20, %xmm15
+       pxor %xmm15, %xmm6
+       pxor %xmm8, %xmm7
+       pxor %xmm9, %xmm4
+       movdqa %xmm7, %xmm15
+       pslld $ 12, %xmm7
+       psrld $20, %xmm15
+       pxor %xmm15, %xmm7
+       movdqa %xmm4, %xmm15
+       pslld $ 12, %xmm4
+       psrld $20, %xmm15
+       pxor %xmm15, %xmm4
+       movdqa 112(%rsp), %xmm15
+       paddd %xmm5, %xmm0
+       paddd %xmm6, %xmm1
+       pxor %xmm0, %xmm15
+       pxor %xmm1, %xmm12
+       paddd %xmm7, %xmm2
+       paddd %xmm4, %xmm3
+       pxor %xmm2, %xmm13
+       pxor %xmm3, %xmm14
+       pshufb 96(%rsp), %xmm15
+       pshufb 96(%rsp), %xmm12
+       paddd %xmm15, %xmm10
+       paddd %xmm12, %xmm11
+       pshufb 96(%rsp), %xmm13
+       pshufb 96(%rsp), %xmm14
+       paddd %xmm13, %xmm8
+       paddd %xmm14, %xmm9
+       movdqa %xmm15, 112(%rsp)
+       pxor %xmm10, %xmm5
+       pxor %xmm11, %xmm6
+       movdqa %xmm5, %xmm15
+       pslld $ 7, %xmm5
+       psrld $25, %xmm15
+       pxor %xmm15, %xmm5
+       movdqa %xmm6, %xmm15
+       pslld $ 7, %xmm6
+       psrld $25, %xmm15
+       pxor %xmm15, %xmm6
+       pxor %xmm8, %xmm7
+       pxor %xmm9, %xmm4
+       movdqa %xmm7, %xmm15
+       pslld $ 7, %xmm7
+       psrld $25, %xmm15
+       pxor %xmm15, %xmm7
+       movdqa %xmm4, %xmm15
+       pslld $ 7, %xmm4
+       psrld $25, %xmm15
+       pxor %xmm15, %xmm4
+       subq $2, %rax
+       movdqa 112(%rsp), %xmm15
+       jnz .Lchacha_blocks_ssse3_mainloop1
+       paddd 128(%rsp), %xmm0
+       paddd 144(%rsp), %xmm1
+       paddd 160(%rsp), %xmm2
+       paddd 176(%rsp), %xmm3
+       paddd 192(%rsp), %xmm4
+       paddd 208(%rsp), %xmm5
+       paddd 224(%rsp), %xmm6
+       paddd 240(%rsp), %xmm7
+       paddd 256(%rsp), %xmm8
+       paddd 272(%rsp), %xmm9
+       paddd 288(%rsp), %xmm10
+       paddd 304(%rsp), %xmm11
+       paddd 320(%rsp), %xmm12
+       paddd 336(%rsp), %xmm13
+       paddd 352(%rsp), %xmm14
+       paddd 368(%rsp), %xmm15
+       movdqa %xmm8, 384(%rsp)
+       movdqa %xmm9, 400(%rsp)
+       movdqa %xmm10, 416(%rsp)
+       movdqa %xmm11, 432(%rsp)
+       movdqa %xmm12, 448(%rsp)
+       movdqa %xmm13, 464(%rsp)
+       movdqa %xmm14, 480(%rsp)
+       movdqa %xmm15, 496(%rsp)
+       movdqa %xmm0, %xmm8
+       movdqa %xmm2, %xmm9
+       movdqa %xmm4, %xmm10
+       movdqa %xmm6, %xmm11
+       punpckhdq %xmm1, %xmm0
+       punpckhdq %xmm3, %xmm2
+       punpckhdq %xmm5, %xmm4
+       punpckhdq %xmm7, %xmm6
+       punpckldq %xmm1, %xmm8
+       punpckldq %xmm3, %xmm9
+       punpckldq %xmm5, %xmm10
+       punpckldq %xmm7, %xmm11
+       movdqa %xmm0, %xmm1
+       movdqa %xmm4, %xmm3
+       movdqa %xmm8, %xmm5
+       movdqa %xmm10, %xmm7
+       punpckhqdq %xmm2, %xmm0
+       punpckhqdq %xmm6, %xmm4
+       punpckhqdq %xmm9, %xmm8
+       punpckhqdq %xmm11, %xmm10
+       punpcklqdq %xmm2, %xmm1
+       punpcklqdq %xmm6, %xmm3
+       punpcklqdq %xmm9, %xmm5
+       punpcklqdq %xmm11, %xmm7
+       andq %rsi, %rsi
+       jz .Lchacha_blocks_ssse3_noinput1
+       movdqu 0(%rsi), %xmm2
+       movdqu 16(%rsi), %xmm6
+       movdqu 64(%rsi), %xmm9
+       movdqu 80(%rsi), %xmm11
+       movdqu 128(%rsi), %xmm12
+       movdqu 144(%rsi), %xmm13
+       movdqu 192(%rsi), %xmm14
+       movdqu 208(%rsi), %xmm15
+       pxor %xmm2, %xmm5
+       pxor %xmm6, %xmm7
+       pxor %xmm9, %xmm8
+       pxor %xmm11, %xmm10
+       pxor %xmm12, %xmm1
+       pxor %xmm13, %xmm3
+       pxor %xmm14, %xmm0
+       pxor %xmm15, %xmm4
+       movdqu %xmm5, 0(%rdx)
+       movdqu %xmm7, 16(%rdx)
+       movdqu %xmm8, 64(%rdx)
+       movdqu %xmm10, 80(%rdx)
+       movdqu %xmm1, 128(%rdx)
+       movdqu %xmm3, 144(%rdx)
+       movdqu %xmm0, 192(%rdx)
+       movdqu %xmm4, 208(%rdx)
+       movdqa 384(%rsp), %xmm0
+       movdqa 400(%rsp), %xmm1
+       movdqa 416(%rsp), %xmm2
+       movdqa 432(%rsp), %xmm3
+       movdqa 448(%rsp), %xmm4
+       movdqa 464(%rsp), %xmm5
+       movdqa 480(%rsp), %xmm6
+       movdqa 496(%rsp), %xmm7
+       movdqa %xmm0, %xmm8
+       movdqa %xmm2, %xmm9
+       movdqa %xmm4, %xmm10
+       movdqa %xmm6, %xmm11
+       punpckldq %xmm1, %xmm8
+       punpckldq %xmm3, %xmm9
+       punpckhdq %xmm1, %xmm0
+       punpckhdq %xmm3, %xmm2
+       punpckldq %xmm5, %xmm10
+       punpckldq %xmm7, %xmm11
+       punpckhdq %xmm5, %xmm4
+       punpckhdq %xmm7, %xmm6
+       movdqa %xmm8, %xmm1
+       movdqa %xmm0, %xmm3
+       movdqa %xmm10, %xmm5
+       movdqa %xmm4, %xmm7
+       punpcklqdq %xmm9, %xmm1
+       punpcklqdq %xmm11, %xmm5
+       punpckhqdq %xmm9, %xmm8
+       punpckhqdq %xmm11, %xmm10
+       punpcklqdq %xmm2, %xmm3
+       punpcklqdq %xmm6, %xmm7
+       punpckhqdq %xmm2, %xmm0
+       punpckhqdq %xmm6, %xmm4
+       movdqu 32(%rsi), %xmm2
+       movdqu 48(%rsi), %xmm6
+       movdqu 96(%rsi), %xmm9
+       movdqu 112(%rsi), %xmm11
+       movdqu 160(%rsi), %xmm12
+       movdqu 176(%rsi), %xmm13
+       movdqu 224(%rsi), %xmm14
+       movdqu 240(%rsi), %xmm15
+       pxor %xmm2, %xmm1
+       pxor %xmm6, %xmm5
+       pxor %xmm9, %xmm8
+       pxor %xmm11, %xmm10
+       pxor %xmm12, %xmm3
+       pxor %xmm13, %xmm7
+       pxor %xmm14, %xmm0
+       pxor %xmm15, %xmm4
+       movdqu %xmm1, 32(%rdx)
+       movdqu %xmm5, 48(%rdx)
+       movdqu %xmm8, 96(%rdx)
+       movdqu %xmm10, 112(%rdx)
+       movdqu %xmm3, 160(%rdx)
+       movdqu %xmm7, 176(%rdx)
+       movdqu %xmm0, 224(%rdx)
+       movdqu %xmm4, 240(%rdx)
+       addq $256, %rsi
+       jmp .Lchacha_blocks_ssse3_mainloop_cont
+.Lchacha_blocks_ssse3_noinput1:
+       movdqu %xmm5, 0(%rdx)
+       movdqu %xmm7, 16(%rdx)
+       movdqu %xmm8, 64(%rdx)
+       movdqu %xmm10, 80(%rdx)
+       movdqu %xmm1, 128(%rdx)
+       movdqu %xmm3, 144(%rdx)
+       movdqu %xmm0, 192(%rdx)
+       movdqu %xmm4, 208(%rdx)
+       movdqa 384(%rsp), %xmm0
+       movdqa 400(%rsp), %xmm1
+       movdqa 416(%rsp), %xmm2
+       movdqa 432(%rsp), %xmm3
+       movdqa 448(%rsp), %xmm4
+       movdqa 464(%rsp), %xmm5
+       movdqa 480(%rsp), %xmm6
+       movdqa 496(%rsp), %xmm7
+       movdqa %xmm0, %xmm8
+       movdqa %xmm2, %xmm9
+       movdqa %xmm4, %xmm10
+       movdqa %xmm6, %xmm11
+       punpckldq %xmm1, %xmm8
+       punpckldq %xmm3, %xmm9
+       punpckhdq %xmm1, %xmm0
+       punpckhdq %xmm3, %xmm2
+       punpckldq %xmm5, %xmm10
+       punpckldq %xmm7, %xmm11
+       punpckhdq %xmm5, %xmm4
+       punpckhdq %xmm7, %xmm6
+       movdqa %xmm8, %xmm1
+       movdqa %xmm0, %xmm3
+       movdqa %xmm10, %xmm5
+       movdqa %xmm4, %xmm7
+       punpcklqdq %xmm9, %xmm1
+       punpcklqdq %xmm11, %xmm5
+       punpckhqdq %xmm9, %xmm8
+       punpckhqdq %xmm11, %xmm10
+       punpcklqdq %xmm2, %xmm3
+       punpcklqdq %xmm6, %xmm7
+       punpckhqdq %xmm2, %xmm0
+       punpckhqdq %xmm6, %xmm4
+       movdqu %xmm1, 32(%rdx)
+       movdqu %xmm5, 48(%rdx)
+       movdqu %xmm8, 96(%rdx)
+       movdqu %xmm10, 112(%rdx)
+       movdqu %xmm3, 160(%rdx)
+       movdqu %xmm7, 176(%rdx)
+       movdqu %xmm0, 224(%rdx)
+       movdqu %xmm4, 240(%rdx)
+.Lchacha_blocks_ssse3_mainloop_cont:
+       addq $256, %rdx
+       subq $256, %rcx
+       cmp $256, %rcx
+       jae .Lchacha_blocks_ssse3_atleast256
+       movdqa 80(%rsp), %xmm6
+       movdqa 96(%rsp), %xmm7
+       movdqa 0(%rsp), %xmm8
+       movdqa 16(%rsp), %xmm9
+       movdqa 32(%rsp), %xmm10
+       movdqa 48(%rsp), %xmm11
+       movq $1, %r9
+.Lchacha_blocks_ssse3_below256:
+       movq %r9, %xmm5
+       andq %rcx, %rcx
+       jz .Lchacha_blocks_ssse3_done
+       cmpq $64, %rcx
+       jae .Lchacha_blocks_ssse3_above63
+       movq %rdx, %r9
+       andq %rsi, %rsi
+       jz .Lchacha_blocks_ssse3_noinput2
+       movq %rcx, %r10
+       movq %rsp, %rdx
+       addq %r10, %rsi
+       addq %r10, %rdx
+       negq %r10
+.Lchacha_blocks_ssse3_copyinput:
+       movb (%rsi, %r10), %al
+       movb %al, (%rdx, %r10)
+       incq %r10
+       jnz .Lchacha_blocks_ssse3_copyinput
+       movq %rsp, %rsi
+.Lchacha_blocks_ssse3_noinput2:
+       movq %rsp, %rdx
+.Lchacha_blocks_ssse3_above63:
+       movdqa %xmm8, %xmm0
+       movdqa %xmm9, %xmm1
+       movdqa %xmm10, %xmm2
+       movdqa %xmm11, %xmm3
+       movq 64(%rsp), %rax
+.Lchacha_blocks_ssse3_mainloop2:
+       paddd %xmm1, %xmm0
+       pxor %xmm0, %xmm3
+       pshufb %xmm6, %xmm3
+       paddd %xmm3, %xmm2
+       pxor %xmm2, %xmm1
+       movdqa %xmm1, %xmm4
+       pslld $12, %xmm4
+       psrld $20, %xmm1
+       pxor %xmm4, %xmm1
+       paddd %xmm1, %xmm0
+       pxor %xmm0, %xmm3
+       pshufb %xmm7, %xmm3
+       pshufd $0x93, %xmm0, %xmm0
+       paddd %xmm3, %xmm2
+       pshufd $0x4e, %xmm3, %xmm3
+       pxor %xmm2, %xmm1
+       pshufd $0x39, %xmm2, %xmm2
+       movdqa %xmm1, %xmm4
+       pslld $7, %xmm4
+       psrld $25, %xmm1
+       pxor %xmm4, %xmm1
+       paddd %xmm1, %xmm0
+       pxor %xmm0, %xmm3
+       pshufb %xmm6, %xmm3
+       paddd %xmm3, %xmm2
+       pxor %xmm2, %xmm1
+       movdqa %xmm1, %xmm4
+       pslld $12, %xmm4
+       psrld $20, %xmm1
+       pxor %xmm4, %xmm1
+       paddd %xmm1, %xmm0
+       pxor %xmm0, %xmm3
+       pshufb %xmm7, %xmm3
+       pshufd $0x39, %xmm0, %xmm0
+       paddd %xmm3, %xmm2
+       pshufd $0x4e, %xmm3, %xmm3
+       pxor %xmm2, %xmm1
+       pshufd $0x93, %xmm2, %xmm2
+       movdqa %xmm1, %xmm4
+       pslld $7, %xmm4
+       psrld $25, %xmm1
+       pxor %xmm4, %xmm1
+       subq $2, %rax
+       jnz .Lchacha_blocks_ssse3_mainloop2
+       paddd %xmm8, %xmm0
+       paddd %xmm9, %xmm1
+       paddd %xmm10, %xmm2
+       paddd %xmm11, %xmm3
+       andq %rsi, %rsi
+       jz .Lchacha_blocks_ssse3_noinput3
+       movdqu 0(%rsi), %xmm12
+       movdqu 16(%rsi), %xmm13
+       movdqu 32(%rsi), %xmm14
+       movdqu 48(%rsi), %xmm15
+       pxor %xmm12, %xmm0
+       pxor %xmm13, %xmm1
+       pxor %xmm14, %xmm2
+       pxor %xmm15, %xmm3
+       addq $64, %rsi
+.Lchacha_blocks_ssse3_noinput3:
+       movdqu %xmm0, 0(%rdx)
+       movdqu %xmm1, 16(%rdx)
+       movdqu %xmm2, 32(%rdx)
+       movdqu %xmm3, 48(%rdx)
+       paddq %xmm5, %xmm11
+       cmpq $64, %rcx
+       jbe .Lchacha_blocks_ssse3_mainloop2_finishup
+       addq $64, %rdx
+       subq $64, %rcx
+       jmp .Lchacha_blocks_ssse3_below256
+.Lchacha_blocks_ssse3_mainloop2_finishup:
+       cmpq $64, %rcx
+       je .Lchacha_blocks_ssse3_done
+       addq %rcx, %r9
+       addq %rcx, %rdx
+       negq %rcx
+.Lchacha_blocks_ssse3_copyoutput:
+       movb (%rdx, %rcx), %al
+       movb %al, (%r9, %rcx)
+       incq %rcx
+       jnz .Lchacha_blocks_ssse3_copyoutput
+.Lchacha_blocks_ssse3_done:
+       movdqu %xmm11, 48(%rdi)
+       movq %rbp, %rsp
+       pxor %xmm15, %xmm15
+       pxor %xmm7, %xmm7
+       pxor %xmm14, %xmm14
+       pxor %xmm6, %xmm6
+       pxor %xmm13, %xmm13
+       pxor %xmm5, %xmm5
+       pxor %xmm12, %xmm12
+       pxor %xmm4, %xmm4
+       popq %rbp
+       popq %rbx
+       movl $(63 + 512 + 16), %eax
+       pxor %xmm11, %xmm11
+       pxor %xmm3, %xmm3
+       pxor %xmm10, %xmm10
+       pxor %xmm2, %xmm2
+       pxor %xmm9, %xmm9
+       pxor %xmm1, %xmm1
+       pxor %xmm8, %xmm8
+       pxor %xmm0, %xmm0
+       ret
+ELF(.size _gcry_chacha20_amd64_ssse3_blocks,.-_gcry_chacha20_amd64_ssse3_blocks;)
+
+.data
+.align 16;
+.LC:
+.byte 2,3,0,1,6,7,4,5,10,11,8,9,14,15,12,13       /* pshufb rotate by 16 */
+.byte 3,0,1,2,7,4,5,6,11,8,9,10,15,12,13,14       /* pshufb rotate by 8 */
+
+#endif /*defined(USE_CHACHA20)*/
+#endif /*__x86_64*/
diff --git a/cipher/chacha20.c b/cipher/chacha20.c
new file mode 100644 (file)
index 0000000..613fa82
--- /dev/null
@@ -0,0 +1,637 @@
+/* chacha20.c  -  Bernstein's ChaCha20 cipher
+ * Copyright (C) 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * For a description of the algorithm, see:
+ *   http://cr.yp.to/chacha.html
+ */
+
+/* The code is based on salsa20.c and public-domain ChaCha implementations:
+ *  chacha-ref.c version 20080118
+ *  D. J. Bernstein
+ *  Public domain.
+ * and
+ *  Andrew Moon
+ *  https://github.com/floodyberry/chacha-opt
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "types.h"
+#include "g10lib.h"
+#include "cipher.h"
+#include "bufhelp.h"
+
+
+#define CHACHA20_MIN_KEY_SIZE 16        /* Bytes.  */
+#define CHACHA20_MAX_KEY_SIZE 32        /* Bytes.  */
+#define CHACHA20_BLOCK_SIZE   64        /* Bytes.  */
+#define CHACHA20_MIN_IV_SIZE   8        /* Bytes.  */
+#define CHACHA20_MAX_IV_SIZE  12        /* Bytes.  */
+#define CHACHA20_CTR_SIZE     16        /* Bytes.  */
+#define CHACHA20_INPUT_LENGTH (CHACHA20_BLOCK_SIZE / 4)
+
+/* USE_SSE2 indicates whether to compile with Intel SSE2 code. */
+#undef USE_SSE2
+#if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+    defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define USE_SSE2 1
+#endif
+
+/* USE_SSSE3 indicates whether to compile with Intel SSSE3 code. */
+#undef USE_SSSE3
+#if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+    defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
+    defined(HAVE_GCC_INLINE_ASM_SSSE3)
+# define USE_SSSE3 1
+#endif
+
+/* USE_AVX2 indicates whether to compile with Intel AVX2 code. */
+#undef USE_AVX2
+#if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+    defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
+    defined(ENABLE_AVX2_SUPPORT)
+# define USE_AVX2 1
+#endif
+
+/* USE_NEON indicates whether to enable ARM NEON assembly code. */
+#undef USE_NEON
+#ifdef ENABLE_NEON_SUPPORT
+# if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) \
+     && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) \
+     && defined(HAVE_GCC_INLINE_ASM_NEON)
+#  define USE_NEON 1
+# endif
+#endif /*ENABLE_NEON_SUPPORT*/
+
+
+struct CHACHA20_context_s;
+
+
+/* Assembly implementations use SystemV ABI, ABI conversion and additional
+ * stack to store XMM6-XMM15 needed on Win64. */
+#undef ASM_FUNC_ABI
+#undef ASM_EXTRA_STACK
+#if (defined(USE_SSE2) || defined(USE_SSSE3) || defined(USE_AVX2)) && \
+    defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)
+# define ASM_FUNC_ABI __attribute__((sysv_abi))
+# define ASM_EXTRA_STACK (10 * 16)
+#else
+# define ASM_FUNC_ABI
+# define ASM_EXTRA_STACK 0
+#endif
+
+
+typedef unsigned int (* chacha20_blocks_t)(u32 *state, const byte *src,
+                                           byte *dst,
+                                           size_t bytes) ASM_FUNC_ABI;
+
+typedef struct CHACHA20_context_s
+{
+  u32 input[CHACHA20_INPUT_LENGTH];
+  u32 pad[CHACHA20_INPUT_LENGTH];
+  chacha20_blocks_t blocks;
+  unsigned int unused; /* bytes in the pad.  */
+} CHACHA20_context_t;
+
+
+#ifdef USE_SSE2
+
+unsigned int _gcry_chacha20_amd64_sse2_blocks(u32 *state, const byte *in,
+                                              byte *out,
+                                              size_t bytes) ASM_FUNC_ABI;
+
+#endif /* USE_SSE2 */
+
+#ifdef USE_SSSE3
+
+unsigned int _gcry_chacha20_amd64_ssse3_blocks(u32 *state, const byte *in,
+                                               byte *out,
+                                               size_t bytes) ASM_FUNC_ABI;
+
+#endif /* USE_SSSE3 */
+
+#ifdef USE_AVX2
+
+unsigned int _gcry_chacha20_amd64_avx2_blocks(u32 *state, const byte *in,
+                                              byte *out,
+                                              size_t bytes) ASM_FUNC_ABI;
+
+#endif /* USE_AVX2 */
+
+#ifdef USE_NEON
+
+unsigned int _gcry_chacha20_armv7_neon_blocks(u32 *state, const byte *in,
+                                              byte *out,
+                                              size_t bytes) ASM_FUNC_ABI;
+
+#endif /* USE_NEON */
+
+
+static void chacha20_setiv (void *context, const byte * iv, size_t ivlen);
+static const char *selftest (void);
+\f
+
+
+#define QROUND(a,b,c,d)         \
+  do {                          \
+    a += b; d = rol(d ^ a, 16); \
+    c += d; b = rol(b ^ c, 12); \
+    a += b; d = rol(d ^ a, 8);  \
+    c += d; b = rol(b ^ c, 7);  \
+  } while (0)
+
+#define QOUT(ai, bi, ci, di) \
+  DO_OUT(ai); DO_OUT(bi); DO_OUT(ci); DO_OUT(di)
+
+
+#ifndef USE_SSE2
+ASM_FUNC_ABI static unsigned int
+chacha20_blocks (u32 *state, const byte *src, byte *dst, size_t bytes)
+{
+  u32 pad[CHACHA20_INPUT_LENGTH];
+  u32 inp[CHACHA20_INPUT_LENGTH];
+  unsigned int i;
+
+  /* Note: 'bytes' must be multiple of 64 and not zero. */
+
+  inp[0] = state[0];
+  inp[1] = state[1];
+  inp[2] = state[2];
+  inp[3] = state[3];
+  inp[4] = state[4];
+  inp[5] = state[5];
+  inp[6] = state[6];
+  inp[7] = state[7];
+  inp[8] = state[8];
+  inp[9] = state[9];
+  inp[10] = state[10];
+  inp[11] = state[11];
+  inp[12] = state[12];
+  inp[13] = state[13];
+  inp[14] = state[14];
+  inp[15] = state[15];
+
+  do
+    {
+      /* First round. */
+      pad[0] = inp[0];
+      pad[4] = inp[4];
+      pad[8] = inp[8];
+      pad[12] = inp[12];
+      QROUND (pad[0], pad[4], pad[8], pad[12]);
+      pad[1] = inp[1];
+      pad[5] = inp[5];
+      pad[9] = inp[9];
+      pad[13] = inp[13];
+      QROUND (pad[1], pad[5], pad[9], pad[13]);
+      pad[2] = inp[2];
+      pad[6] = inp[6];
+      pad[10] = inp[10];
+      pad[14] = inp[14];
+      QROUND (pad[2], pad[6], pad[10], pad[14]);
+      pad[3] = inp[3];
+      pad[7] = inp[7];
+      pad[11] = inp[11];
+      pad[15] = inp[15];
+      QROUND (pad[3], pad[7], pad[11], pad[15]);
+
+      QROUND (pad[0], pad[5], pad[10], pad[15]);
+      QROUND (pad[1], pad[6], pad[11], pad[12]);
+      QROUND (pad[2], pad[7], pad[8], pad[13]);
+      QROUND (pad[3], pad[4], pad[9], pad[14]);
+
+      for (i = 2; i < 20 - 2; i += 2)
+      {
+        QROUND (pad[0], pad[4], pad[8], pad[12]);
+        QROUND (pad[1], pad[5], pad[9], pad[13]);
+        QROUND (pad[2], pad[6], pad[10], pad[14]);
+        QROUND (pad[3], pad[7], pad[11], pad[15]);
+
+        QROUND (pad[0], pad[5], pad[10], pad[15]);
+        QROUND (pad[1], pad[6], pad[11], pad[12]);
+        QROUND (pad[2], pad[7], pad[8], pad[13]);
+        QROUND (pad[3], pad[4], pad[9], pad[14]);
+      }
+
+      QROUND (pad[0], pad[4], pad[8], pad[12]);
+      QROUND (pad[1], pad[5], pad[9], pad[13]);
+      QROUND (pad[2], pad[6], pad[10], pad[14]);
+      QROUND (pad[3], pad[7], pad[11], pad[15]);
+
+      if (src)
+        {
+#define DO_OUT(idx) buf_put_le32(dst + (idx) * 4, \
+                                 (pad[idx] + inp[idx]) ^ \
+                                  buf_get_le32(src + (idx) * 4))
+          /* Last round. */
+          QROUND (pad[0], pad[5], pad[10], pad[15]);
+          QOUT(0, 5, 10, 15);
+          QROUND (pad[1], pad[6], pad[11], pad[12]);
+          QOUT(1, 6, 11, 12);
+          QROUND (pad[2], pad[7], pad[8], pad[13]);
+          QOUT(2, 7, 8, 13);
+          QROUND (pad[3], pad[4], pad[9], pad[14]);
+          QOUT(3, 4, 9, 14);
+#undef DO_OUT
+        }
+      else
+        {
+#define DO_OUT(idx) buf_put_le32(dst + (idx) * 4, pad[idx] + inp[idx])
+          /* Last round. */
+          QROUND (pad[0], pad[5], pad[10], pad[15]);
+          QOUT(0, 5, 10, 15);
+          QROUND (pad[1], pad[6], pad[11], pad[12]);
+          QOUT(1, 6, 11, 12);
+          QROUND (pad[2], pad[7], pad[8], pad[13]);
+          QOUT(2, 7, 8, 13);
+          QROUND (pad[3], pad[4], pad[9], pad[14]);
+          QOUT(3, 4, 9, 14);
+#undef DO_OUT
+        }
+
+      /* Update counter. */
+      inp[13] += (!++inp[12]);
+
+      bytes -= CHACHA20_BLOCK_SIZE;
+      dst += CHACHA20_BLOCK_SIZE;
+      src += (src) ? CHACHA20_BLOCK_SIZE : 0;
+    }
+  while (bytes >= CHACHA20_BLOCK_SIZE);
+
+  state[12] = inp[12];
+  state[13] = inp[13];
+
+  /* burn_stack */
+  return (2 * CHACHA20_INPUT_LENGTH * sizeof(u32) + 6 * sizeof(void *));
+}
+#endif /*!USE_SSE2*/
+
+#undef QROUND
+#undef QOUT
+
+
+static unsigned int
+chacha20_core(u32 *dst, struct CHACHA20_context_s *ctx)
+{
+  return ctx->blocks(ctx->input, NULL, (byte *)dst, CHACHA20_BLOCK_SIZE)
+         + ASM_EXTRA_STACK;
+}
+
+
+static void
+chacha20_keysetup (CHACHA20_context_t * ctx, const byte * key,
+                   unsigned int keylen)
+{
+  /* These constants are the little endian encoding of the string
+     "expand 32-byte k".  For the 128 bit variant, the "32" in that
+     string will be fixed up to "16".  */
+  ctx->input[0] = 0x61707865;        /* "apxe"  */
+  ctx->input[1] = 0x3320646e;        /* "3 dn"  */
+  ctx->input[2] = 0x79622d32;        /* "yb-2"  */
+  ctx->input[3] = 0x6b206574;        /* "k et"  */
+
+  ctx->input[4] = buf_get_le32 (key + 0);
+  ctx->input[5] = buf_get_le32 (key + 4);
+  ctx->input[6] = buf_get_le32 (key + 8);
+  ctx->input[7] = buf_get_le32 (key + 12);
+
+  if (keylen == CHACHA20_MAX_KEY_SIZE) /* 256 bits */
+    {
+      ctx->input[8] = buf_get_le32 (key + 16);
+      ctx->input[9] = buf_get_le32 (key + 20);
+      ctx->input[10] = buf_get_le32 (key + 24);
+      ctx->input[11] = buf_get_le32 (key + 28);
+    }
+  else /* 128 bits */
+    {
+      ctx->input[8] = ctx->input[4];
+      ctx->input[9] = ctx->input[5];
+      ctx->input[10] = ctx->input[6];
+      ctx->input[11] = ctx->input[7];
+
+      ctx->input[1] -= 0x02000000;        /* Change to "1 dn".  */
+      ctx->input[2] += 0x00000004;        /* Change to "yb-6".  */
+    }
+}
+
+
+static void
+chacha20_ivsetup (CHACHA20_context_t * ctx, const byte * iv, size_t ivlen)
+{
+  if (ivlen == CHACHA20_CTR_SIZE)
+    {
+      ctx->input[12] = buf_get_le32 (iv + 0);
+      ctx->input[13] = buf_get_le32 (iv + 4);
+      ctx->input[14] = buf_get_le32 (iv + 8);
+      ctx->input[15] = buf_get_le32 (iv + 12);
+    }
+  else if (ivlen == CHACHA20_MAX_IV_SIZE)
+    {
+      ctx->input[12] = 0;
+      ctx->input[13] = buf_get_le32 (iv + 0);
+      ctx->input[14] = buf_get_le32 (iv + 4);
+      ctx->input[15] = buf_get_le32 (iv + 8);
+    }
+  else if (ivlen == CHACHA20_MIN_IV_SIZE)
+    {
+      ctx->input[12] = 0;
+      ctx->input[13] = 0;
+      ctx->input[14] = buf_get_le32 (iv + 0);
+      ctx->input[15] = buf_get_le32 (iv + 4);
+    }
+  else
+    {
+      ctx->input[12] = 0;
+      ctx->input[13] = 0;
+      ctx->input[14] = 0;
+      ctx->input[15] = 0;
+    }
+}
+
+
+static gcry_err_code_t
+chacha20_do_setkey (CHACHA20_context_t * ctx,
+                    const byte * key, unsigned int keylen)
+{
+  static int initialized;
+  static const char *selftest_failed;
+  unsigned int features = _gcry_get_hw_features ();
+
+  if (!initialized)
+    {
+      initialized = 1;
+      selftest_failed = selftest ();
+      if (selftest_failed)
+        log_error ("CHACHA20 selftest failed (%s)\n", selftest_failed);
+    }
+  if (selftest_failed)
+    return GPG_ERR_SELFTEST_FAILED;
+
+  if (keylen != CHACHA20_MAX_KEY_SIZE && keylen != CHACHA20_MIN_KEY_SIZE)
+    return GPG_ERR_INV_KEYLEN;
+
+#ifdef USE_SSE2
+  ctx->blocks = _gcry_chacha20_amd64_sse2_blocks;
+#else
+  ctx->blocks = chacha20_blocks;
+#endif
+
+#ifdef USE_SSSE3
+  if (features & HWF_INTEL_SSSE3)
+    ctx->blocks = _gcry_chacha20_amd64_ssse3_blocks;
+#endif
+#ifdef USE_AVX2
+  if (features & HWF_INTEL_AVX2)
+    ctx->blocks = _gcry_chacha20_amd64_avx2_blocks;
+#endif
+#ifdef USE_NEON
+  if (features & HWF_ARM_NEON)
+    ctx->blocks = _gcry_chacha20_armv7_neon_blocks;
+#endif
+
+  (void)features;
+
+  chacha20_keysetup (ctx, key, keylen);
+
+  /* We default to a zero nonce.  */
+  chacha20_setiv (ctx, NULL, 0);
+
+  return 0;
+}
+
+
+static gcry_err_code_t
+chacha20_setkey (void *context, const byte * key, unsigned int keylen)
+{
+  CHACHA20_context_t *ctx = (CHACHA20_context_t *) context;
+  gcry_err_code_t rc = chacha20_do_setkey (ctx, key, keylen);
+  _gcry_burn_stack (4 + sizeof (void *) + 4 * sizeof (void *));
+  return rc;
+}
+
+
+static void
+chacha20_setiv (void *context, const byte * iv, size_t ivlen)
+{
+  CHACHA20_context_t *ctx = (CHACHA20_context_t *) context;
+
+  /* draft-nir-cfrg-chacha20-poly1305-02 defines 96-bit and 64-bit nonce. */
+  if (iv && ivlen != CHACHA20_MAX_IV_SIZE && ivlen != CHACHA20_MIN_IV_SIZE
+      && ivlen != CHACHA20_CTR_SIZE)
+    log_info ("WARNING: chacha20_setiv: bad ivlen=%u\n", (u32) ivlen);
+
+  if (iv && (ivlen == CHACHA20_MAX_IV_SIZE || ivlen == CHACHA20_MIN_IV_SIZE
+             || ivlen == CHACHA20_CTR_SIZE))
+    chacha20_ivsetup (ctx, iv, ivlen);
+  else
+    chacha20_ivsetup (ctx, NULL, 0);
+
+  /* Reset the unused pad bytes counter.  */
+  ctx->unused = 0;
+}
+\f
+
+
+/* Note: This function requires LENGTH > 0.  */
+static void
+chacha20_do_encrypt_stream (CHACHA20_context_t * ctx,
+                            byte * outbuf, const byte * inbuf, size_t length)
+{
+  unsigned int nburn, burn = 0;
+
+  if (ctx->unused)
+    {
+      unsigned char *p = (void *) ctx->pad;
+      size_t n;
+
+      gcry_assert (ctx->unused < CHACHA20_BLOCK_SIZE);
+
+      n = ctx->unused;
+      if (n > length)
+        n = length;
+      buf_xor (outbuf, inbuf, p + CHACHA20_BLOCK_SIZE - ctx->unused, n);
+      length -= n;
+      outbuf += n;
+      inbuf += n;
+      ctx->unused -= n;
+      if (!length)
+        return;
+      gcry_assert (!ctx->unused);
+    }
+
+  if (length >= CHACHA20_BLOCK_SIZE)
+    {
+      size_t nblocks = length / CHACHA20_BLOCK_SIZE;
+      size_t bytes = nblocks * CHACHA20_BLOCK_SIZE;
+      burn = ctx->blocks(ctx->input, inbuf, outbuf, bytes);
+      length -= bytes;
+      outbuf += bytes;
+      inbuf  += bytes;
+    }
+
+  if (length > 0)
+    {
+      nburn = chacha20_core (ctx->pad, ctx);
+      burn = nburn > burn ? nburn : burn;
+
+      buf_xor (outbuf, inbuf, ctx->pad, length);
+      ctx->unused = CHACHA20_BLOCK_SIZE - length;
+    }
+
+  _gcry_burn_stack (burn);
+}
+
+
+static void
+chacha20_encrypt_stream (void *context, byte * outbuf, const byte * inbuf,
+                         size_t length)
+{
+  CHACHA20_context_t *ctx = (CHACHA20_context_t *) context;
+
+  if (length)
+    chacha20_do_encrypt_stream (ctx, outbuf, inbuf, length);
+}
+
+
+static const char *
+selftest (void)
+{
+  byte ctxbuf[sizeof(CHACHA20_context_t) + 15];
+  CHACHA20_context_t *ctx;
+  byte scratch[127 + 1];
+  byte buf[512 + 64 + 4];
+  int i;
+
+  /* From draft-strombergson-chacha-test-vectors */
+  static byte key_1[] = {
+    0xc4, 0x6e, 0xc1, 0xb1, 0x8c, 0xe8, 0xa8, 0x78,
+    0x72, 0x5a, 0x37, 0xe7, 0x80, 0xdf, 0xb7, 0x35,
+    0x1f, 0x68, 0xed, 0x2e, 0x19, 0x4c, 0x79, 0xfb,
+    0xc6, 0xae, 0xbe, 0xe1, 0xa6, 0x67, 0x97, 0x5d
+  };
+  static const byte nonce_1[] =
+    { 0x1a, 0xda, 0x31, 0xd5, 0xcf, 0x68, 0x82, 0x21 };
+  static const byte plaintext_1[127] = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
+  static const byte ciphertext_1[127] = {
+    0xf6, 0x3a, 0x89, 0xb7, 0x5c, 0x22, 0x71, 0xf9,
+    0x36, 0x88, 0x16, 0x54, 0x2b, 0xa5, 0x2f, 0x06,
+    0xed, 0x49, 0x24, 0x17, 0x92, 0x30, 0x2b, 0x00,
+    0xb5, 0xe8, 0xf8, 0x0a, 0xe9, 0xa4, 0x73, 0xaf,
+    0xc2, 0x5b, 0x21, 0x8f, 0x51, 0x9a, 0xf0, 0xfd,
+    0xd4, 0x06, 0x36, 0x2e, 0x8d, 0x69, 0xde, 0x7f,
+    0x54, 0xc6, 0x04, 0xa6, 0xe0, 0x0f, 0x35, 0x3f,
+    0x11, 0x0f, 0x77, 0x1b, 0xdc, 0xa8, 0xab, 0x92,
+    0xe5, 0xfb, 0xc3, 0x4e, 0x60, 0xa1, 0xd9, 0xa9,
+    0xdb, 0x17, 0x34, 0x5b, 0x0a, 0x40, 0x27, 0x36,
+    0x85, 0x3b, 0xf9, 0x10, 0xb0, 0x60, 0xbd, 0xf1,
+    0xf8, 0x97, 0xb6, 0x29, 0x0f, 0x01, 0xd1, 0x38,
+    0xae, 0x2c, 0x4c, 0x90, 0x22, 0x5b, 0xa9, 0xea,
+    0x14, 0xd5, 0x18, 0xf5, 0x59, 0x29, 0xde, 0xa0,
+    0x98, 0xca, 0x7a, 0x6c, 0xcf, 0xe6, 0x12, 0x27,
+    0x05, 0x3c, 0x84, 0xe4, 0x9a, 0x4a, 0x33
+  };
+
+  /* 16-byte alignment required for amd64 implementation. */
+  ctx = (CHACHA20_context_t *)((uintptr_t)(ctxbuf + 15) & ~(uintptr_t)15);
+
+  chacha20_setkey (ctx, key_1, sizeof key_1);
+  chacha20_setiv (ctx, nonce_1, sizeof nonce_1);
+  scratch[sizeof (scratch) - 1] = 0;
+  chacha20_encrypt_stream (ctx, scratch, plaintext_1, sizeof plaintext_1);
+  if (memcmp (scratch, ciphertext_1, sizeof ciphertext_1))
+    return "ChaCha20 encryption test 1 failed.";
+  if (scratch[sizeof (scratch) - 1])
+    return "ChaCha20 wrote too much.";
+  chacha20_setkey (ctx, key_1, sizeof (key_1));
+  chacha20_setiv (ctx, nonce_1, sizeof nonce_1);
+  chacha20_encrypt_stream (ctx, scratch, scratch, sizeof plaintext_1);
+  if (memcmp (scratch, plaintext_1, sizeof plaintext_1))
+    return "ChaCha20 decryption test 1 failed.";
+
+  for (i = 0; i < sizeof buf; i++)
+    buf[i] = i;
+  chacha20_setkey (ctx, key_1, sizeof key_1);
+  chacha20_setiv (ctx, nonce_1, sizeof nonce_1);
+  /*encrypt */
+  chacha20_encrypt_stream (ctx, buf, buf, sizeof buf);
+  /*decrypt */
+  chacha20_setkey (ctx, key_1, sizeof key_1);
+  chacha20_setiv (ctx, nonce_1, sizeof nonce_1);
+  chacha20_encrypt_stream (ctx, buf, buf, 1);
+  chacha20_encrypt_stream (ctx, buf + 1, buf + 1, (sizeof buf) - 1 - 1);
+  chacha20_encrypt_stream (ctx, buf + (sizeof buf) - 1,
+                           buf + (sizeof buf) - 1, 1);
+  for (i = 0; i < sizeof buf; i++)
+    if (buf[i] != (byte) i)
+      return "ChaCha20 encryption test 2 failed.";
+
+  chacha20_setkey (ctx, key_1, sizeof key_1);
+  chacha20_setiv (ctx, nonce_1, sizeof nonce_1);
+  /* encrypt */
+  for (i = 0; i < sizeof buf; i++)
+    chacha20_encrypt_stream (ctx, &buf[i], &buf[i], 1);
+  /* decrypt */
+  chacha20_setkey (ctx, key_1, sizeof key_1);
+  chacha20_setiv (ctx, nonce_1, sizeof nonce_1);
+  chacha20_encrypt_stream (ctx, buf, buf, sizeof buf);
+  for (i = 0; i < sizeof buf; i++)
+    if (buf[i] != (byte) i)
+      return "ChaCha20 encryption test 3 failed.";
+
+  return NULL;
+}
+
+
+gcry_cipher_spec_t _gcry_cipher_spec_chacha20 = {
+  GCRY_CIPHER_CHACHA20,
+  {0, 0},                       /* flags */
+  "CHACHA20",                   /* name */
+  NULL,                         /* aliases */
+  NULL,                         /* oids */
+  1,                            /* blocksize in bytes. */
+  CHACHA20_MAX_KEY_SIZE * 8,    /* standard key length in bits. */
+  sizeof (CHACHA20_context_t),
+  chacha20_setkey,
+  NULL,
+  NULL,
+  chacha20_encrypt_stream,
+  chacha20_encrypt_stream,
+  NULL,
+  NULL,
+  chacha20_setiv
+};
index 50ac107..698742d 100644 (file)
@@ -25,7 +25,6 @@
 
 #include "g10lib.h"
 #include "cipher.h"
-#include "ath.h"
 #include "bufhelp.h"
 #include "./cipher-internal.h"
 
index 4b929da..67814b7 100644 (file)
@@ -26,7 +26,6 @@
 
 #include "g10lib.h"
 #include "cipher.h"
-#include "ath.h"
 #include "./cipher-internal.h"
 #include "bufhelp.h"
 
index 47f2162..4d8f816 100644 (file)
@@ -1,5 +1,5 @@
 /* cipher-ccm.c - CTR mode with CBC-MAC mode implementation
- * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
 
 #include "g10lib.h"
 #include "cipher.h"
-#include "ath.h"
 #include "bufhelp.h"
 #include "./cipher-internal.h"
 
-/* We need a 64 bit type for this code.  */
-#ifdef HAVE_U64_TYPEDEF
-
 
 #define set_burn(burn, nburn) do { \
   unsigned int __nburn = (nburn); \
@@ -365,78 +361,3 @@ _gcry_cipher_ccm_decrypt (gcry_cipher_hd_t c, unsigned char *outbuf,
 
   return err;
 }
-
-#else
-
-/*
- * Provide dummy functions so that we avoid adding too much #ifdefs in
- * cipher.c.
- */
-
-gcry_err_code_t
-_gcry_cipher_ccm_encrypt(gcry_cipher_hd_t c, unsigned char *outbuf,
-                        size_t outbuflen, const unsigned char *inbuf,
-                        size_t inbuflen)
-{
-  (void)c;
-  (void)outbuf;
-  (void)outbuflen;
-  (void)inbuf;
-  (void)inbuflen;
-  return GPG_ERR_NOT_SUPPORTED;
-}
-
-gcry_err_code_t
-_gcry_cipher_ccm_decrypt(gcry_cipher_hd_t c, unsigned char *outbuf,
-                        size_t outbuflen, const unsigned char *inbuf,
-                        size_t inbuflen)
-{
-  (void)c;
-  (void)outbuf;
-  (void)outbuflen;
-  (void)inbuf;
-  (void)inbuflen;
-  return GPG_ERR_NOT_SUPPORTED;
-}
-
-gcry_err_code_t
-_gcry_cipher_ccm_set_nonce(gcry_cipher_hd_t c, const unsigned char *nonce,
-                          size_t noncelen)
-{
-  (void)c;
-  (void)nonce;
-  (void)noncelen;
-  return GPG_ERR_NOT_SUPPORTED;
-}
-
-gcry_err_code_t
-_gcry_cipher_ccm_authenticate(gcry_cipher_hd_t c, const unsigned char *abuf,
-                             size_t abuflen)
-{
-  (void)c;
-  (void)abuf;
-  (void)abuflen;
-  return GPG_ERR_NOT_SUPPORTED;
-}
-
-gcry_err_code_t
-_gcry_cipher_ccm_get_tag(gcry_cipher_hd_t c, unsigned char *outtag,
-                        size_t taglen)
-{
-  (void)c;
-  (void)outtag;
-  (void)taglen;
-  return GPG_ERR_NOT_SUPPORTED;
-}
-
-gcry_err_code_t
-_gcry_cipher_ccm_check_tag(gcry_cipher_hd_t c, const unsigned char *intag,
-                          size_t taglen)
-{
-  (void)c;
-  (void)intag;
-  (void)taglen;
-  return GPG_ERR_NOT_SUPPORTED;
-}
-
-#endif /*HAVE_U64_TYPEDEF*/
index 8539f54..f289ed3 100644 (file)
@@ -26,7 +26,6 @@
 
 #include "g10lib.h"
 #include "cipher.h"
-#include "ath.h"
 #include "bufhelp.h"
 #include "./cipher-internal.h"
 
index 25d5db2..eca1c1a 100644 (file)
@@ -1,5 +1,5 @@
 /* cmac.c - CMAC, Cipher-based MAC.
- * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
index 1e7133c..4bbfaae 100644 (file)
@@ -26,7 +26,6 @@
 
 #include "g10lib.h"
 #include "cipher.h"
-#include "ath.h"
 #include "bufhelp.h"
 #include "./cipher-internal.h"
 
diff --git a/cipher/cipher-gcm-intel-pclmul.c b/cipher/cipher-gcm-intel-pclmul.c
new file mode 100644 (file)
index 0000000..a327249
--- /dev/null
@@ -0,0 +1,474 @@
+/* cipher-gcm-intel-pclmul.c  -  Intel PCLMUL accelerated Galois Counter Mode
+ *                               implementation
+ * Copyright (C) 2013-2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "bufhelp.h"
+#include "./cipher-internal.h"
+
+
+#ifdef GCM_USE_INTEL_PCLMUL
+
+
+#if _GCRY_GCC_VERSION >= 40400 /* 4.4 */
+/* Prevent compiler from issuing SSE instructions between asm blocks. */
+#  pragma GCC target("no-sse")
+#endif
+
+
+/*
+ Intel PCLMUL ghash based on white paper:
+  "Intel® Carry-Less Multiplication Instruction and its Usage for Computing the
+   GCM Mode - Rev 2.01"; Shay Gueron, Michael E. Kounavis.
+ */
+static inline void gfmul_pclmul(void)
+{
+  /* Input: XMM0 and XMM1, Output: XMM1. Input XMM0 stays unmodified.
+     Input must be converted to little-endian.
+   */
+  asm volatile (/* gfmul, xmm0 has operator a and xmm1 has operator b. */
+                "pshufd $78, %%xmm0, %%xmm2\n\t"
+                "pshufd $78, %%xmm1, %%xmm4\n\t"
+                "pxor %%xmm0, %%xmm2\n\t" /* xmm2 holds a0+a1 */
+                "pxor %%xmm1, %%xmm4\n\t" /* xmm4 holds b0+b1 */
+
+                "movdqa %%xmm0, %%xmm3\n\t"
+                "pclmulqdq $0, %%xmm1, %%xmm3\n\t"  /* xmm3 holds a0*b0 */
+                "movdqa %%xmm0, %%xmm6\n\t"
+                "pclmulqdq $17, %%xmm1, %%xmm6\n\t" /* xmm6 holds a1*b1 */
+                "movdqa %%xmm3, %%xmm5\n\t"
+                "pclmulqdq $0, %%xmm2, %%xmm4\n\t"  /* xmm4 holds (a0+a1)*(b0+b1) */
+
+                "pxor %%xmm6, %%xmm5\n\t" /* xmm5 holds a0*b0+a1*b1 */
+                "pxor %%xmm5, %%xmm4\n\t" /* xmm4 holds a0*b0+a1*b1+(a0+a1)*(b0+b1) */
+                "movdqa %%xmm4, %%xmm5\n\t"
+                "psrldq $8, %%xmm4\n\t"
+                "pslldq $8, %%xmm5\n\t"
+                "pxor %%xmm5, %%xmm3\n\t"
+                "pxor %%xmm4, %%xmm6\n\t" /* <xmm6:xmm3> holds the result of the
+                                             carry-less multiplication of xmm0
+                                             by xmm1 */
+
+                /* shift the result by one bit position to the left cope for
+                   the fact that bits are reversed */
+                "movdqa %%xmm3, %%xmm4\n\t"
+                "movdqa %%xmm6, %%xmm5\n\t"
+                "pslld $1, %%xmm3\n\t"
+                "pslld $1, %%xmm6\n\t"
+                "psrld $31, %%xmm4\n\t"
+                "psrld $31, %%xmm5\n\t"
+                "movdqa %%xmm4, %%xmm1\n\t"
+                "pslldq $4, %%xmm5\n\t"
+                "pslldq $4, %%xmm4\n\t"
+                "psrldq $12, %%xmm1\n\t"
+                "por %%xmm4, %%xmm3\n\t"
+                "por %%xmm5, %%xmm6\n\t"
+                "por %%xmm6, %%xmm1\n\t"
+
+                /* first phase of the reduction */
+                "movdqa %%xmm3, %%xmm6\n\t"
+                "movdqa %%xmm3, %%xmm7\n\t"
+                "pslld $31, %%xmm6\n\t"  /* packed right shifting << 31 */
+                "movdqa %%xmm3, %%xmm5\n\t"
+                "pslld $30, %%xmm7\n\t"  /* packed right shifting shift << 30 */
+                "pslld $25, %%xmm5\n\t"  /* packed right shifting shift << 25 */
+                "pxor %%xmm7, %%xmm6\n\t" /* xor the shifted versions */
+                "pxor %%xmm5, %%xmm6\n\t"
+                "movdqa %%xmm6, %%xmm7\n\t"
+                "pslldq $12, %%xmm6\n\t"
+                "psrldq $4, %%xmm7\n\t"
+                "pxor %%xmm6, %%xmm3\n\t" /* first phase of the reduction
+                                             complete */
+
+                /* second phase of the reduction */
+                "movdqa %%xmm3, %%xmm2\n\t"
+                "movdqa %%xmm3, %%xmm4\n\t"
+                "psrld $1, %%xmm2\n\t"    /* packed left shifting >> 1 */
+                "movdqa %%xmm3, %%xmm5\n\t"
+                "psrld $2, %%xmm4\n\t"    /* packed left shifting >> 2 */
+                "psrld $7, %%xmm5\n\t"    /* packed left shifting >> 7 */
+                "pxor %%xmm4, %%xmm2\n\t" /* xor the shifted versions */
+                "pxor %%xmm5, %%xmm2\n\t"
+                "pxor %%xmm7, %%xmm2\n\t"
+                "pxor %%xmm2, %%xmm3\n\t"
+                "pxor %%xmm3, %%xmm1\n\t" /* the result is in xmm1 */
+                ::: "cc" );
+}
+
+
+#ifdef __x86_64__
+static inline void gfmul_pclmul_aggr4(void)
+{
+  /* Input:
+      H¹: XMM0          X_i            : XMM6
+      H²: XMM8          X_(i-1)        : XMM3
+      H³: XMM9          X_(i-2)        : XMM2
+      H⁴: XMM10         X_(i-3)⊕Y_(i-4): XMM1
+     Output:
+      Y_i: XMM1
+     Inputs XMM0 stays unmodified.
+     Input must be converted to little-endian.
+   */
+  asm volatile (/* perform clmul and merge results... */
+                "pshufd $78, %%xmm10, %%xmm11\n\t"
+                "pshufd $78, %%xmm1, %%xmm12\n\t"
+                "pxor %%xmm10, %%xmm11\n\t" /* xmm11 holds 4:a0+a1 */
+                "pxor %%xmm1, %%xmm12\n\t" /* xmm12 holds 4:b0+b1 */
+
+                "pshufd $78, %%xmm9, %%xmm13\n\t"
+                "pshufd $78, %%xmm2, %%xmm14\n\t"
+                "pxor %%xmm9, %%xmm13\n\t" /* xmm13 holds 3:a0+a1 */
+                "pxor %%xmm2, %%xmm14\n\t" /* xmm14 holds 3:b0+b1 */
+
+                "pshufd $78, %%xmm8, %%xmm5\n\t"
+                "pshufd $78, %%xmm3, %%xmm15\n\t"
+                "pxor %%xmm8, %%xmm5\n\t" /* xmm1 holds 2:a0+a1 */
+                "pxor %%xmm3, %%xmm15\n\t" /* xmm2 holds 2:b0+b1 */
+
+                "movdqa %%xmm10, %%xmm4\n\t"
+                "movdqa %%xmm9, %%xmm7\n\t"
+                "pclmulqdq $0, %%xmm1, %%xmm4\n\t"   /* xmm4 holds 4:a0*b0 */
+                "pclmulqdq $0, %%xmm2, %%xmm7\n\t"   /* xmm7 holds 3:a0*b0 */
+                "pclmulqdq $17, %%xmm10, %%xmm1\n\t" /* xmm1 holds 4:a1*b1 */
+                "pclmulqdq $17, %%xmm9, %%xmm2\n\t"  /* xmm9 holds 3:a1*b1 */
+                "pclmulqdq $0, %%xmm11, %%xmm12\n\t" /* xmm12 holds 4:(a0+a1)*(b0+b1) */
+                "pclmulqdq $0, %%xmm13, %%xmm14\n\t" /* xmm14 holds 3:(a0+a1)*(b0+b1) */
+
+                "pshufd $78, %%xmm0, %%xmm10\n\t"
+                "pshufd $78, %%xmm6, %%xmm11\n\t"
+                "pxor %%xmm0, %%xmm10\n\t" /* xmm10 holds 1:a0+a1 */
+                "pxor %%xmm6, %%xmm11\n\t" /* xmm11 holds 1:b0+b1 */
+
+                "pxor %%xmm4, %%xmm7\n\t"   /* xmm7 holds 3+4:a0*b0 */
+                "pxor %%xmm2, %%xmm1\n\t"   /* xmm1 holds 3+4:a1*b1 */
+                "pxor %%xmm14, %%xmm12\n\t" /* xmm12 holds 3+4:(a0+a1)*(b0+b1) */
+
+                "movdqa %%xmm8, %%xmm13\n\t"
+                "pclmulqdq $0, %%xmm3, %%xmm13\n\t"  /* xmm13 holds 2:a0*b0 */
+                "pclmulqdq $17, %%xmm8, %%xmm3\n\t"  /* xmm3 holds 2:a1*b1 */
+                "pclmulqdq $0, %%xmm5, %%xmm15\n\t" /* xmm15 holds 2:(a0+a1)*(b0+b1) */
+
+                "pxor %%xmm13, %%xmm7\n\t" /* xmm7 holds 2+3+4:a0*b0 */
+                "pxor %%xmm3, %%xmm1\n\t"  /* xmm1 holds 2+3+4:a1*b1 */
+                "pxor %%xmm15, %%xmm12\n\t" /* xmm12 holds 2+3+4:(a0+a1)*(b0+b1) */
+
+                "movdqa %%xmm0, %%xmm3\n\t"
+                "pclmulqdq $0, %%xmm6, %%xmm3\n\t"  /* xmm3 holds 1:a0*b0 */
+                "pclmulqdq $17, %%xmm0, %%xmm6\n\t" /* xmm6 holds 1:a1*b1 */
+                "movdqa %%xmm11, %%xmm4\n\t"
+                "pclmulqdq $0, %%xmm10, %%xmm4\n\t" /* xmm4 holds 1:(a0+a1)*(b0+b1) */
+
+                "pxor %%xmm7, %%xmm3\n\t"  /* xmm3 holds 1+2+3+4:a0*b0 */
+                "pxor %%xmm1, %%xmm6\n\t"  /* xmm6 holds 1+2+3+4:a1*b1 */
+                "pxor %%xmm12, %%xmm4\n\t" /* xmm4 holds 1+2+3+4:(a0+a1)*(b0+b1) */
+
+                /* aggregated reduction... */
+                "movdqa %%xmm3, %%xmm5\n\t"
+                "pxor %%xmm6, %%xmm5\n\t" /* xmm5 holds a0*b0+a1*b1 */
+                "pxor %%xmm5, %%xmm4\n\t" /* xmm4 holds a0*b0+a1*b1+(a0+a1)*(b0+b1) */
+                "movdqa %%xmm4, %%xmm5\n\t"
+                "psrldq $8, %%xmm4\n\t"
+                "pslldq $8, %%xmm5\n\t"
+                "pxor %%xmm5, %%xmm3\n\t"
+                "pxor %%xmm4, %%xmm6\n\t" /* <xmm6:xmm3> holds the result of the
+                                             carry-less multiplication of xmm0
+                                             by xmm1 */
+
+                /* shift the result by one bit position to the left cope for
+                   the fact that bits are reversed */
+                "movdqa %%xmm3, %%xmm4\n\t"
+                "movdqa %%xmm6, %%xmm5\n\t"
+                "pslld $1, %%xmm3\n\t"
+                "pslld $1, %%xmm6\n\t"
+                "psrld $31, %%xmm4\n\t"
+                "psrld $31, %%xmm5\n\t"
+                "movdqa %%xmm4, %%xmm1\n\t"
+                "pslldq $4, %%xmm5\n\t"
+                "pslldq $4, %%xmm4\n\t"
+                "psrldq $12, %%xmm1\n\t"
+                "por %%xmm4, %%xmm3\n\t"
+                "por %%xmm5, %%xmm6\n\t"
+                "por %%xmm6, %%xmm1\n\t"
+
+                /* first phase of the reduction */
+                "movdqa %%xmm3, %%xmm6\n\t"
+                "movdqa %%xmm3, %%xmm7\n\t"
+                "pslld $31, %%xmm6\n\t"  /* packed right shifting << 31 */
+                "movdqa %%xmm3, %%xmm5\n\t"
+                "pslld $30, %%xmm7\n\t"  /* packed right shifting shift << 30 */
+                "pslld $25, %%xmm5\n\t"  /* packed right shifting shift << 25 */
+                "pxor %%xmm7, %%xmm6\n\t" /* xor the shifted versions */
+                "pxor %%xmm5, %%xmm6\n\t"
+                "movdqa %%xmm6, %%xmm7\n\t"
+                "pslldq $12, %%xmm6\n\t"
+                "psrldq $4, %%xmm7\n\t"
+                "pxor %%xmm6, %%xmm3\n\t" /* first phase of the reduction
+                                             complete */
+
+                /* second phase of the reduction */
+                "movdqa %%xmm3, %%xmm2\n\t"
+                "movdqa %%xmm3, %%xmm4\n\t"
+                "psrld $1, %%xmm2\n\t"    /* packed left shifting >> 1 */
+                "movdqa %%xmm3, %%xmm5\n\t"
+                "psrld $2, %%xmm4\n\t"    /* packed left shifting >> 2 */
+                "psrld $7, %%xmm5\n\t"    /* packed left shifting >> 7 */
+                "pxor %%xmm4, %%xmm2\n\t" /* xor the shifted versions */
+                "pxor %%xmm5, %%xmm2\n\t"
+                "pxor %%xmm7, %%xmm2\n\t"
+                "pxor %%xmm2, %%xmm3\n\t"
+                "pxor %%xmm3, %%xmm1\n\t" /* the result is in xmm1 */
+                :::"cc");
+}
+#endif
+
+
+void
+_gcry_ghash_setup_intel_pclmul (gcry_cipher_hd_t c)
+{
+  u64 tmp[2];
+#if defined(__x86_64__) && defined(__WIN64__)
+  char win64tmp[3 * 16];
+
+  /* XMM6-XMM8 need to be restored after use. */
+  asm volatile ("movdqu %%xmm6, 0*16(%0)\n\t"
+                "movdqu %%xmm7, 1*16(%0)\n\t"
+                "movdqu %%xmm8, 2*16(%0)\n\t"
+                :
+                : "r" (win64tmp)
+                : "memory");
+#endif
+
+  /* Swap endianness of hsub. */
+  tmp[0] = buf_get_be64(c->u_mode.gcm.u_ghash_key.key + 8);
+  tmp[1] = buf_get_be64(c->u_mode.gcm.u_ghash_key.key + 0);
+  buf_cpy (c->u_mode.gcm.u_ghash_key.key, tmp, GCRY_GCM_BLOCK_LEN);
+
+#ifdef __x86_64__
+  asm volatile ("movdqu %[h_1], %%xmm0\n\t"
+                "movdqa %%xmm0, %%xmm1\n\t"
+                :
+                : [h_1] "m" (*tmp));
+
+  gfmul_pclmul (); /* H•H => H² */
+
+  asm volatile ("movdqu %%xmm1, 0*16(%[h_234])\n\t"
+                "movdqa %%xmm1, %%xmm8\n\t"
+                :
+                : [h_234] "r" (c->u_mode.gcm.gcm_table)
+                : "memory");
+
+  gfmul_pclmul (); /* H•H² => H³ */
+
+  asm volatile ("movdqa %%xmm8, %%xmm0\n\t"
+                "movdqu %%xmm1, 1*16(%[h_234])\n\t"
+                "movdqa %%xmm8, %%xmm1\n\t"
+                :
+                : [h_234] "r" (c->u_mode.gcm.gcm_table)
+                : "memory");
+
+  gfmul_pclmul (); /* H²•H² => H⁴ */
+
+  asm volatile ("movdqu %%xmm1, 2*16(%[h_234])\n\t"
+                :
+                : [h_234] "r" (c->u_mode.gcm.gcm_table)
+                : "memory");
+
+#ifdef __WIN64__
+  /* Clear/restore used registers. */
+  asm volatile( "pxor %%xmm0, %%xmm0\n\t"
+                "pxor %%xmm1, %%xmm1\n\t"
+                "pxor %%xmm2, %%xmm2\n\t"
+                "pxor %%xmm3, %%xmm3\n\t"
+                "pxor %%xmm4, %%xmm4\n\t"
+                "pxor %%xmm5, %%xmm5\n\t"
+                "movdqu 0*16(%0), %%xmm6\n\t"
+                "movdqu 1*16(%0), %%xmm7\n\t"
+                "movdqu 2*16(%0), %%xmm8\n\t"
+                :
+                : "r" (win64tmp)
+                : "memory");
+#else
+  /* Clear used registers. */
+  asm volatile( "pxor %%xmm0, %%xmm0\n\t"
+                "pxor %%xmm1, %%xmm1\n\t"
+                "pxor %%xmm2, %%xmm2\n\t"
+                "pxor %%xmm3, %%xmm3\n\t"
+                "pxor %%xmm4, %%xmm4\n\t"
+                "pxor %%xmm5, %%xmm5\n\t"
+                "pxor %%xmm6, %%xmm6\n\t"
+                "pxor %%xmm7, %%xmm7\n\t"
+                "pxor %%xmm8, %%xmm8\n\t"
+                ::: "cc" );
+#endif
+#endif
+
+  wipememory (tmp, sizeof(tmp));
+}
+
+
+unsigned int
+_gcry_ghash_intel_pclmul (gcry_cipher_hd_t c, byte *result, const byte *buf,
+                          size_t nblocks)
+{
+  static const unsigned char be_mask[16] __attribute__ ((aligned (16))) =
+    { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
+  const unsigned int blocksize = GCRY_GCM_BLOCK_LEN;
+#ifdef __WIN64__
+  char win64tmp[10 * 16];
+#endif
+
+  if (nblocks == 0)
+    return 0;
+
+#ifdef __WIN64__
+  /* XMM8-XMM15 need to be restored after use. */
+  asm volatile ("movdqu %%xmm6,  0*16(%0)\n\t"
+                "movdqu %%xmm7,  1*16(%0)\n\t"
+                "movdqu %%xmm8,  2*16(%0)\n\t"
+                "movdqu %%xmm9,  3*16(%0)\n\t"
+                "movdqu %%xmm10, 4*16(%0)\n\t"
+                "movdqu %%xmm11, 5*16(%0)\n\t"
+                "movdqu %%xmm12, 6*16(%0)\n\t"
+                "movdqu %%xmm13, 7*16(%0)\n\t"
+                "movdqu %%xmm14, 8*16(%0)\n\t"
+                "movdqu %%xmm15, 9*16(%0)\n\t"
+                :
+                : "r" (win64tmp)
+                : "memory" );
+#endif
+
+  /* Preload hash and H1. */
+  asm volatile ("movdqu %[hash], %%xmm1\n\t"
+                "movdqa %[hsub], %%xmm0\n\t"
+                "pshufb %[be_mask], %%xmm1\n\t" /* be => le */
+                :
+                : [hash] "m" (*result), [be_mask] "m" (*be_mask),
+                  [hsub] "m" (*c->u_mode.gcm.u_ghash_key.key));
+
+#ifdef __x86_64__
+  if (nblocks >= 4)
+    {
+      do
+        {
+          asm volatile ("movdqa %[be_mask], %%xmm4\n\t"
+                        "movdqu 0*16(%[buf]), %%xmm5\n\t"
+                        "movdqu 1*16(%[buf]), %%xmm2\n\t"
+                        "movdqu 2*16(%[buf]), %%xmm3\n\t"
+                        "movdqu 3*16(%[buf]), %%xmm6\n\t"
+                        "pshufb %%xmm4, %%xmm5\n\t" /* be => le */
+
+                        /* Load H2, H3, H4. */
+                        "movdqu 2*16(%[h_234]), %%xmm10\n\t"
+                        "movdqu 1*16(%[h_234]), %%xmm9\n\t"
+                        "movdqu 0*16(%[h_234]), %%xmm8\n\t"
+
+                        "pxor %%xmm5, %%xmm1\n\t"
+                        "pshufb %%xmm4, %%xmm2\n\t" /* be => le */
+                        "pshufb %%xmm4, %%xmm3\n\t" /* be => le */
+                        "pshufb %%xmm4, %%xmm6\n\t" /* be => le */
+                        :
+                        : [buf] "r" (buf), [be_mask] "m" (*be_mask),
+                          [h_234] "r" (c->u_mode.gcm.gcm_table));
+
+          gfmul_pclmul_aggr4 ();
+
+          buf += 4 * blocksize;
+          nblocks -= 4;
+        }
+      while (nblocks >= 4);
+
+#ifndef __WIN64__
+      /* Clear used x86-64/XMM registers. */
+      asm volatile( "pxor %%xmm8, %%xmm8\n\t"
+                    "pxor %%xmm9, %%xmm9\n\t"
+                    "pxor %%xmm10, %%xmm10\n\t"
+                    "pxor %%xmm11, %%xmm11\n\t"
+                    "pxor %%xmm12, %%xmm12\n\t"
+                    "pxor %%xmm13, %%xmm13\n\t"
+                    "pxor %%xmm14, %%xmm14\n\t"
+                    "pxor %%xmm15, %%xmm15\n\t"
+                    ::: "cc" );
+#endif
+    }
+#endif
+
+  while (nblocks--)
+    {
+      asm volatile ("movdqu %[buf], %%xmm2\n\t"
+                    "pshufb %[be_mask], %%xmm2\n\t" /* be => le */
+                    "pxor %%xmm2, %%xmm1\n\t"
+                    :
+                    : [buf] "m" (*buf), [be_mask] "m" (*be_mask));
+
+      gfmul_pclmul ();
+
+      buf += blocksize;
+    }
+
+  /* Store hash. */
+  asm volatile ("pshufb %[be_mask], %%xmm1\n\t" /* be => le */
+                "movdqu %%xmm1, %[hash]\n\t"
+                : [hash] "=m" (*result)
+                : [be_mask] "m" (*be_mask));
+
+#ifdef __WIN64__
+  /* Clear/restore used registers. */
+  asm volatile( "pxor %%xmm0, %%xmm0\n\t"
+                "pxor %%xmm1, %%xmm1\n\t"
+                "pxor %%xmm2, %%xmm2\n\t"
+                "pxor %%xmm3, %%xmm3\n\t"
+                "pxor %%xmm4, %%xmm4\n\t"
+                "pxor %%xmm5, %%xmm5\n\t"
+                "movdqu 0*16(%0), %%xmm6\n\t"
+                "movdqu 1*16(%0), %%xmm7\n\t"
+                "movdqu 2*16(%0), %%xmm8\n\t"
+                "movdqu 3*16(%0), %%xmm9\n\t"
+                "movdqu 4*16(%0), %%xmm10\n\t"
+                "movdqu 5*16(%0), %%xmm11\n\t"
+                "movdqu 6*16(%0), %%xmm12\n\t"
+                "movdqu 7*16(%0), %%xmm13\n\t"
+                "movdqu 8*16(%0), %%xmm14\n\t"
+                "movdqu 9*16(%0), %%xmm15\n\t"
+                :
+                : "r" (win64tmp)
+                : "memory" );
+#else
+  /* Clear used registers. */
+  asm volatile( "pxor %%xmm0, %%xmm0\n\t"
+                "pxor %%xmm1, %%xmm1\n\t"
+                "pxor %%xmm2, %%xmm2\n\t"
+                "pxor %%xmm3, %%xmm3\n\t"
+                "pxor %%xmm4, %%xmm4\n\t"
+                "pxor %%xmm5, %%xmm5\n\t"
+                "pxor %%xmm6, %%xmm6\n\t"
+                "pxor %%xmm7, %%xmm7\n\t"
+                ::: "cc" );
+#endif
+
+  return 0;
+}
+
+#endif /* GCM_USE_INTEL_PCLMUL */
index 457e337..6e0959a 100644 (file)
@@ -1,6 +1,6 @@
 /* cipher-gcm.c  - Generic Galois Counter Mode implementation
  * Copyright (C) 2013 Dmitry Eremin-Solenikov
- * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
 
 #include "g10lib.h"
 #include "cipher.h"
-#include "ath.h"
 #include "bufhelp.h"
 #include "./cipher-internal.h"
 
+
+#ifdef GCM_USE_INTEL_PCLMUL
+extern void _gcry_ghash_setup_intel_pclmul (gcry_cipher_hd_t c);
+
+extern unsigned int _gcry_ghash_intel_pclmul (gcry_cipher_hd_t c, byte *result,
+                                              const byte *buf, size_t nblocks);
+#endif
+
+
 #ifdef GCM_USE_TABLES
 static const u16 gcmR[256] = {
   0x0000, 0x01c2, 0x0384, 0x0246, 0x0708, 0x06ca, 0x048c, 0x054e,
@@ -163,7 +171,7 @@ do_ghash (unsigned char *result, const unsigned char *buf, const u64 *gcmM)
           sizeof(int)*2 + sizeof(void*)*5);
 }
 
-#else
+#else /*!GCM_TABLES_USE_U64*/
 
 static void
 bshift (u32 * M, int i)
@@ -276,9 +284,10 @@ do_ghash (unsigned char *result, const unsigned char *buf, const u32 *gcmM)
   return (sizeof(V) + sizeof(T) + sizeof(tmp) +
           sizeof(int)*2 + sizeof(void*)*6);
 }
-#endif /* !HAVE_U64_TYPEDEF || SIZEOF_UNSIGNED_LONG != 8 */
+#endif /*!GCM_TABLES_USE_U64*/
 
-#define fillM(c, h) do_fillM (h, c->u_mode.gcm.gcm_table)
+#define fillM(c) \
+  do_fillM (c->u_mode.gcm.u_ghash_key.key, c->u_mode.gcm.gcm_table)
 #define GHASH(c, result, buf) do_ghash (result, buf, c->u_mode.gcm.gcm_table)
 
 #else
@@ -343,331 +352,24 @@ do_ghash (unsigned char *hsub, unsigned char *result, const unsigned char *buf)
   return (sizeof(V) + sizeof(T) + sizeof(int)*2 + sizeof(void*)*5);
 }
 
-#define fillM(c, h) do { } while (0)
+#define fillM(c) do { } while (0)
 #define GHASH(c, result, buf) do_ghash (c->u_mode.gcm.u_ghash_key.key, result, buf)
 
 #endif /* !GCM_USE_TABLES */
 
 
-#ifdef GCM_USE_INTEL_PCLMUL
-/*
- Intel PCLMUL ghash based on white paper:
-  "Intel® Carry-Less Multiplication Instruction and its Usage for Computing the
-   GCM Mode - Rev 2.01"; Shay Gueron, Michael E. Kounavis.
- */
-static inline void gfmul_pclmul(void)
-{
-  /* Input: XMM0 and XMM1, Output: XMM1. Input XMM0 stays unmodified.
-     Input must be converted to little-endian.
-   */
-  asm volatile (/* gfmul, xmm0 has operator a and xmm1 has operator b. */
-                "pshufd $78, %%xmm0, %%xmm2\n\t"
-                "pshufd $78, %%xmm1, %%xmm4\n\t"
-                "pxor %%xmm0, %%xmm2\n\t" /* xmm2 holds a0+a1 */
-                "pxor %%xmm1, %%xmm4\n\t" /* xmm4 holds b0+b1 */
-
-                "movdqa %%xmm0, %%xmm3\n\t"
-                "pclmulqdq $0, %%xmm1, %%xmm3\n\t"  /* xmm3 holds a0*b0 */
-                "movdqa %%xmm0, %%xmm6\n\t"
-                "pclmulqdq $17, %%xmm1, %%xmm6\n\t" /* xmm6 holds a1*b1 */
-                "movdqa %%xmm3, %%xmm5\n\t"
-                "pclmulqdq $0, %%xmm2, %%xmm4\n\t"  /* xmm4 holds (a0+a1)*(b0+b1) */
-
-                "pxor %%xmm6, %%xmm5\n\t" /* xmm5 holds a0*b0+a1*b1 */
-                "pxor %%xmm5, %%xmm4\n\t" /* xmm4 holds a0*b0+a1*b1+(a0+a1)*(b0+b1) */
-                "movdqa %%xmm4, %%xmm5\n\t"
-                "psrldq $8, %%xmm4\n\t"
-                "pslldq $8, %%xmm5\n\t"
-                "pxor %%xmm5, %%xmm3\n\t"
-                "pxor %%xmm4, %%xmm6\n\t" /* <xmm6:xmm3> holds the result of the
-                                             carry-less multiplication of xmm0
-                                             by xmm1 */
-
-                /* shift the result by one bit position to the left cope for
-                   the fact that bits are reversed */
-                "movdqa %%xmm3, %%xmm4\n\t"
-                "movdqa %%xmm6, %%xmm5\n\t"
-                "pslld $1, %%xmm3\n\t"
-                "pslld $1, %%xmm6\n\t"
-                "psrld $31, %%xmm4\n\t"
-                "psrld $31, %%xmm5\n\t"
-                "movdqa %%xmm4, %%xmm1\n\t"
-                "pslldq $4, %%xmm5\n\t"
-                "pslldq $4, %%xmm4\n\t"
-                "psrldq $12, %%xmm1\n\t"
-                "por %%xmm4, %%xmm3\n\t"
-                "por %%xmm5, %%xmm6\n\t"
-                "por %%xmm6, %%xmm1\n\t"
-
-                /* first phase of the reduction */
-                "movdqa %%xmm3, %%xmm6\n\t"
-                "movdqa %%xmm3, %%xmm7\n\t"
-                "pslld $31, %%xmm6\n\t"  /* packed right shifting << 31 */
-                "movdqa %%xmm3, %%xmm5\n\t"
-                "pslld $30, %%xmm7\n\t"  /* packed right shifting shift << 30 */
-                "pslld $25, %%xmm5\n\t"  /* packed right shifting shift << 25 */
-                "pxor %%xmm7, %%xmm6\n\t" /* xor the shifted versions */
-                "pxor %%xmm5, %%xmm6\n\t"
-                "movdqa %%xmm6, %%xmm7\n\t"
-                "pslldq $12, %%xmm6\n\t"
-                "psrldq $4, %%xmm7\n\t"
-                "pxor %%xmm6, %%xmm3\n\t" /* first phase of the reduction
-                                             complete */
-
-                /* second phase of the reduction */
-                "movdqa %%xmm3, %%xmm2\n\t"
-                "movdqa %%xmm3, %%xmm4\n\t"
-                "psrld $1, %%xmm2\n\t"    /* packed left shifting >> 1 */
-                "movdqa %%xmm3, %%xmm5\n\t"
-                "psrld $2, %%xmm4\n\t"    /* packed left shifting >> 2 */
-                "psrld $7, %%xmm5\n\t"    /* packed left shifting >> 7 */
-                "pxor %%xmm4, %%xmm2\n\t" /* xor the shifted versions */
-                "pxor %%xmm5, %%xmm2\n\t"
-                "pxor %%xmm7, %%xmm2\n\t"
-                "pxor %%xmm2, %%xmm3\n\t"
-                "pxor %%xmm3, %%xmm1\n\t" /* the result is in xmm1 */
-                ::: "cc" );
-}
-
-#ifdef __x86_64__
-static inline void gfmul_pclmul_aggr4(void)
-{
-  /* Input:
-      H¹: XMM0                X_i            : XMM6
-      H²: XMM8                X_(i-1)        : XMM3
-      H³: XMM9                X_(i-2)        : XMM2
-      H⁴: XMM10              X_(i-3)⊕Y_(i-4): XMM1
-     Output:
-      Y_i: XMM1
-     Inputs XMM0 stays unmodified.
-     Input must be converted to little-endian.
-   */
-  asm volatile (/* perform clmul and merge results... */
-                "pshufd $78, %%xmm10, %%xmm11\n\t"
-                "pshufd $78, %%xmm1, %%xmm12\n\t"
-                "pxor %%xmm10, %%xmm11\n\t" /* xmm11 holds 4:a0+a1 */
-                "pxor %%xmm1, %%xmm12\n\t" /* xmm12 holds 4:b0+b1 */
-
-                "pshufd $78, %%xmm9, %%xmm13\n\t"
-                "pshufd $78, %%xmm2, %%xmm14\n\t"
-                "pxor %%xmm9, %%xmm13\n\t" /* xmm13 holds 3:a0+a1 */
-                "pxor %%xmm2, %%xmm14\n\t" /* xmm14 holds 3:b0+b1 */
-
-                "pshufd $78, %%xmm8, %%xmm5\n\t"
-                "pshufd $78, %%xmm3, %%xmm15\n\t"
-                "pxor %%xmm8, %%xmm5\n\t" /* xmm1 holds 2:a0+a1 */
-                "pxor %%xmm3, %%xmm15\n\t" /* xmm2 holds 2:b0+b1 */
-
-                "movdqa %%xmm10, %%xmm4\n\t"
-                "movdqa %%xmm9, %%xmm7\n\t"
-                "pclmulqdq $0, %%xmm1, %%xmm4\n\t"   /* xmm4 holds 4:a0*b0 */
-                "pclmulqdq $0, %%xmm2, %%xmm7\n\t"   /* xmm7 holds 3:a0*b0 */
-                "pclmulqdq $17, %%xmm10, %%xmm1\n\t" /* xmm1 holds 4:a1*b1 */
-                "pclmulqdq $17, %%xmm9, %%xmm2\n\t"  /* xmm9 holds 3:a1*b1 */
-                "pclmulqdq $0, %%xmm11, %%xmm12\n\t" /* xmm12 holds 4:(a0+a1)*(b0+b1) */
-                "pclmulqdq $0, %%xmm13, %%xmm14\n\t" /* xmm14 holds 3:(a0+a1)*(b0+b1) */
-
-                "pshufd $78, %%xmm0, %%xmm10\n\t"
-                "pshufd $78, %%xmm6, %%xmm11\n\t"
-                "pxor %%xmm0, %%xmm10\n\t" /* xmm10 holds 1:a0+a1 */
-                "pxor %%xmm6, %%xmm11\n\t" /* xmm11 holds 1:b0+b1 */
-
-                "pxor %%xmm4, %%xmm7\n\t"   /* xmm7 holds 3+4:a0*b0 */
-                "pxor %%xmm2, %%xmm1\n\t"   /* xmm1 holds 3+4:a1*b1 */
-                "pxor %%xmm14, %%xmm12\n\t" /* xmm12 holds 3+4:(a0+a1)*(b0+b1) */
-
-                "movdqa %%xmm8, %%xmm13\n\t"
-                "pclmulqdq $0, %%xmm3, %%xmm13\n\t"  /* xmm13 holds 2:a0*b0 */
-                "pclmulqdq $17, %%xmm8, %%xmm3\n\t"  /* xmm3 holds 2:a1*b1 */
-                "pclmulqdq $0, %%xmm5, %%xmm15\n\t" /* xmm15 holds 2:(a0+a1)*(b0+b1) */
-
-                "pxor %%xmm13, %%xmm7\n\t" /* xmm7 holds 2+3+4:a0*b0 */
-                "pxor %%xmm3, %%xmm1\n\t"  /* xmm1 holds 2+3+4:a1*b1 */
-                "pxor %%xmm15, %%xmm12\n\t" /* xmm12 holds 2+3+4:(a0+a1)*(b0+b1) */
-
-                "movdqa %%xmm0, %%xmm3\n\t"
-                "pclmulqdq $0, %%xmm6, %%xmm3\n\t"  /* xmm3 holds 1:a0*b0 */
-                "pclmulqdq $17, %%xmm0, %%xmm6\n\t" /* xmm6 holds 1:a1*b1 */
-                "movdqa %%xmm11, %%xmm4\n\t"
-                "pclmulqdq $0, %%xmm10, %%xmm4\n\t" /* xmm4 holds 1:(a0+a1)*(b0+b1) */
-
-                "pxor %%xmm7, %%xmm3\n\t"  /* xmm3 holds 1+2+3+4:a0*b0 */
-                "pxor %%xmm1, %%xmm6\n\t"  /* xmm6 holds 1+2+3+4:a1*b1 */
-                "pxor %%xmm12, %%xmm4\n\t" /* xmm4 holds 1+2+3+4:(a0+a1)*(b0+b1) */
-
-                /* aggregated reduction... */
-                "movdqa %%xmm3, %%xmm5\n\t"
-                "pxor %%xmm6, %%xmm5\n\t" /* xmm5 holds a0*b0+a1*b1 */
-                "pxor %%xmm5, %%xmm4\n\t" /* xmm4 holds a0*b0+a1*b1+(a0+a1)*(b0+b1) */
-                "movdqa %%xmm4, %%xmm5\n\t"
-                "psrldq $8, %%xmm4\n\t"
-                "pslldq $8, %%xmm5\n\t"
-                "pxor %%xmm5, %%xmm3\n\t"
-                "pxor %%xmm4, %%xmm6\n\t" /* <xmm6:xmm3> holds the result of the
-                                             carry-less multiplication of xmm0
-                                             by xmm1 */
-
-                /* shift the result by one bit position to the left cope for
-                   the fact that bits are reversed */
-                "movdqa %%xmm3, %%xmm4\n\t"
-                "movdqa %%xmm6, %%xmm5\n\t"
-                "pslld $1, %%xmm3\n\t"
-                "pslld $1, %%xmm6\n\t"
-                "psrld $31, %%xmm4\n\t"
-                "psrld $31, %%xmm5\n\t"
-                "movdqa %%xmm4, %%xmm1\n\t"
-                "pslldq $4, %%xmm5\n\t"
-                "pslldq $4, %%xmm4\n\t"
-                "psrldq $12, %%xmm1\n\t"
-                "por %%xmm4, %%xmm3\n\t"
-                "por %%xmm5, %%xmm6\n\t"
-                "por %%xmm6, %%xmm1\n\t"
-
-                /* first phase of the reduction */
-                "movdqa %%xmm3, %%xmm6\n\t"
-                "movdqa %%xmm3, %%xmm7\n\t"
-                "pslld $31, %%xmm6\n\t"  /* packed right shifting << 31 */
-                "movdqa %%xmm3, %%xmm5\n\t"
-                "pslld $30, %%xmm7\n\t"  /* packed right shifting shift << 30 */
-                "pslld $25, %%xmm5\n\t"  /* packed right shifting shift << 25 */
-                "pxor %%xmm7, %%xmm6\n\t" /* xor the shifted versions */
-                "pxor %%xmm5, %%xmm6\n\t"
-                "movdqa %%xmm6, %%xmm7\n\t"
-                "pslldq $12, %%xmm6\n\t"
-                "psrldq $4, %%xmm7\n\t"
-                "pxor %%xmm6, %%xmm3\n\t" /* first phase of the reduction
-                                             complete */
-
-                /* second phase of the reduction */
-                "movdqa %%xmm3, %%xmm2\n\t"
-                "movdqa %%xmm3, %%xmm4\n\t"
-                "psrld $1, %%xmm2\n\t"    /* packed left shifting >> 1 */
-                "movdqa %%xmm3, %%xmm5\n\t"
-                "psrld $2, %%xmm4\n\t"    /* packed left shifting >> 2 */
-                "psrld $7, %%xmm5\n\t"    /* packed left shifting >> 7 */
-                "pxor %%xmm4, %%xmm2\n\t" /* xor the shifted versions */
-                "pxor %%xmm5, %%xmm2\n\t"
-                "pxor %%xmm7, %%xmm2\n\t"
-                "pxor %%xmm2, %%xmm3\n\t"
-                "pxor %%xmm3, %%xmm1\n\t" /* the result is in xmm1 */
-                :::"cc");
-}
-#endif
-
-#endif /*GCM_USE_INTEL_PCLMUL*/
-
-
 static unsigned int
-ghash (gcry_cipher_hd_t c, byte *result, const byte *buf,
-       size_t nblocks)
+ghash_internal (gcry_cipher_hd_t c, byte *result, const byte *buf,
+                size_t nblocks)
 {
   const unsigned int blocksize = GCRY_GCM_BLOCK_LEN;
-  unsigned int burn;
-
-  if (nblocks == 0)
-    return 0;
-
-  if (0)
-    ;
-#ifdef GCM_USE_INTEL_PCLMUL
-  else if (c->u_mode.gcm.use_intel_pclmul)
-    {
-      static const unsigned char be_mask[16] __attribute__ ((aligned (16))) =
-        { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
-
-      /* Preload hash and H1. */
-      asm volatile ("movdqu %[hash], %%xmm1\n\t"
-                    "movdqa %[hsub], %%xmm0\n\t"
-                    "pshufb %[be_mask], %%xmm1\n\t" /* be => le */
-                    :
-                    : [hash] "m" (*result), [be_mask] "m" (*be_mask),
-                      [hsub] "m" (*c->u_mode.gcm.u_ghash_key.key));
-
-#ifdef __x86_64__
-      if (nblocks >= 4)
-        {
-          do
-            {
-              asm volatile ("movdqa %[be_mask], %%xmm4\n\t"
-                            "movdqu 0*16(%[buf]), %%xmm5\n\t"
-                            "movdqu 1*16(%[buf]), %%xmm2\n\t"
-                            "movdqu 2*16(%[buf]), %%xmm3\n\t"
-                            "movdqu 3*16(%[buf]), %%xmm6\n\t"
-                            "pshufb %%xmm4, %%xmm5\n\t" /* be => le */
-
-                            /* Load H2, H3, H4. */
-                            "movdqu 2*16(%[h_234]), %%xmm10\n\t"
-                            "movdqu 1*16(%[h_234]), %%xmm9\n\t"
-                            "movdqu 0*16(%[h_234]), %%xmm8\n\t"
-
-                            "pxor %%xmm5, %%xmm1\n\t"
-                            "pshufb %%xmm4, %%xmm2\n\t" /* be => le */
-                            "pshufb %%xmm4, %%xmm3\n\t" /* be => le */
-                            "pshufb %%xmm4, %%xmm6\n\t" /* be => le */
-                            :
-                            : [buf] "r" (buf), [be_mask] "m" (*be_mask),
-                              [h_234] "r" (c->u_mode.gcm.gcm_table));
-
-              gfmul_pclmul_aggr4 ();
-
-              buf += 4 * blocksize;
-              nblocks -= 4;
-            }
-          while (nblocks >= 4);
-
-          /* Clear used x86-64/XMM registers. */
-          asm volatile( "pxor %%xmm8, %%xmm8\n\t"
-                        "pxor %%xmm9, %%xmm9\n\t"
-                        "pxor %%xmm10, %%xmm10\n\t"
-                        "pxor %%xmm11, %%xmm11\n\t"
-                        "pxor %%xmm12, %%xmm12\n\t"
-                        "pxor %%xmm13, %%xmm13\n\t"
-                        "pxor %%xmm14, %%xmm14\n\t"
-                        "pxor %%xmm15, %%xmm15\n\t"
-                        ::: "cc" );
-        }
-#endif
-
-      while (nblocks--)
-        {
-          asm volatile ("movdqu %[buf], %%xmm2\n\t"
-                        "pshufb %[be_mask], %%xmm2\n\t" /* be => le */
-                        "pxor %%xmm2, %%xmm1\n\t"
-                        :
-                        : [buf] "m" (*buf), [be_mask] "m" (*be_mask));
-
-          gfmul_pclmul ();
-
-          buf += blocksize;
-        }
+  unsigned int burn = 0;
 
-      /* Store hash. */
-      asm volatile ("pshufb %[be_mask], %%xmm1\n\t" /* be => le */
-                    "movdqu %%xmm1, %[hash]\n\t"
-                    : [hash] "=m" (*result)
-                    : [be_mask] "m" (*be_mask));
-
-      /* Clear used registers. */
-      asm volatile( "pxor %%xmm0, %%xmm0\n\t"
-                    "pxor %%xmm1, %%xmm1\n\t"
-                    "pxor %%xmm2, %%xmm2\n\t"
-                    "pxor %%xmm3, %%xmm3\n\t"
-                    "pxor %%xmm4, %%xmm4\n\t"
-                    "pxor %%xmm5, %%xmm5\n\t"
-                    "pxor %%xmm6, %%xmm6\n\t"
-                    "pxor %%xmm7, %%xmm7\n\t"
-                    ::: "cc" );
-      burn = 0;
-    }
-#endif
-  else
+  while (nblocks)
     {
-      while (nblocks)
-        {
-          burn = GHASH (c, result, buf);
-          buf += blocksize;
-          nblocks--;
-        }
+      burn = GHASH (c, result, buf);
+      buf += blocksize;
+      nblocks--;
     }
 
   return burn + (burn ? 5*sizeof(void*) : 0);
@@ -675,70 +377,22 @@ ghash (gcry_cipher_hd_t c, byte *result, const byte *buf,
 
 
 static void
-setupM (gcry_cipher_hd_t c, byte *h)
+setupM (gcry_cipher_hd_t c)
 {
   if (0)
     ;
 #ifdef GCM_USE_INTEL_PCLMUL
   else if (_gcry_get_hw_features () & HWF_INTEL_PCLMUL)
     {
-      u64 tmp[2];
-
-      c->u_mode.gcm.use_intel_pclmul = 1;
-
-      /* Swap endianness of hsub. */
-      tmp[0] = buf_get_be64(c->u_mode.gcm.u_ghash_key.key + 8);
-      tmp[1] = buf_get_be64(c->u_mode.gcm.u_ghash_key.key + 0);
-      buf_cpy (c->u_mode.gcm.u_ghash_key.key, tmp, GCRY_GCM_BLOCK_LEN);
-
-#ifdef __x86_64__
-      asm volatile ("movdqu %[h_1], %%xmm0\n\t"
-                    "movdqa %%xmm0, %%xmm1\n\t"
-                    :
-                    : [h_1] "m" (*tmp));
-
-      gfmul_pclmul (); /* H•H => H² */
-
-      asm volatile ("movdqu %%xmm1, 0*16(%[h_234])\n\t"
-                    "movdqa %%xmm1, %%xmm8\n\t"
-                    :
-                    : [h_234] "r" (c->u_mode.gcm.gcm_table)
-                    : "memory");
-
-      gfmul_pclmul (); /* H•H² => H³ */
-
-      asm volatile ("movdqa %%xmm8, %%xmm0\n\t"
-                    "movdqu %%xmm1, 1*16(%[h_234])\n\t"
-                    "movdqa %%xmm8, %%xmm1\n\t"
-                    :
-                    : [h_234] "r" (c->u_mode.gcm.gcm_table)
-                    : "memory");
-
-      gfmul_pclmul (); /* H²•H² => H⁴ */
-
-      asm volatile ("movdqu %%xmm1, 2*16(%[h_234])\n\t"
-                    :
-                    : [h_234] "r" (c->u_mode.gcm.gcm_table)
-                    : "memory");
-
-      /* Clear used registers. */
-      asm volatile( "pxor %%xmm0, %%xmm0\n\t"
-                    "pxor %%xmm1, %%xmm1\n\t"
-                    "pxor %%xmm2, %%xmm2\n\t"
-                    "pxor %%xmm3, %%xmm3\n\t"
-                    "pxor %%xmm4, %%xmm4\n\t"
-                    "pxor %%xmm5, %%xmm5\n\t"
-                    "pxor %%xmm6, %%xmm6\n\t"
-                    "pxor %%xmm7, %%xmm7\n\t"
-                    "pxor %%xmm8, %%xmm8\n\t"
-                    ::: "cc" );
-#endif
-
-      wipememory (tmp, sizeof(tmp));
+      c->u_mode.gcm.ghash_fn = _gcry_ghash_intel_pclmul;
+      _gcry_ghash_setup_intel_pclmul (c);
     }
 #endif
   else
-    fillM (c, h);
+    {
+      c->u_mode.gcm.ghash_fn = ghash_internal;
+      fillM (c);
+    }
 }
 
 
@@ -811,6 +465,7 @@ do_ghash_buf(gcry_cipher_hd_t c, byte *hash, const byte *buf,
 {
   unsigned int blocksize = GCRY_GCM_BLOCK_LEN;
   unsigned int unused = c->u_mode.gcm.mac_unused;
+  ghash_fn_t ghash_fn = c->u_mode.gcm.ghash_fn;
   size_t nblocks, n;
   unsigned int burn = 0;
 
@@ -819,7 +474,7 @@ do_ghash_buf(gcry_cipher_hd_t c, byte *hash, const byte *buf,
 
   do
     {
-      if (buflen + unused < blocksize || unused > 0)
+      if (buflen > 0 && (buflen + unused < blocksize || unused > 0))
         {
           n = blocksize - unused;
           n = n < buflen ? n : buflen;
@@ -844,7 +499,7 @@ do_ghash_buf(gcry_cipher_hd_t c, byte *hash, const byte *buf,
           gcry_assert (unused == blocksize);
 
           /* Process one block from macbuf.  */
-          burn = ghash (c, hash, c->u_mode.gcm.macbuf, 1);
+          burn = ghash_fn (c, hash, c->u_mode.gcm.macbuf, 1);
           unused = 0;
         }
 
@@ -852,7 +507,7 @@ do_ghash_buf(gcry_cipher_hd_t c, byte *hash, const byte *buf,
 
       if (nblocks)
         {
-          burn = ghash (c, hash, buf, nblocks);
+          burn = ghash_fn (c, hash, buf, nblocks);
           buf += blocksize * nblocks;
           buflen -= blocksize * nblocks;
         }
@@ -880,7 +535,9 @@ _gcry_cipher_gcm_encrypt (gcry_cipher_hd_t c,
     return GPG_ERR_BUFFER_TOO_SHORT;
   if (c->u_mode.gcm.datalen_over_limits)
     return GPG_ERR_INV_LENGTH;
-  if (c->marks.tag || c->u_mode.gcm.ghash_data_finalized)
+  if (c->marks.tag
+      || c->u_mode.gcm.ghash_data_finalized
+      || !c->u_mode.gcm.ghash_fn)
     return GPG_ERR_INV_STATE;
 
   if (!c->marks.iv)
@@ -926,7 +583,9 @@ _gcry_cipher_gcm_decrypt (gcry_cipher_hd_t c,
     return GPG_ERR_BUFFER_TOO_SHORT;
   if (c->u_mode.gcm.datalen_over_limits)
     return GPG_ERR_INV_LENGTH;
-  if (c->marks.tag || c->u_mode.gcm.ghash_data_finalized)
+  if (c->marks.tag
+      || c->u_mode.gcm.ghash_data_finalized
+      || !c->u_mode.gcm.ghash_fn)
     return GPG_ERR_INV_STATE;
 
   if (!c->marks.iv)
@@ -962,8 +621,10 @@ _gcry_cipher_gcm_authenticate (gcry_cipher_hd_t c,
     return GPG_ERR_CIPHER_ALGO;
   if (c->u_mode.gcm.datalen_over_limits)
     return GPG_ERR_INV_LENGTH;
-  if (c->marks.tag || c->u_mode.gcm.ghash_aad_finalized ||
-      c->u_mode.gcm.ghash_data_finalized)
+  if (c->marks.tag
+      || c->u_mode.gcm.ghash_aad_finalized
+      || c->u_mode.gcm.ghash_data_finalized
+      || !c->u_mode.gcm.ghash_fn)
     return GPG_ERR_INV_STATE;
 
   if (!c->marks.iv)
@@ -989,7 +650,7 @@ _gcry_cipher_gcm_setkey (gcry_cipher_hd_t c)
 
   c->spec->encrypt (&c->context.c, c->u_mode.gcm.u_ghash_key.key,
                     c->u_mode.gcm.u_ghash_key.key);
-  setupM (c, c->u_mode.gcm.u_ghash_key.key);
+  setupM (c);
 }
 
 
@@ -1011,6 +672,9 @@ _gcry_cipher_gcm_initiv (gcry_cipher_hd_t c, const byte *iv, size_t ivlen)
       u32 iv_bytes[2] = {0, 0};
       u32 bitlengths[2][2];
 
+      if (!c->u_mode.gcm.ghash_fn)
+        return GPG_ERR_INV_STATE;
+
       memset(c->u_ctr.ctr, 0, GCRY_GCM_BLOCK_LEN);
 
       gcm_bytecounter_add(iv_bytes, ivlen);
@@ -1105,12 +769,32 @@ _gcry_cipher_gcm_geniv (gcry_cipher_hd_t c,
 #endif
 
 
+static int
+is_tag_length_valid(size_t taglen)
+{
+  switch (taglen)
+    {
+    /* Allowed tag lengths from NIST SP 800-38D.  */
+    case 128 / 8: /* GCRY_GCM_BLOCK_LEN */
+    case 120 / 8:
+    case 112 / 8:
+    case 104 / 8:
+    case 96 / 8:
+    case 64 / 8:
+    case 32 / 8:
+      return 1;
+
+    default:
+      return 0;
+    }
+}
+
 static gcry_err_code_t
 _gcry_cipher_gcm_tag (gcry_cipher_hd_t c,
                       byte * outbuf, size_t outbuflen, int check)
 {
-  if (outbuflen < GCRY_GCM_BLOCK_LEN)
-    return GPG_ERR_BUFFER_TOO_SHORT;
+  if (!(is_tag_length_valid (outbuflen) || outbuflen >= GCRY_GCM_BLOCK_LEN))
+    return GPG_ERR_INV_LENGTH;
   if (c->u_mode.gcm.datalen_over_limits)
     return GPG_ERR_INV_LENGTH;
 
@@ -1118,6 +802,9 @@ _gcry_cipher_gcm_tag (gcry_cipher_hd_t c,
     {
       u32 bitlengths[2][2];
 
+      if (!c->u_mode.gcm.ghash_fn)
+        return GPG_ERR_INV_STATE;
+
       /* aad length */
       bitlengths[0][1] = be_bswap32(c->u_mode.gcm.aadlen[0] << 3);
       bitlengths[0][0] = be_bswap32((c->u_mode.gcm.aadlen[0] >> 29) |
@@ -1148,13 +835,20 @@ _gcry_cipher_gcm_tag (gcry_cipher_hd_t c,
 
   if (!check)
     {
+      if (outbuflen > GCRY_GCM_BLOCK_LEN)
+        outbuflen = GCRY_GCM_BLOCK_LEN;
+
+      /* NB: We already checked that OUTBUF is large enough to hold
+       * the result or has valid truncated length.  */
       memcpy (outbuf, c->u_mode.gcm.u_tag.tag, outbuflen);
-      return GPG_ERR_NO_ERROR;
     }
   else
     {
-      return buf_eq_const(outbuf, c->u_mode.gcm.u_tag.tag, outbuflen) ?
-               GPG_ERR_NO_ERROR : GPG_ERR_CHECKSUM;
+      /* OUTBUFLEN gives the length of the user supplied tag in OUTBUF
+       * and thus we need to compare its length first.  */
+      if (!is_tag_length_valid (outbuflen)
+          || !buf_eq_const (outbuf, c->u_mode.gcm.u_tag.tag, outbuflen))
+        return GPG_ERR_CHECKSUM;
     }
 
   return 0;
index cdac445..9fd1d91 100644 (file)
 #ifndef G10_CIPHER_INTERNAL_H
 #define G10_CIPHER_INTERNAL_H
 
+#include "./poly1305-internal.h"
+
+
 /* The maximum supported size of a block in bytes.  */
 #define MAX_BLOCKSIZE 16
 
+/* The length for an OCB block.  Although OCB supports any block
+   length it does not make sense to use a 64 bit blocklen (and cipher)
+   because this reduces the security margin to an unacceptable state.
+   Thus we require a cipher with 128 bit blocklength.  */
+#define OCB_BLOCK_LEN  (128/8)
+
+/* The size of the pre-computed L table for OCB.  This takes the same
+   size as the table used for GCM and thus we don't save anything by
+   not using such a table.  */
+#define OCB_L_TABLE_SIZE 16
+
+
+/* Check the above constants.  */
+#if OCB_BLOCK_LEN > MAX_BLOCKSIZE
+# error OCB_BLOCKLEN > MAX_BLOCKSIZE
+#endif
+
+
+
 /* Magic values for the context structure.  */
 #define CTX_MAGIC_NORMAL 0x24091964
 #define CTX_MAGIC_SECURE 0x46919042
@@ -39,7 +61,7 @@
 #define GCM_USE_TABLES 1
 
 
-/* GCM_USE_INTEL_PCLMUL inidicates whether to compile GCM with Intel PCLMUL
+/* GCM_USE_INTEL_PCLMUL indicates whether to compile GCM with Intel PCLMUL
    code.  */
 #undef GCM_USE_INTEL_PCLMUL
 #if defined(ENABLE_PCLMUL_SUPPORT) && defined(GCM_USE_TABLES)
 #endif /* GCM_USE_INTEL_PCLMUL */
 
 
+typedef unsigned int (*ghash_fn_t) (gcry_cipher_hd_t c, byte *result,
+                                    const byte *buf, size_t nblocks);
+
+
 /* A VIA processor with the Padlock engine as well as the Intel AES_NI
    instructions require an alignment of most data on a 16 byte
    boundary.  Because we trick out the compiler while allocating the
@@ -102,6 +128,10 @@ struct gcry_cipher_handle
     void (*ctr_enc)(void *context, unsigned char *iv,
                     void *outbuf_arg, const void *inbuf_arg,
                     size_t nblocks);
+    size_t (*ocb_crypt)(gcry_cipher_hd_t c, void *outbuf_arg,
+                       const void *inbuf_arg, size_t nblocks, int encrypt);
+    size_t (*ocb_auth)(gcry_cipher_hd_t c, const void *abuf_arg,
+                      size_t nblocks);
   } bulk;
 
 
@@ -112,19 +142,22 @@ struct gcry_cipher_handle
     unsigned int key:1; /* Set to 1 if a key has been set.  */
     unsigned int iv:1;  /* Set to 1 if a IV has been set.  */
     unsigned int tag:1; /* Set to 1 if a tag is finalized. */
+    unsigned int finalize:1; /* Next encrypt/decrypt has the final data.  */
   } marks;
 
   /* The initialization vector.  For best performance we make sure
      that it is properly aligned.  In particular some implementations
      of bulk operations expect an 16 byte aligned IV.  IV is also used
-     to store CBC-MAC in CCM mode; counter IV is stored in U_CTR.  */
+     to store CBC-MAC in CCM mode; counter IV is stored in U_CTR.  For
+     OCB mode it is used for the offset value.  */
   union {
     cipher_context_alignment_t iv_align;
     unsigned char iv[MAX_BLOCKSIZE];
   } u_iv;
 
   /* The counter for CTR mode.  This field is also used by AESWRAP and
-     thus we can't use the U_IV union.  */
+     thus we can't use the U_IV union.  For OCB mode it is used for
+     the checksum.  */
   union {
     cipher_context_alignment_t iv_align;
     unsigned char ctr[MAX_BLOCKSIZE];
@@ -135,7 +168,6 @@ struct gcry_cipher_handle
   int unused;  /* Number of unused bytes in LASTIV. */
 
   union {
-#ifdef HAVE_U64_TYPEDEF
     /* Mode specific storage for CCM mode. */
     struct {
       u64 encryptlen;
@@ -152,7 +184,20 @@ struct gcry_cipher_handle
       unsigned int lengths:1; /* Set to 1 if CCM length parameters has been
                                  processed.  */
     } ccm;
-#endif
+
+    /* Mode specific storage for Poly1305 mode. */
+    struct {
+      /* byte counter for AAD. */
+      u32 aadcount[2];
+
+      /* byte counter for data. */
+      u32 datacount[2];
+
+      unsigned int aad_finalized:1;
+      unsigned int bytecount_over_limits:1;
+
+      poly1305_context_t ctx;
+    } poly1305;
 
     /* Mode specific storage for CMAC mode. */
     struct {
@@ -174,6 +219,7 @@ struct gcry_cipher_handle
       unsigned char macbuf[GCRY_CCM_BLOCK_LEN];
       int mac_unused;  /* Number of unprocessed bytes in MACBUF. */
 
+
       /* byte counters for GCM */
       u32 aadlen[2];
       u32 datalen[2];
@@ -195,15 +241,12 @@ struct gcry_cipher_handle
         unsigned char key[MAX_BLOCKSIZE];
       } u_ghash_key;
 
-#ifdef GCM_USE_INTEL_PCLMUL
-      /* Use Intel PCLMUL instructions for accelerated GHASH. */
-      unsigned int use_intel_pclmul:1;
-#endif
+      /* GHASH implementation in use. */
+      ghash_fn_t ghash_fn;
 
       /* Pre-calculated table for GCM. */
 #ifdef GCM_USE_TABLES
- #if defined(HAVE_U64_TYPEDEF) && (SIZEOF_UNSIGNED_LONG == 8 \
-                                   || defined(__x86_64__))
+ #if (SIZEOF_UNSIGNED_LONG == 8 || defined(__x86_64__))
       #define GCM_TABLES_USE_U64 1
       u64 gcm_table[2 * 16];
  #else
@@ -212,6 +255,46 @@ struct gcry_cipher_handle
  #endif
 #endif
     } gcm;
+
+    /* Mode specific storage for OCB mode. */
+    struct {
+      /* Helper variables and pre-computed table of L values.  */
+      unsigned char L_star[OCB_BLOCK_LEN];
+      unsigned char L_dollar[OCB_BLOCK_LEN];
+      unsigned char L[OCB_BLOCK_LEN][OCB_L_TABLE_SIZE];
+
+      /* The tag is valid if marks.tag has been set.  */
+      unsigned char tag[OCB_BLOCK_LEN];
+
+      /* A buffer to hold the offset for the AAD processing.  */
+      unsigned char aad_offset[OCB_BLOCK_LEN];
+
+      /* A buffer to hold the current sum of AAD processing.  We can't
+         use tag here because tag may already hold the preprocessed
+         checksum of the data.  */
+      unsigned char aad_sum[OCB_BLOCK_LEN];
+
+      /* A buffer to store AAD data not yet processed.  */
+      unsigned char aad_leftover[OCB_BLOCK_LEN];
+
+      /* Number of data/aad blocks processed so far.  */
+      u64 data_nblocks;
+      u64 aad_nblocks;
+
+      /* Number of valid bytes in AAD_LEFTOVER.  */
+      unsigned char aad_nleftover;
+
+      /* Length of the tag.  Fixed for now but may eventually be
+         specified using a set of gcry_cipher_flags.  */
+      unsigned char taglen;
+
+      /* Flags indicating that the final data/aad block has been
+         processed.  */
+      unsigned int data_finalized:1;
+      unsigned int aad_finalized:1;
+
+    } ocb;
+
   } u_mode;
 
   /* What follows are two contexts of the cipher in use.  The first
@@ -282,10 +365,8 @@ gcry_err_code_t _gcry_cipher_ccm_set_nonce
                  size_t noncelen);
 gcry_err_code_t _gcry_cipher_ccm_authenticate
 /*           */ (gcry_cipher_hd_t c, const unsigned char *abuf, size_t abuflen);
-#ifdef HAVE_U64_TYPEDEF
 gcry_err_code_t _gcry_cipher_ccm_set_lengths
 /*           */ (gcry_cipher_hd_t c, u64 encryptedlen, u64 aadlen, u64 taglen);
-#endif
 gcry_err_code_t _gcry_cipher_ccm_get_tag
 /*           */ (gcry_cipher_hd_t c,
                  unsigned char *outtag, size_t taglen);
@@ -319,4 +400,73 @@ void _gcry_cipher_gcm_setkey
 /*           */   (gcry_cipher_hd_t c);
 
 
+/*-- cipher-poly1305.c --*/
+gcry_err_code_t _gcry_cipher_poly1305_encrypt
+/*           */   (gcry_cipher_hd_t c,
+                   unsigned char *outbuf, size_t outbuflen,
+                   const unsigned char *inbuf, size_t inbuflen);
+gcry_err_code_t _gcry_cipher_poly1305_decrypt
+/*           */   (gcry_cipher_hd_t c,
+                   unsigned char *outbuf, size_t outbuflen,
+                   const unsigned char *inbuf, size_t inbuflen);
+gcry_err_code_t _gcry_cipher_poly1305_setiv
+/*           */   (gcry_cipher_hd_t c,
+                   const unsigned char *iv, size_t ivlen);
+gcry_err_code_t _gcry_cipher_poly1305_authenticate
+/*           */   (gcry_cipher_hd_t c,
+                   const unsigned char *aadbuf, size_t aadbuflen);
+gcry_err_code_t _gcry_cipher_poly1305_get_tag
+/*           */   (gcry_cipher_hd_t c,
+                   unsigned char *outtag, size_t taglen);
+gcry_err_code_t _gcry_cipher_poly1305_check_tag
+/*           */   (gcry_cipher_hd_t c,
+                   const unsigned char *intag, size_t taglen);
+void _gcry_cipher_poly1305_setkey
+/*           */   (gcry_cipher_hd_t c);
+
+
+/*-- cipher-ocb.c --*/
+gcry_err_code_t _gcry_cipher_ocb_encrypt
+/*           */ (gcry_cipher_hd_t c,
+                 unsigned char *outbuf, size_t outbuflen,
+                 const unsigned char *inbuf, size_t inbuflen);
+gcry_err_code_t _gcry_cipher_ocb_decrypt
+/*           */ (gcry_cipher_hd_t c,
+                 unsigned char *outbuf, size_t outbuflen,
+                 const unsigned char *inbuf, size_t inbuflen);
+gcry_err_code_t _gcry_cipher_ocb_set_nonce
+/*           */ (gcry_cipher_hd_t c, const unsigned char *nonce,
+                 size_t noncelen);
+gcry_err_code_t _gcry_cipher_ocb_authenticate
+/*           */ (gcry_cipher_hd_t c, const unsigned char *abuf, size_t abuflen);
+gcry_err_code_t _gcry_cipher_ocb_get_tag
+/*           */ (gcry_cipher_hd_t c,
+                 unsigned char *outtag, size_t taglen);
+gcry_err_code_t _gcry_cipher_ocb_check_tag
+/*           */ (gcry_cipher_hd_t c,
+                 const unsigned char *intag, size_t taglen);
+const unsigned char *_gcry_cipher_ocb_get_l
+/*           */ (gcry_cipher_hd_t c, unsigned char *l_tmp, u64 n);
+
+
+/* Inline version of _gcry_cipher_ocb_get_l, with hard-coded fast paths for
+   most common cases.  */
+static inline const unsigned char *
+ocb_get_l (gcry_cipher_hd_t c, unsigned char *l_tmp, u64 n)
+{
+  if (n & 1)
+    return c->u_mode.ocb.L[0];
+  else if (n & 2)
+    return c->u_mode.ocb.L[1];
+  else
+    {
+      unsigned int ntz = _gcry_ctz64 (n);
+
+      if (ntz < OCB_L_TABLE_SIZE)
+       return c->u_mode.ocb.L[ntz];
+      else
+       return _gcry_cipher_ocb_get_l (c, l_tmp, n);
+    }
+}
+
 #endif /*G10_CIPHER_INTERNAL_H*/
diff --git a/cipher/cipher-ocb.c b/cipher/cipher-ocb.c
new file mode 100644 (file)
index 0000000..92260d2
--- /dev/null
@@ -0,0 +1,608 @@
+/* cipher-ocb.c -  OCB cipher mode
+ * Copyright (C) 2015, 2016 g10 Code GmbH
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * OCB is covered by several patents but may be used freely by most
+ * software.  See http://web.cs.ucdavis.edu/~rogaway/ocb/license.htm .
+ * In particular license 1 is suitable for Libgcrypt: See
+ * http://web.cs.ucdavis.edu/~rogaway/ocb/license1.pdf for the full
+ * license document; it basically says:
+ *
+ *   License 1 — License for Open-Source Software Implementations of OCB
+ *               (Jan 9, 2013)
+ *
+ *   Under this license, you are authorized to make, use, and
+ *   distribute open-source software implementations of OCB. This
+ *   license terminates for you if you sue someone over their
+ *   open-source software implementation of OCB claiming that you have
+ *   a patent covering their implementation.
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "bufhelp.h"
+#include "./cipher-internal.h"
+
+
+/* Double the OCB_BLOCK_LEN sized block B in-place.  */
+static inline void
+double_block (unsigned char *b)
+{
+#if OCB_BLOCK_LEN != 16
+  unsigned char b_0 = b[0];
+  int i;
+
+  for (i=0; i < OCB_BLOCK_LEN - 1; i++)
+    b[i] = (b[i] << 1) | (b[i+1] >> 7);
+
+  b[OCB_BLOCK_LEN-1] = (b[OCB_BLOCK_LEN-1] << 1) ^ ((b_0 >> 7) * 135);
+#else
+  /* This is the generic code for 16 byte blocks.  However it is not
+     faster than the straight byte by byte implementation.  */
+  u64 l_0, l, r;
+
+  l = buf_get_be64 (b);
+  r = buf_get_be64 (b + 8);
+
+  l_0 = (int64_t)l >> 63;
+  l = (l + l) ^ (r >> 63);
+  r = (r + r) ^ (l_0 & 135);
+
+  buf_put_be64 (b, l);
+  buf_put_be64 (b+8, r);
+#endif
+}
+
+
+/* Double the OCB_BLOCK_LEN sized block S and store it at D.  S and D
+   may point to the same memory location but they may not overlap.  */
+static void
+double_block_cpy (unsigned char *d, const unsigned char *s)
+{
+  if (d != s)
+    buf_cpy (d, s, OCB_BLOCK_LEN);
+  double_block (d);
+}
+
+
+/* Copy NBYTES from buffer S starting at bit offset BITOFF to buffer D.  */
+static void
+bit_copy (unsigned char *d, const unsigned char *s,
+          unsigned int bitoff, unsigned int nbytes)
+{
+  unsigned int shift;
+
+  s += bitoff / 8;
+  shift = bitoff % 8;
+  if (shift)
+    {
+      for (; nbytes; nbytes--, d++, s++)
+        *d = (s[0] << shift) | (s[1] >> (8 - shift));
+    }
+  else
+    {
+      for (; nbytes; nbytes--, d++, s++)
+        *d = *s;
+    }
+}
+
+
+/* Return the L-value for block N.  In most cases we use the table;
+   only if the lower OCB_L_TABLE_SIZE bits of N are zero we need to
+   compute it.  With a table size of 16 we need to this this only
+   every 65536-th block.  L_TMP is a helper buffer of size
+   OCB_BLOCK_LEN which is used to hold the computation if not taken
+   from the table.  */
+const unsigned char *
+_gcry_cipher_ocb_get_l (gcry_cipher_hd_t c, unsigned char *l_tmp, u64 n)
+{
+  int ntz = _gcry_ctz64 (n);
+
+  if (ntz < OCB_L_TABLE_SIZE)
+    return c->u_mode.ocb.L[ntz];
+
+  double_block_cpy (l_tmp, c->u_mode.ocb.L[OCB_L_TABLE_SIZE - 1]);
+  for (ntz -= OCB_L_TABLE_SIZE; ntz; ntz--)
+    double_block (l_tmp);
+
+  return l_tmp;
+}
+
+
+/* Set the nonce for OCB.  This requires that the key has been set.
+   Using it again resets start a new encryption cycle using the same
+   key.  */
+gcry_err_code_t
+_gcry_cipher_ocb_set_nonce (gcry_cipher_hd_t c, const unsigned char *nonce,
+                            size_t noncelen)
+{
+  unsigned char ktop[OCB_BLOCK_LEN];
+  unsigned char stretch[OCB_BLOCK_LEN + 8];
+  unsigned int bottom;
+  int i;
+  unsigned int burn = 0;
+  unsigned int nburn;
+
+  /* Check args.  */
+  if (!c->marks.key)
+    return GPG_ERR_INV_STATE;  /* Key must have been set first.  */
+  switch (c->u_mode.ocb.taglen)
+    {
+    case 8:
+    case 12:
+    case 16:
+      break;
+    default:
+      return GPG_ERR_BUG; /* Invalid tag length. */
+    }
+
+  if (c->spec->blocksize != OCB_BLOCK_LEN)
+    return GPG_ERR_CIPHER_ALGO;
+  if (!nonce)
+    return GPG_ERR_INV_ARG;
+  /* 120 bit is the allowed maximum.  In addition we impose a minimum
+     of 64 bit.  */
+  if (noncelen > (120/8) || noncelen < (64/8) || noncelen >= OCB_BLOCK_LEN)
+    return GPG_ERR_INV_LENGTH;
+
+  /* Set up the L table.  */
+  /* L_star = E(zero_128) */
+  memset (ktop, 0, OCB_BLOCK_LEN);
+  nburn = c->spec->encrypt (&c->context.c, c->u_mode.ocb.L_star, ktop);
+  burn = nburn > burn ? nburn : burn;
+  /* L_dollar = double(L_star)  */
+  double_block_cpy (c->u_mode.ocb.L_dollar, c->u_mode.ocb.L_star);
+  /* L_0 = double(L_dollar), ...  */
+  double_block_cpy (c->u_mode.ocb.L[0], c->u_mode.ocb.L_dollar);
+  for (i = 1; i < OCB_L_TABLE_SIZE; i++)
+    double_block_cpy (c->u_mode.ocb.L[i], c->u_mode.ocb.L[i-1]);
+
+  /* Prepare the nonce.  */
+  memset (ktop, 0, (OCB_BLOCK_LEN - noncelen));
+  buf_cpy (ktop + (OCB_BLOCK_LEN - noncelen), nonce, noncelen);
+  ktop[0] = ((c->u_mode.ocb.taglen * 8) % 128) << 1;
+  ktop[OCB_BLOCK_LEN - noncelen - 1] |= 1;
+  bottom = ktop[OCB_BLOCK_LEN - 1] & 0x3f;
+  ktop[OCB_BLOCK_LEN - 1] &= 0xc0; /* Zero the bottom bits.  */
+  nburn = c->spec->encrypt (&c->context.c, ktop, ktop);
+  burn = nburn > burn ? nburn : burn;
+  /* Stretch = Ktop || (Ktop[1..64] xor Ktop[9..72]) */
+  buf_cpy (stretch, ktop, OCB_BLOCK_LEN);
+  buf_xor (stretch + OCB_BLOCK_LEN, ktop, ktop + 1, 8);
+  /* Offset_0 = Stretch[1+bottom..128+bottom]
+     (We use the IV field to store the offset) */
+  bit_copy (c->u_iv.iv, stretch, bottom, OCB_BLOCK_LEN);
+  c->marks.iv = 1;
+
+  /* Checksum_0 = zeros(128)
+     (We use the CTR field to store the checksum) */
+  memset (c->u_ctr.ctr, 0, OCB_BLOCK_LEN);
+
+  /* Clear AAD buffer.  */
+  memset (c->u_mode.ocb.aad_offset, 0, OCB_BLOCK_LEN);
+  memset (c->u_mode.ocb.aad_sum, 0, OCB_BLOCK_LEN);
+
+  /* Setup other values.  */
+  memset (c->lastiv, 0, sizeof(c->lastiv));
+  c->unused = 0;
+  c->marks.tag = 0;
+  c->marks.finalize = 0;
+  c->u_mode.ocb.data_nblocks = 0;
+  c->u_mode.ocb.aad_nblocks = 0;
+  c->u_mode.ocb.aad_nleftover = 0;
+  c->u_mode.ocb.data_finalized = 0;
+  c->u_mode.ocb.aad_finalized = 0;
+
+  /* log_printhex ("L_*       ", c->u_mode.ocb.L_star, OCB_BLOCK_LEN); */
+  /* log_printhex ("L_$       ", c->u_mode.ocb.L_dollar, OCB_BLOCK_LEN); */
+  /* log_printhex ("L_0       ", c->u_mode.ocb.L[0], OCB_BLOCK_LEN); */
+  /* log_printhex ("L_1       ", c->u_mode.ocb.L[1], OCB_BLOCK_LEN); */
+  /* log_debug (   "bottom    : %u (decimal)\n", bottom); */
+  /* log_printhex ("Ktop      ", ktop, OCB_BLOCK_LEN); */
+  /* log_printhex ("Stretch   ", stretch, sizeof stretch); */
+  /* log_printhex ("Offset_0  ", c->u_iv.iv, OCB_BLOCK_LEN); */
+
+  /* Cleanup */
+  wipememory (ktop, sizeof ktop);
+  wipememory (stretch, sizeof stretch);
+  if (burn > 0)
+    _gcry_burn_stack (burn + 4*sizeof(void*));
+
+  return 0;
+}
+
+
+/* Process additional authentication data.  This implementation allows
+   to add additional authentication data at any time before the final
+   gcry_cipher_gettag.  */
+gcry_err_code_t
+_gcry_cipher_ocb_authenticate (gcry_cipher_hd_t c, const unsigned char *abuf,
+                               size_t abuflen)
+{
+  unsigned char l_tmp[OCB_BLOCK_LEN];
+
+  /* Check that a nonce and thus a key has been set and that we have
+     not yet computed the tag.  We also return an error if the aad has
+     been finalized (i.e. a short block has been processed).  */
+  if (!c->marks.iv || c->marks.tag || c->u_mode.ocb.aad_finalized)
+    return GPG_ERR_INV_STATE;
+
+  /* Check correct usage and arguments.  */
+  if (c->spec->blocksize != OCB_BLOCK_LEN)
+    return GPG_ERR_CIPHER_ALGO;
+
+  /* Process remaining data from the last call first.  */
+  if (c->u_mode.ocb.aad_nleftover)
+    {
+      for (; abuflen && c->u_mode.ocb.aad_nleftover < OCB_BLOCK_LEN;
+           abuf++, abuflen--)
+        c->u_mode.ocb.aad_leftover[c->u_mode.ocb.aad_nleftover++] = *abuf;
+
+      if (c->u_mode.ocb.aad_nleftover == OCB_BLOCK_LEN)
+        {
+          c->u_mode.ocb.aad_nblocks++;
+
+          /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+          buf_xor_1 (c->u_mode.ocb.aad_offset,
+                     ocb_get_l (c, l_tmp, c->u_mode.ocb.aad_nblocks),
+                     OCB_BLOCK_LEN);
+          /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i)  */
+          buf_xor (l_tmp, c->u_mode.ocb.aad_offset,
+                   c->u_mode.ocb.aad_leftover, OCB_BLOCK_LEN);
+          c->spec->encrypt (&c->context.c, l_tmp, l_tmp);
+          buf_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, OCB_BLOCK_LEN);
+
+          c->u_mode.ocb.aad_nleftover = 0;
+        }
+    }
+
+  if (!abuflen)
+    return 0;
+
+  /* Use a bulk method if available.  */
+  if (abuflen >= OCB_BLOCK_LEN && c->bulk.ocb_auth)
+    {
+      size_t nblks;
+      size_t nleft;
+      size_t ndone;
+
+      nblks = abuflen / OCB_BLOCK_LEN;
+      nleft = c->bulk.ocb_auth (c, abuf, nblks);
+      ndone = nblks - nleft;
+
+      abuf += ndone * OCB_BLOCK_LEN;
+      abuflen -= ndone * OCB_BLOCK_LEN;
+      nblks = nleft;
+    }
+
+  /* Hash all full blocks.  */
+  while (abuflen >= OCB_BLOCK_LEN)
+    {
+      c->u_mode.ocb.aad_nblocks++;
+
+      /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+      buf_xor_1 (c->u_mode.ocb.aad_offset,
+                 ocb_get_l (c, l_tmp, c->u_mode.ocb.aad_nblocks),
+                 OCB_BLOCK_LEN);
+      /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i)  */
+      buf_xor (l_tmp, c->u_mode.ocb.aad_offset, abuf, OCB_BLOCK_LEN);
+      c->spec->encrypt (&c->context.c, l_tmp, l_tmp);
+      buf_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, OCB_BLOCK_LEN);
+
+      abuf += OCB_BLOCK_LEN;
+      abuflen -= OCB_BLOCK_LEN;
+    }
+
+  /* Store away the remaining data.  */
+  for (; abuflen && c->u_mode.ocb.aad_nleftover < OCB_BLOCK_LEN;
+       abuf++, abuflen--)
+    c->u_mode.ocb.aad_leftover[c->u_mode.ocb.aad_nleftover++] = *abuf;
+  gcry_assert (!abuflen);
+
+  return 0;
+}
+
+
+/* Hash final partial AAD block.  */
+static void
+ocb_aad_finalize (gcry_cipher_hd_t c)
+{
+  unsigned char l_tmp[OCB_BLOCK_LEN];
+
+  /* Check that a nonce and thus a key has been set and that we have
+     not yet computed the tag.  We also skip this if the aad has been
+     finalized.  */
+  if (!c->marks.iv || c->marks.tag || c->u_mode.ocb.aad_finalized)
+    return;
+  if (c->spec->blocksize != OCB_BLOCK_LEN)
+    return;  /* Ooops.  */
+
+  /* Hash final partial block if any.  */
+  if (c->u_mode.ocb.aad_nleftover)
+    {
+      /* Offset_* = Offset_m xor L_*  */
+      buf_xor_1 (c->u_mode.ocb.aad_offset,
+                 c->u_mode.ocb.L_star, OCB_BLOCK_LEN);
+      /* CipherInput = (A_* || 1 || zeros(127-bitlen(A_*))) xor Offset_*  */
+      buf_cpy (l_tmp, c->u_mode.ocb.aad_leftover, c->u_mode.ocb.aad_nleftover);
+      memset (l_tmp + c->u_mode.ocb.aad_nleftover, 0,
+              OCB_BLOCK_LEN - c->u_mode.ocb.aad_nleftover);
+      l_tmp[c->u_mode.ocb.aad_nleftover] = 0x80;
+      buf_xor_1 (l_tmp, c->u_mode.ocb.aad_offset, OCB_BLOCK_LEN);
+      /* Sum = Sum_m xor ENCIPHER(K, CipherInput)  */
+      c->spec->encrypt (&c->context.c, l_tmp, l_tmp);
+      buf_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, OCB_BLOCK_LEN);
+
+      c->u_mode.ocb.aad_nleftover = 0;
+    }
+
+  /* Mark AAD as finalized so that gcry_cipher_ocb_authenticate can
+   * return an erro when called again.  */
+  c->u_mode.ocb.aad_finalized = 1;
+}
+
+
+
+/* Checksumming for encrypt and decrypt.  */
+static void
+ocb_checksum (unsigned char *chksum, const unsigned char *plainbuf,
+              size_t nblks)
+{
+  while (nblks > 0)
+    {
+      /* Checksum_i = Checksum_{i-1} xor P_i  */
+      buf_xor_1(chksum, plainbuf, OCB_BLOCK_LEN);
+
+      plainbuf += OCB_BLOCK_LEN;
+      nblks--;
+    }
+}
+
+
+/* Common code for encrypt and decrypt.  */
+static gcry_err_code_t
+ocb_crypt (gcry_cipher_hd_t c, int encrypt,
+           unsigned char *outbuf, size_t outbuflen,
+           const unsigned char *inbuf, size_t inbuflen)
+{
+  unsigned char l_tmp[OCB_BLOCK_LEN];
+  unsigned int burn = 0;
+  unsigned int nburn;
+  size_t nblks = inbuflen / OCB_BLOCK_LEN;
+
+  /* Check that a nonce and thus a key has been set and that we are
+     not yet in end of data state. */
+  if (!c->marks.iv || c->u_mode.ocb.data_finalized)
+    return GPG_ERR_INV_STATE;
+
+  /* Check correct usage and arguments.  */
+  if (c->spec->blocksize != OCB_BLOCK_LEN)
+    return GPG_ERR_CIPHER_ALGO;
+  if (outbuflen < inbuflen)
+    return GPG_ERR_BUFFER_TOO_SHORT;
+  if (c->marks.finalize)
+    ; /* Allow arbitarty length. */
+  else if ((inbuflen % OCB_BLOCK_LEN))
+    return GPG_ERR_INV_LENGTH;  /* We support only full blocks for now.  */
+
+  /* Use a bulk method if available.  */
+  if (nblks && c->bulk.ocb_crypt)
+    {
+      size_t nleft;
+      size_t ndone;
+
+      nleft = c->bulk.ocb_crypt (c, outbuf, inbuf, nblks, encrypt);
+      ndone = nblks - nleft;
+
+      inbuf += ndone * OCB_BLOCK_LEN;
+      outbuf += ndone * OCB_BLOCK_LEN;
+      inbuflen -= ndone * OCB_BLOCK_LEN;
+      outbuflen -= ndone * OCB_BLOCK_LEN;
+      nblks = nleft;
+    }
+
+  if (nblks)
+    {
+      gcry_cipher_encrypt_t crypt_fn =
+          encrypt ? c->spec->encrypt : c->spec->decrypt;
+
+      if (encrypt)
+        {
+          /* Checksum_i = Checksum_{i-1} xor P_i  */
+          ocb_checksum (c->u_ctr.ctr, inbuf, nblks);
+        }
+
+      /* Encrypt all full blocks.  */
+      while (inbuflen >= OCB_BLOCK_LEN)
+        {
+          c->u_mode.ocb.data_nblocks++;
+
+          /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+          buf_xor_1 (c->u_iv.iv,
+                     ocb_get_l (c, l_tmp, c->u_mode.ocb.data_nblocks),
+                     OCB_BLOCK_LEN);
+          /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)  */
+          buf_xor (outbuf, c->u_iv.iv, inbuf, OCB_BLOCK_LEN);
+          nburn = crypt_fn (&c->context.c, outbuf, outbuf);
+          burn = nburn > burn ? nburn : burn;
+          buf_xor_1 (outbuf, c->u_iv.iv, OCB_BLOCK_LEN);
+
+          inbuf += OCB_BLOCK_LEN;
+          inbuflen -= OCB_BLOCK_LEN;
+          outbuf += OCB_BLOCK_LEN;
+          outbuflen =- OCB_BLOCK_LEN;
+        }
+
+      if (!encrypt)
+        {
+          /* Checksum_i = Checksum_{i-1} xor P_i  */
+          ocb_checksum (c->u_ctr.ctr, outbuf - nblks * OCB_BLOCK_LEN, nblks);
+        }
+    }
+
+  /* Encrypt final partial block.  Note that we expect INBUFLEN to be
+     shorter than OCB_BLOCK_LEN (see above).  */
+  if (inbuflen)
+    {
+      unsigned char pad[OCB_BLOCK_LEN];
+
+      /* Offset_* = Offset_m xor L_*  */
+      buf_xor_1 (c->u_iv.iv, c->u_mode.ocb.L_star, OCB_BLOCK_LEN);
+      /* Pad = ENCIPHER(K, Offset_*) */
+      nburn = c->spec->encrypt (&c->context.c, pad, c->u_iv.iv);
+      burn = nburn > burn ? nburn : burn;
+
+      if (encrypt)
+        {
+          /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */
+          /* Note that INBUFLEN is less than OCB_BLOCK_LEN.  */
+          buf_cpy (l_tmp, inbuf, inbuflen);
+          memset (l_tmp + inbuflen, 0, OCB_BLOCK_LEN - inbuflen);
+          l_tmp[inbuflen] = 0x80;
+          buf_xor_1 (c->u_ctr.ctr, l_tmp, OCB_BLOCK_LEN);
+          /* C_* = P_* xor Pad[1..bitlen(P_*)] */
+          buf_xor (outbuf, inbuf, pad, inbuflen);
+        }
+      else
+        {
+          /* P_* = C_* xor Pad[1..bitlen(C_*)] */
+          /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */
+          buf_cpy (l_tmp, pad, OCB_BLOCK_LEN);
+          buf_cpy (l_tmp, inbuf, inbuflen);
+          buf_xor_1 (l_tmp, pad, OCB_BLOCK_LEN);
+          l_tmp[inbuflen] = 0x80;
+          buf_cpy (outbuf, l_tmp, inbuflen);
+
+          buf_xor_1 (c->u_ctr.ctr, l_tmp, OCB_BLOCK_LEN);
+        }
+    }
+
+  /* Compute the tag if the finalize flag has been set.  */
+  if (c->marks.finalize)
+    {
+      /* Tag = ENCIPHER(K, Checksum xor Offset xor L_$) xor HASH(K,A) */
+      buf_xor (c->u_mode.ocb.tag, c->u_ctr.ctr, c->u_iv.iv, OCB_BLOCK_LEN);
+      buf_xor_1 (c->u_mode.ocb.tag, c->u_mode.ocb.L_dollar, OCB_BLOCK_LEN);
+      nburn = c->spec->encrypt (&c->context.c,
+                                c->u_mode.ocb.tag, c->u_mode.ocb.tag);
+      burn = nburn > burn ? nburn : burn;
+
+      c->u_mode.ocb.data_finalized = 1;
+      /* Note that the the final part of the tag computation is done
+         by _gcry_cipher_ocb_get_tag.  */
+    }
+
+  if (burn > 0)
+    _gcry_burn_stack (burn + 4*sizeof(void*));
+
+  return 0;
+}
+
+
+/* Encrypt (INBUF,INBUFLEN) in OCB mode to OUTBUF.  OUTBUFLEN gives
+   the allocated size of OUTBUF.  This function accepts only multiples
+   of a full block unless gcry_cipher_final has been called in which
+   case the next block may have any length.  */
+gcry_err_code_t
+_gcry_cipher_ocb_encrypt (gcry_cipher_hd_t c,
+                          unsigned char *outbuf, size_t outbuflen,
+                          const unsigned char *inbuf, size_t inbuflen)
+
+{
+  return ocb_crypt (c, 1, outbuf, outbuflen, inbuf, inbuflen);
+}
+
+
+/* Decrypt (INBUF,INBUFLEN) in OCB mode to OUTBUF.  OUTBUFLEN gives
+   the allocated size of OUTBUF.  This function accepts only multiples
+   of a full block unless gcry_cipher_final has been called in which
+   case the next block may have any length.  */
+gcry_err_code_t
+_gcry_cipher_ocb_decrypt (gcry_cipher_hd_t c,
+                          unsigned char *outbuf, size_t outbuflen,
+                          const unsigned char *inbuf, size_t inbuflen)
+{
+  return ocb_crypt (c, 0, outbuf, outbuflen, inbuf, inbuflen);
+}
+
+
+/* Compute the tag.  The last data operation has already done some
+   part of it.  To allow adding AAD even after having done all data,
+   we finish the tag computation only here.  */
+static void
+compute_tag_if_needed (gcry_cipher_hd_t c)
+{
+  if (!c->marks.tag)
+    {
+      ocb_aad_finalize (c);
+      buf_xor_1 (c->u_mode.ocb.tag, c->u_mode.ocb.aad_sum, OCB_BLOCK_LEN);
+      c->marks.tag = 1;
+    }
+}
+
+
+/* Copy the already computed tag to OUTTAG.  OUTTAGSIZE is the
+   allocated size of OUTTAG; the function returns an error if that is
+   too short to hold the tag.  */
+gcry_err_code_t
+_gcry_cipher_ocb_get_tag (gcry_cipher_hd_t c,
+                          unsigned char *outtag, size_t outtagsize)
+{
+  if (c->u_mode.ocb.taglen > outtagsize)
+    return GPG_ERR_BUFFER_TOO_SHORT;
+  if (!c->u_mode.ocb.data_finalized)
+    return GPG_ERR_INV_STATE; /* Data has not yet been finalized.  */
+
+  compute_tag_if_needed (c);
+
+  memcpy (outtag, c->u_mode.ocb.tag, c->u_mode.ocb.taglen);
+
+  return 0;
+}
+
+
+/* Check that the tag (INTAG,TAGLEN) matches the computed tag for the
+   handle C.  */
+gcry_err_code_t
+_gcry_cipher_ocb_check_tag (gcry_cipher_hd_t c, const unsigned char *intag,
+                           size_t taglen)
+{
+  size_t n;
+
+  if (!c->u_mode.ocb.data_finalized)
+    return GPG_ERR_INV_STATE; /* Data has not yet been finalized.  */
+
+  compute_tag_if_needed (c);
+
+  n = c->u_mode.ocb.taglen;
+  if (taglen < n)
+    n = taglen;
+
+  if (!buf_eq_const (intag, c->u_mode.ocb.tag, n)
+      || c->u_mode.ocb.taglen != taglen)
+    return GPG_ERR_CHECKSUM;
+
+  return 0;
+}
index 3842774..7db7658 100644 (file)
@@ -26,7 +26,6 @@
 
 #include "g10lib.h"
 #include "cipher.h"
-#include "ath.h"
 #include "bufhelp.h"
 #include "./cipher-internal.h"
 
diff --git a/cipher/cipher-poly1305.c b/cipher/cipher-poly1305.c
new file mode 100644 (file)
index 0000000..a2a74e8
--- /dev/null
@@ -0,0 +1,334 @@
+/* cipher-poly1305.c  -  Poly1305 based AEAD cipher mode, RFC-7539
+ * Copyright (C) 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "bufhelp.h"
+#include "./cipher-internal.h"
+#include "./poly1305-internal.h"
+
+
+static inline int
+poly1305_bytecounter_add (u32 ctr[2], size_t add)
+{
+  int overflow = 0;
+
+  if (sizeof(add) > sizeof(u32))
+    {
+      u32 high_add = ((add >> 31) >> 1) & 0xffffffff;
+      ctr[1] += high_add;
+      if (ctr[1] < high_add)
+        overflow = 1;
+    }
+
+  ctr[0] += add;
+  if (ctr[0] >= add)
+    return overflow;
+
+  ctr[1] += 1;
+  return (ctr[1] < 1) || overflow;
+}
+
+
+static void
+poly1305_fill_bytecounts (gcry_cipher_hd_t c)
+{
+  u32 lenbuf[4];
+
+  lenbuf[0] = le_bswap32(c->u_mode.poly1305.aadcount[0]);
+  lenbuf[1] = le_bswap32(c->u_mode.poly1305.aadcount[1]);
+  lenbuf[2] = le_bswap32(c->u_mode.poly1305.datacount[0]);
+  lenbuf[3] = le_bswap32(c->u_mode.poly1305.datacount[1]);
+  _gcry_poly1305_update (&c->u_mode.poly1305.ctx, (byte*)lenbuf,
+                        sizeof(lenbuf));
+
+  wipememory(lenbuf, sizeof(lenbuf));
+}
+
+
+static void
+poly1305_do_padding (gcry_cipher_hd_t c, u32 ctr[2])
+{
+  static const byte zero_padding_buf[15] = {};
+  u32 padding_count;
+
+  /* Padding to 16 byte boundary. */
+  if (ctr[0] % 16 > 0)
+    {
+      padding_count = 16 - ctr[0] % 16;
+
+      _gcry_poly1305_update (&c->u_mode.poly1305.ctx, zero_padding_buf,
+                            padding_count);
+    }
+}
+
+
+static void
+poly1305_aad_finish (gcry_cipher_hd_t c)
+{
+  /* After AAD, feed padding bytes so we get 16 byte alignment. */
+  poly1305_do_padding (c, c->u_mode.poly1305.aadcount);
+
+  /* Start of encryption marks end of AAD stream. */
+  c->u_mode.poly1305.aad_finalized = 1;
+
+  c->u_mode.poly1305.datacount[0] = 0;
+  c->u_mode.poly1305.datacount[1] = 0;
+}
+
+
+static gcry_err_code_t
+poly1305_set_zeroiv (gcry_cipher_hd_t c)
+{
+  byte zero[8] = { 0, };
+
+  return _gcry_cipher_poly1305_setiv (c, zero, sizeof(zero));
+}
+
+
+gcry_err_code_t
+_gcry_cipher_poly1305_authenticate (gcry_cipher_hd_t c,
+                                   const byte * aadbuf, size_t aadbuflen)
+{
+  if (c->u_mode.poly1305.bytecount_over_limits)
+    return GPG_ERR_INV_LENGTH;
+  if (c->u_mode.poly1305.aad_finalized)
+    return GPG_ERR_INV_STATE;
+  if (c->marks.tag)
+    return GPG_ERR_INV_STATE;
+
+  if (!c->marks.iv)
+    poly1305_set_zeroiv(c);
+
+  if (poly1305_bytecounter_add(c->u_mode.poly1305.aadcount, aadbuflen))
+    {
+      c->u_mode.poly1305.bytecount_over_limits = 1;
+      return GPG_ERR_INV_LENGTH;
+    }
+
+  _gcry_poly1305_update (&c->u_mode.poly1305.ctx, aadbuf, aadbuflen);
+
+  return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_poly1305_encrypt (gcry_cipher_hd_t c,
+                              byte *outbuf, size_t outbuflen,
+                              const byte *inbuf, size_t inbuflen)
+{
+  gcry_err_code_t err;
+
+  if (outbuflen < inbuflen)
+    return GPG_ERR_BUFFER_TOO_SHORT;
+  if (c->marks.tag)
+    return GPG_ERR_INV_STATE;
+  if (c->u_mode.poly1305.bytecount_over_limits)
+    return GPG_ERR_INV_LENGTH;
+
+  if (!c->marks.iv)
+    {
+      err = poly1305_set_zeroiv(c);
+      if (err)
+        return err;
+    }
+
+  if (!c->u_mode.poly1305.aad_finalized)
+    poly1305_aad_finish(c);
+
+  if (poly1305_bytecounter_add(c->u_mode.poly1305.datacount, inbuflen))
+    {
+      c->u_mode.poly1305.bytecount_over_limits = 1;
+      return GPG_ERR_INV_LENGTH;
+    }
+
+  c->spec->stencrypt(&c->context.c, outbuf, (byte*)inbuf, inbuflen);
+
+  _gcry_poly1305_update (&c->u_mode.poly1305.ctx, outbuf, inbuflen);
+
+  return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_poly1305_decrypt (gcry_cipher_hd_t c,
+                              byte *outbuf, size_t outbuflen,
+                              const byte *inbuf, size_t inbuflen)
+{
+  gcry_err_code_t err;
+
+  if (outbuflen < inbuflen)
+    return GPG_ERR_BUFFER_TOO_SHORT;
+  if (c->marks.tag)
+    return GPG_ERR_INV_STATE;
+  if (c->u_mode.poly1305.bytecount_over_limits)
+    return GPG_ERR_INV_LENGTH;
+
+  if (!c->marks.iv)
+    {
+      err = poly1305_set_zeroiv(c);
+      if (err)
+        return err;
+    }
+
+  if (!c->u_mode.poly1305.aad_finalized)
+    poly1305_aad_finish(c);
+
+  if (poly1305_bytecounter_add(c->u_mode.poly1305.datacount, inbuflen))
+    {
+      c->u_mode.poly1305.bytecount_over_limits = 1;
+      return GPG_ERR_INV_LENGTH;
+    }
+
+  _gcry_poly1305_update (&c->u_mode.poly1305.ctx, inbuf, inbuflen);
+
+  c->spec->stdecrypt(&c->context.c, outbuf, (byte*)inbuf, inbuflen);
+  return 0;
+}
+
+
+static gcry_err_code_t
+_gcry_cipher_poly1305_tag (gcry_cipher_hd_t c,
+                          byte * outbuf, size_t outbuflen, int check)
+{
+  gcry_err_code_t err;
+
+  if (outbuflen < POLY1305_TAGLEN)
+    return GPG_ERR_BUFFER_TOO_SHORT;
+  if (c->u_mode.poly1305.bytecount_over_limits)
+    return GPG_ERR_INV_LENGTH;
+
+  if (!c->marks.iv)
+    {
+      err = poly1305_set_zeroiv(c);
+      if (err)
+        return err;
+    }
+
+  if (!c->u_mode.poly1305.aad_finalized)
+    poly1305_aad_finish(c);
+
+  if (!c->marks.tag)
+    {
+      /* After data, feed padding bytes so we get 16 byte alignment. */
+      poly1305_do_padding (c, c->u_mode.poly1305.datacount);
+
+      /* Write byte counts to poly1305. */
+      poly1305_fill_bytecounts(c);
+
+      _gcry_poly1305_finish(&c->u_mode.poly1305.ctx, c->u_iv.iv);
+
+      c->marks.tag = 1;
+    }
+
+  if (!check)
+    {
+      memcpy (outbuf, c->u_iv.iv, POLY1305_TAGLEN);
+    }
+  else
+    {
+      /* OUTBUFLEN gives the length of the user supplied tag in OUTBUF
+       * and thus we need to compare its length first.  */
+      if (outbuflen != POLY1305_TAGLEN
+          || !buf_eq_const (outbuf, c->u_iv.iv, POLY1305_TAGLEN))
+        return GPG_ERR_CHECKSUM;
+    }
+
+  return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_poly1305_get_tag (gcry_cipher_hd_t c, unsigned char *outtag,
+                          size_t taglen)
+{
+  return _gcry_cipher_poly1305_tag (c, outtag, taglen, 0);
+}
+
+gcry_err_code_t
+_gcry_cipher_poly1305_check_tag (gcry_cipher_hd_t c, const unsigned char *intag,
+                            size_t taglen)
+{
+  return _gcry_cipher_poly1305_tag (c, (unsigned char *) intag, taglen, 1);
+}
+
+
+void
+_gcry_cipher_poly1305_setkey (gcry_cipher_hd_t c)
+{
+  c->u_mode.poly1305.aadcount[0] = 0;
+  c->u_mode.poly1305.aadcount[1] = 0;
+
+  c->u_mode.poly1305.datacount[0] = 0;
+  c->u_mode.poly1305.datacount[1] = 0;
+
+  c->u_mode.poly1305.bytecount_over_limits = 0;
+  c->u_mode.poly1305.aad_finalized = 0;
+  c->marks.tag = 0;
+  c->marks.iv = 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_poly1305_setiv (gcry_cipher_hd_t c, const byte *iv, size_t ivlen)
+{
+  byte tmpbuf[64]; /* size of ChaCha20 block */
+  gcry_err_code_t err;
+
+  /* IV must be 96-bits */
+  if (!iv && ivlen != (96 / 8))
+    return GPG_ERR_INV_ARG;
+
+  memset(&c->u_mode.poly1305.ctx, 0, sizeof(c->u_mode.poly1305.ctx));
+
+  c->u_mode.poly1305.aadcount[0] = 0;
+  c->u_mode.poly1305.aadcount[1] = 0;
+
+  c->u_mode.poly1305.datacount[0] = 0;
+  c->u_mode.poly1305.datacount[1] = 0;
+
+  c->u_mode.poly1305.bytecount_over_limits = 0;
+  c->u_mode.poly1305.aad_finalized = 0;
+  c->marks.tag = 0;
+  c->marks.iv = 0;
+
+  /* Set up IV for stream cipher. */
+  c->spec->setiv (&c->context.c, iv, ivlen);
+
+  /* Get the first block from ChaCha20. */
+  memset(tmpbuf, 0, sizeof(tmpbuf));
+  c->spec->stencrypt(&c->context.c, tmpbuf, tmpbuf, sizeof(tmpbuf));
+
+  /* Use the first 32-bytes as Poly1305 key. */
+  err = _gcry_poly1305_init (&c->u_mode.poly1305.ctx, tmpbuf, POLY1305_KEYLEN);
+
+  wipememory(tmpbuf, sizeof(tmpbuf));
+
+  if (err)
+    return err;
+
+  c->marks.iv = 1;
+  return 0;
+}
index bb33d94..cecbab7 100644 (file)
@@ -1,5 +1,5 @@
 /* cipher-selftest.c - Helper functions for bulk encryption selftests.
- *     Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
 #endif
 
 
+/* Return an allocated buffers of size CONTEXT_SIZE with an alignment
+   of 16.  The caller must free that buffer using the address returned
+   at R_MEM.  Returns NULL and sets ERRNO on failure.  */
+void *
+_gcry_cipher_selftest_alloc_ctx (const int context_size, unsigned char **r_mem)
+{
+  int offs;
+  unsigned int ctx_aligned_size, memsize;
+
+  ctx_aligned_size = context_size + 15;
+  ctx_aligned_size -= ctx_aligned_size & 0xf;
+
+  memsize = ctx_aligned_size + 16;
+
+  *r_mem = xtrycalloc (1, memsize);
+  if (!*r_mem)
+    return NULL;
+
+  offs = (16 - ((uintptr_t)*r_mem & 15)) & 15;
+  return (void*)(*r_mem + offs);
+}
+
+
 /* Run the self-tests for <block cipher>-CBC-<block size>, tests bulk CBC
    decryption.  Returns NULL on success. */
 const char *
@@ -82,7 +105,11 @@ _gcry_selftest_helper_cbc (const char *cipher, gcry_cipher_setkey_t setkey_func,
   ciphertext = plaintext2 + nblocks * blocksize;
 
   /* Initialize ctx */
-  setkey_func (ctx, key, sizeof(key));
+  if (setkey_func (ctx, key, sizeof(key)) != GPG_ERR_NO_ERROR)
+   {
+     xfree(mem);
+     return "setkey failed";
+   }
 
   /* Test single block code path */
   memset (iv, 0x4e, blocksize);
@@ -104,6 +131,8 @@ _gcry_selftest_helper_cbc (const char *cipher, gcry_cipher_setkey_t setkey_func,
       syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
               "%s-CBC-%d test failed (plaintext mismatch)", cipher,
              blocksize * 8);
+#else
+      (void)cipher; /* Not used.  */
 #endif
       return "selftest for CBC failed - see syslog for details";
     }
@@ -199,7 +228,11 @@ _gcry_selftest_helper_cfb (const char *cipher, gcry_cipher_setkey_t setkey_func,
   ciphertext = plaintext2 + nblocks * blocksize;
 
   /* Initialize ctx */
-  setkey_func (ctx, key, sizeof(key));
+  if (setkey_func (ctx, key, sizeof(key)) != GPG_ERR_NO_ERROR)
+   {
+     xfree(mem);
+     return "setkey failed";
+   }
 
   /* Test single block code path */
   memset(iv, 0xd3, blocksize);
@@ -220,6 +253,8 @@ _gcry_selftest_helper_cfb (const char *cipher, gcry_cipher_setkey_t setkey_func,
       syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
               "%s-CFB-%d test failed (plaintext mismatch)", cipher,
              blocksize * 8);
+#else
+      (void)cipher; /* Not used.  */
 #endif
       return "selftest for CFB failed - see syslog for details";
     }
@@ -316,7 +351,11 @@ _gcry_selftest_helper_ctr (const char *cipher, gcry_cipher_setkey_t setkey_func,
   ciphertext2 = ciphertext + nblocks * blocksize;
 
   /* Initialize ctx */
-  setkey_func (ctx, key, sizeof(key));
+  if (setkey_func (ctx, key, sizeof(key)) != GPG_ERR_NO_ERROR)
+   {
+     xfree(mem);
+     return "setkey failed";
+   }
 
   /* Test single block code path */
   memset (iv, 0xff, blocksize);
@@ -344,6 +383,8 @@ _gcry_selftest_helper_ctr (const char *cipher, gcry_cipher_setkey_t setkey_func,
       syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
               "%s-CTR-%d test failed (plaintext mismatch)", cipher,
              blocksize * 8);
+#else
+      (void)cipher; /* Not used.  */
 #endif
       return "selftest for CTR failed - see syslog for details";
     }
index 3a0fe98..a435080 100644 (file)
@@ -1,5 +1,5 @@
 /* cipher-selftest.h - Helper functions for bulk encryption selftests.
- *     Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
@@ -40,6 +40,11 @@ typedef void (*gcry_cipher_bulk_ctr_enc_t)(void *context, unsigned char *iv,
                                           const void *inbuf_arg,
                                           size_t nblocks);
 
+/* Helper function to allocate an aligned context for selftests.  */
+void *_gcry_cipher_selftest_alloc_ctx (const int context_size,
+                                       unsigned char **r_mem);
+
+
 /* Helper function for bulk CBC decryption selftest */
 const char *
 _gcry_selftest_helper_cbc (const char *cipher, gcry_cipher_setkey_t setkey,
index 8c5a0b4..bdcbfbd 100644 (file)
@@ -26,8 +26,8 @@
 #include <errno.h>
 
 #include "g10lib.h"
+#include "../src/gcrypt-testapi.h"
 #include "cipher.h"
-#include "ath.h"
 #include "./cipher-internal.h"
 
 
@@ -84,6 +84,9 @@ static gcry_cipher_spec_t *cipher_list[] =
 #if USE_GOST28147
      &_gcry_cipher_spec_gost28147,
 #endif
+#if USE_CHACHA20
+     &_gcry_cipher_spec_chacha20,
+#endif
     NULL
   };
 
@@ -394,15 +397,11 @@ _gcry_cipher_open_internal (gcry_cipher_hd_t *handle,
     switch (mode)
       {
       case GCRY_CIPHER_MODE_CCM:
-#ifdef HAVE_U64_TYPEDEF
        if (spec->blocksize != GCRY_CCM_BLOCK_LEN)
          err = GPG_ERR_INV_CIPHER_MODE;
        if (!spec->encrypt || !spec->decrypt)
          err = GPG_ERR_INV_CIPHER_MODE;
        break;
-#else
-        err = GPG_ERR_NOT_SUPPORTED;
-#endif
 
       case GCRY_CIPHER_MODE_ECB:
       case GCRY_CIPHER_MODE_CBC:
@@ -416,6 +415,24 @@ _gcry_cipher_open_internal (gcry_cipher_hd_t *handle,
          err = GPG_ERR_INV_CIPHER_MODE;
        break;
 
+      case GCRY_CIPHER_MODE_POLY1305:
+       if (!spec->stencrypt || !spec->stdecrypt || !spec->setiv)
+         err = GPG_ERR_INV_CIPHER_MODE;
+       else if (spec->algo != GCRY_CIPHER_CHACHA20)
+         err = GPG_ERR_INV_CIPHER_MODE;
+       break;
+
+      case GCRY_CIPHER_MODE_OCB:
+        /* Note that our implementation allows only for 128 bit block
+           length algorithms.  Lower block lengths would be possible
+           but we do not implement them because they limit the
+           security too much.  */
+       if (!spec->encrypt || !spec->decrypt)
+         err = GPG_ERR_INV_CIPHER_MODE;
+       else if (spec->blocksize != (128/8))
+         err = GPG_ERR_INV_CIPHER_MODE;
+       break;
+
       case GCRY_CIPHER_MODE_STREAM:
        if (!spec->stencrypt || !spec->stdecrypt)
          err = GPG_ERR_INV_CIPHER_MODE;
@@ -436,7 +453,8 @@ _gcry_cipher_open_internal (gcry_cipher_hd_t *handle,
   /* Perform selftest here and mark this with a flag in cipher_table?
      No, we should not do this as it takes too long.  Further it does
      not make sense to exclude algorithms with failing selftests at
-     runtime: If a selftest fails there is something seriously wrong with the system and thus we better die immediately. */
+     runtime: If a selftest fails there is something seriously wrong
+     with the system and thus we better die immediately. */
 
   if (! err)
     {
@@ -460,11 +478,11 @@ _gcry_cipher_open_internal (gcry_cipher_hd_t *handle,
           size_t off = 0;
 
 #ifdef NEED_16BYTE_ALIGNED_CONTEXT
-          if ( ((unsigned long)h & 0x0f) )
+          if ( ((uintptr_t)h & 0x0f) )
             {
               /* The malloced block is not aligned on a 16 byte
                  boundary.  Correct for this.  */
-              off = 16 - ((unsigned long)h & 0x0f);
+              off = 16 - ((uintptr_t)h & 0x0f);
               h = (void*)((char*)h + off);
             }
 #endif /*NEED_16BYTE_ALIGNED_CONTEXT*/
@@ -489,6 +507,8 @@ _gcry_cipher_open_internal (gcry_cipher_hd_t *handle,
               h->bulk.cbc_enc = _gcry_aes_cbc_enc;
               h->bulk.cbc_dec = _gcry_aes_cbc_dec;
               h->bulk.ctr_enc = _gcry_aes_ctr_enc;
+              h->bulk.ocb_crypt = _gcry_aes_ocb_crypt;
+              h->bulk.ocb_auth  = _gcry_aes_ocb_auth;
               break;
 #endif /*USE_AES*/
 #ifdef USE_BLOWFISH
@@ -512,8 +532,17 @@ _gcry_cipher_open_internal (gcry_cipher_hd_t *handle,
               h->bulk.cbc_dec = _gcry_camellia_cbc_dec;
               h->bulk.cfb_dec = _gcry_camellia_cfb_dec;
               h->bulk.ctr_enc = _gcry_camellia_ctr_enc;
+              h->bulk.ocb_crypt = _gcry_camellia_ocb_crypt;
+              h->bulk.ocb_auth  = _gcry_camellia_ocb_auth;
               break;
 #endif /*USE_CAMELLIA*/
+#ifdef USE_DES
+            case GCRY_CIPHER_3DES:
+              h->bulk.cbc_dec =  _gcry_3des_cbc_dec;
+              h->bulk.cfb_dec =  _gcry_3des_cfb_dec;
+              h->bulk.ctr_enc =  _gcry_3des_ctr_enc;
+              break;
+#endif /*USE_DES*/
 #ifdef USE_SERPENT
            case GCRY_CIPHER_SERPENT128:
            case GCRY_CIPHER_SERPENT192:
@@ -521,6 +550,8 @@ _gcry_cipher_open_internal (gcry_cipher_hd_t *handle,
               h->bulk.cbc_dec = _gcry_serpent_cbc_dec;
               h->bulk.cfb_dec = _gcry_serpent_cfb_dec;
               h->bulk.ctr_enc = _gcry_serpent_ctr_enc;
+              h->bulk.ocb_crypt = _gcry_serpent_ocb_crypt;
+              h->bulk.ocb_auth  = _gcry_serpent_ocb_auth;
               break;
 #endif /*USE_SERPENT*/
 #ifdef USE_TWOFISH
@@ -529,12 +560,26 @@ _gcry_cipher_open_internal (gcry_cipher_hd_t *handle,
               h->bulk.cbc_dec = _gcry_twofish_cbc_dec;
               h->bulk.cfb_dec = _gcry_twofish_cfb_dec;
               h->bulk.ctr_enc = _gcry_twofish_ctr_enc;
+              h->bulk.ocb_crypt = _gcry_twofish_ocb_crypt;
+              h->bulk.ocb_auth  = _gcry_twofish_ocb_auth;
               break;
 #endif /*USE_TWOFISH*/
 
             default:
               break;
             }
+
+          /* Setup defaults depending on the mode.  */
+          switch (mode)
+            {
+            case GCRY_CIPHER_MODE_OCB:
+              h->u_mode.ocb.taglen = 16; /* Bytes.  */
+              break;
+
+            default:
+              break;
+            }
+
        }
     }
 
@@ -542,7 +587,7 @@ _gcry_cipher_open_internal (gcry_cipher_hd_t *handle,
 
   *handle = err ? NULL : h;
 
-  return gcry_error (err);
+  return err;
 }
 
 
@@ -602,6 +647,10 @@ cipher_setkey (gcry_cipher_hd_t c, byte *key, size_t keylen)
           _gcry_cipher_gcm_setkey (c);
           break;
 
+        case GCRY_CIPHER_MODE_POLY1305:
+          _gcry_cipher_poly1305_setkey (c);
+          break;
+
         default:
           break;
         };
@@ -618,10 +667,6 @@ cipher_setkey (gcry_cipher_hd_t c, byte *key, size_t keylen)
 static gcry_err_code_t
 cipher_setiv (gcry_cipher_hd_t c, const byte *iv, size_t ivlen)
 {
-  /* GCM has its own IV handler */
-  if (c->mode == GCRY_CIPHER_MODE_GCM)
-    return _gcry_cipher_gcm_setiv (c, iv, ivlen);
-
   /* If the cipher has its own IV handler, we use only this one.  This
      is currently used for stream ciphers requiring a nonce.  */
   if (c->spec->setiv)
@@ -690,11 +735,19 @@ cipher_reset (gcry_cipher_hd_t c)
       }
       break;
 
-#ifdef HAVE_U64_TYPEDEF
+    case GCRY_CIPHER_MODE_POLY1305:
+      memset (&c->u_mode.poly1305, 0, sizeof c->u_mode.poly1305);
+      break;
+
     case GCRY_CIPHER_MODE_CCM:
       memset (&c->u_mode.ccm, 0, sizeof c->u_mode.ccm);
       break;
-#endif
+
+    case GCRY_CIPHER_MODE_OCB:
+      memset (&c->u_mode.ocb, 0, sizeof c->u_mode.ocb);
+      /* Setup default taglen.  */
+      c->u_mode.ocb.taglen = 16;
+      break;
 
     default:
       break; /* u_mode unused by other modes. */
@@ -802,6 +855,15 @@ cipher_encrypt (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen,
       rc = _gcry_cipher_gcm_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
       break;
 
+    case GCRY_CIPHER_MODE_POLY1305:
+      rc = _gcry_cipher_poly1305_encrypt (c, outbuf, outbuflen,
+                                         inbuf, inbuflen);
+      break;
+
+    case GCRY_CIPHER_MODE_OCB:
+      rc = _gcry_cipher_ocb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+      break;
+
     case GCRY_CIPHER_MODE_STREAM:
       c->spec->stencrypt (&c->context.c,
                           outbuf, (byte*)/*arggg*/inbuf, inbuflen);
@@ -910,6 +972,15 @@ cipher_decrypt (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen,
       rc = _gcry_cipher_gcm_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
       break;
 
+    case GCRY_CIPHER_MODE_POLY1305:
+      rc = _gcry_cipher_poly1305_decrypt (c, outbuf, outbuflen,
+                                         inbuf, inbuflen);
+      break;
+
+    case GCRY_CIPHER_MODE_OCB:
+      rc = _gcry_cipher_ocb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+      break;
+
     case GCRY_CIPHER_MODE_STREAM:
       c->spec->stdecrypt (&c->context.c,
                           outbuf, (byte*)/*arggg*/inbuf, inbuflen);
@@ -991,6 +1062,18 @@ _gcry_cipher_setiv (gcry_cipher_hd_t hd, const void *iv, size_t ivlen)
         rc = _gcry_cipher_ccm_set_nonce (hd, iv, ivlen);
         break;
 
+      case GCRY_CIPHER_MODE_GCM:
+        rc =  _gcry_cipher_gcm_setiv (hd, iv, ivlen);
+        break;
+
+      case GCRY_CIPHER_MODE_POLY1305:
+        rc =  _gcry_cipher_poly1305_setiv (hd, iv, ivlen);
+        break;
+
+      case GCRY_CIPHER_MODE_OCB:
+        rc = _gcry_cipher_ocb_set_nonce (hd, iv, ivlen);
+        break;
+
       default:
         rc = cipher_setiv (hd, iv, ivlen);
         break;
@@ -1041,6 +1124,14 @@ _gcry_cipher_authenticate (gcry_cipher_hd_t hd, const void *abuf,
       rc = _gcry_cipher_gcm_authenticate (hd, abuf, abuflen);
       break;
 
+    case GCRY_CIPHER_MODE_POLY1305:
+      rc = _gcry_cipher_poly1305_authenticate (hd, abuf, abuflen);
+      break;
+
+    case GCRY_CIPHER_MODE_OCB:
+      rc = _gcry_cipher_ocb_authenticate (hd, abuf, abuflen);
+      break;
+
     default:
       log_error ("gcry_cipher_authenticate: invalid mode %d\n", hd->mode);
       rc = GPG_ERR_INV_CIPHER_MODE;
@@ -1070,6 +1161,14 @@ _gcry_cipher_gettag (gcry_cipher_hd_t hd, void *outtag, size_t taglen)
       rc = _gcry_cipher_gcm_get_tag (hd, outtag, taglen);
       break;
 
+    case GCRY_CIPHER_MODE_POLY1305:
+      rc = _gcry_cipher_poly1305_get_tag (hd, outtag, taglen);
+      break;
+
+    case GCRY_CIPHER_MODE_OCB:
+      rc = _gcry_cipher_ocb_get_tag (hd, outtag, taglen);
+      break;
+
     default:
       log_error ("gcry_cipher_gettag: invalid mode %d\n", hd->mode);
       rc = GPG_ERR_INV_CIPHER_MODE;
@@ -1099,6 +1198,14 @@ _gcry_cipher_checktag (gcry_cipher_hd_t hd, const void *intag, size_t taglen)
       rc = _gcry_cipher_gcm_check_tag (hd, intag, taglen);
       break;
 
+    case GCRY_CIPHER_MODE_POLY1305:
+      rc = _gcry_cipher_poly1305_check_tag (hd, intag, taglen);
+      break;
+
+    case GCRY_CIPHER_MODE_OCB:
+      rc = _gcry_cipher_ocb_check_tag (hd, intag, taglen);
+      break;
+
     default:
       log_error ("gcry_cipher_checktag: invalid mode %d\n", hd->mode);
       rc = GPG_ERR_INV_CIPHER_MODE;
@@ -1120,6 +1227,12 @@ _gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
       cipher_reset (h);
       break;
 
+    case GCRYCTL_FINALIZE:
+      if (!h || buffer || buflen)
+       return GPG_ERR_INV_ARG;
+      h->marks.finalize = 1;
+      break;
+
     case GCRYCTL_CFB_SYNC:
       cipher_sync( h );
       break;
@@ -1145,7 +1258,6 @@ _gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
       break;
 
     case GCRYCTL_SET_CCM_LENGTHS:
-#ifdef HAVE_U64_TYPEDEF
       {
         u64 params[3];
         size_t encryptedlen;
@@ -1153,10 +1265,10 @@ _gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
         size_t authtaglen;
 
         if (h->mode != GCRY_CIPHER_MODE_CCM)
-          return gcry_error (GPG_ERR_INV_CIPHER_MODE);
+          return GPG_ERR_INV_CIPHER_MODE;
 
         if (!buffer || buflen != 3 * sizeof(u64))
-          return gcry_error (GPG_ERR_INV_ARG);
+          return GPG_ERR_INV_ARG;
 
         /* This command is used to pass additional length parameters needed
            by CCM mode to initialize CBC-MAC.  */
@@ -1167,20 +1279,40 @@ _gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
 
         rc = _gcry_cipher_ccm_set_lengths (h, encryptedlen, aadlen, authtaglen);
       }
-#else
-      rc = GPG_ERR_NOT_SUPPORTED;
-#endif
+      break;
+
+    case GCRYCTL_SET_TAGLEN:
+      if (!h || !buffer || buflen != sizeof(int) )
+       return GPG_ERR_INV_ARG;
+      switch (h->mode)
+        {
+        case GCRY_CIPHER_MODE_OCB:
+          switch (*(int*)buffer)
+            {
+            case 8: case 12: case 16:
+              h->u_mode.ocb.taglen = *(int*)buffer;
+              break;
+            default:
+              rc = GPG_ERR_INV_LENGTH; /* Invalid tag length. */
+              break;
+            }
+          break;
+
+        default:
+          rc =GPG_ERR_INV_CIPHER_MODE;
+          break;
+        }
       break;
 
     case GCRYCTL_DISABLE_ALGO:
       /* This command expects NULL for H and BUFFER to point to an
          integer with the algo number.  */
       if( h || !buffer || buflen != sizeof(int) )
-       return gcry_error (GPG_ERR_CIPHER_ALGO);
+       return GPG_ERR_CIPHER_ALGO;
       disable_cipher_algo( *(int*)buffer );
       break;
 
-    case 61:  /* Disable weak key detection (private).  */
+    case PRIV_CIPHERCTL_DISABLE_WEAK_KEY:  /* (private)  */
       if (h->spec->set_extra_info)
         rc = h->spec->set_extra_info
           (&h->context.c, CIPHER_INFO_NO_WEAK_KEY, NULL, 0);
@@ -1188,7 +1320,7 @@ _gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
         rc = GPG_ERR_NOT_SUPPORTED;
       break;
 
-    case 62: /* Return current input vector (private).  */
+    case PRIV_CIPHERCTL_GET_INPUT_VECTOR: /* (private)  */
       /* This is the input block as used in CFB and OFB mode which has
          initially been set as IV.  The returned format is:
            1 byte  Actual length of the block in bytes.
@@ -1212,6 +1344,14 @@ _gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
         }
       break;
 
+    case GCRYCTL_SET_SBOX:
+      if (h->spec->set_extra_info)
+        rc = h->spec->set_extra_info
+          (&h->context.c, GCRYCTL_SET_SBOX, buffer, buflen);
+      else
+        rc = GPG_ERR_NOT_SUPPORTED;
+      break;
+
     default:
       rc = GPG_ERR_INV_OP;
     }
@@ -1221,24 +1361,55 @@ _gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
 
 
 /* Return information about the cipher handle H.  CMD is the kind of
-   information requested.  BUFFER and NBYTES are reserved for now.
-
-   There are no values for CMD yet defined.
-
-   The function always returns GPG_ERR_INV_OP.
-
+ * information requested.
+ *
+ * CMD may be one of:
+ *
+ *  GCRYCTL_GET_TAGLEN:
+ *      Return the length of the tag for an AE algorithm mode.  An
+ *      error is returned for modes which do not support a tag.
+ *      BUFFER must be given as NULL.  On success the result is stored
+ *      at NBYTES.  The taglen is returned in bytes.
+ *
+ * The function returns 0 on success or an error code.
  */
 gcry_err_code_t
 _gcry_cipher_info (gcry_cipher_hd_t h, int cmd, void *buffer, size_t *nbytes)
 {
   gcry_err_code_t rc = 0;
 
-  (void)h;
-  (void)buffer;
-  (void)nbytes;
-
   switch (cmd)
     {
+    case GCRYCTL_GET_TAGLEN:
+      if (!h || buffer || !nbytes)
+       rc = GPG_ERR_INV_ARG;
+      else
+       {
+          switch (h->mode)
+            {
+            case GCRY_CIPHER_MODE_OCB:
+              *nbytes = h->u_mode.ocb.taglen;
+              break;
+
+            case GCRY_CIPHER_MODE_CCM:
+              *nbytes = h->u_mode.ccm.authlen;
+              break;
+
+            case GCRY_CIPHER_MODE_GCM:
+              *nbytes = GCRY_GCM_BLOCK_LEN;
+              break;
+
+            case GCRY_CIPHER_MODE_POLY1305:
+              *nbytes = POLY1305_TAGLEN;
+              break;
+
+            default:
+              rc = GPG_ERR_INV_CIPHER_MODE;
+              break;
+            }
+        }
+      break;
+
     default:
       rc = GPG_ERR_INV_OP;
     }
@@ -1364,6 +1535,17 @@ _gcry_cipher_get_algo_blklen (int algo)
 gcry_err_code_t
 _gcry_cipher_init (void)
 {
+  if (fips_mode())
+    {
+      /* disable algorithms that are disallowed in fips */
+      int idx;
+      gcry_cipher_spec_t *spec;
+
+      for (idx = 0; (spec = cipher_list[idx]); idx++)
+        if (!spec->flags.fips)
+          spec->flags.disabled = 1;
+    }
+
   return 0;
 }
 
diff --git a/cipher/crc-intel-pclmul.c b/cipher/crc-intel-pclmul.c
new file mode 100644 (file)
index 0000000..2972fb4
--- /dev/null
@@ -0,0 +1,913 @@
+/* crc-intel-pclmul.c - Intel PCLMUL accelerated CRC implementation
+ * Copyright (C) 2016 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+
+#include "bithelp.h"
+#include "bufhelp.h"
+
+
+#if defined(ENABLE_PCLMUL_SUPPORT) && defined(ENABLE_SSE41_SUPPORT) && \
+    __GNUC__ >= 4 &&                                                   \
+    ((defined(__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__))
+
+
+#if _GCRY_GCC_VERSION >= 40400 /* 4.4 */
+/* Prevent compiler from issuing SSE instructions between asm blocks. */
+#  pragma GCC target("no-sse")
+#endif
+
+
+#define ALIGNED_16 __attribute__ ((aligned (16)))
+
+
+/* Constants structure for generic reflected/non-reflected CRC32 CLMUL
+ * functions. */
+struct crc32_consts_s
+{
+  /* k: { x^(32*17), x^(32*15), x^(32*5), x^(32*3), x^(32*2), 0 } mod P(x) */
+  u64 k[6];
+  /* my_p: { floor(x^64 / P(x)), P(x) } */
+  u64 my_p[2];
+};
+
+
+/* CLMUL constants for CRC32 and CRC32RFC1510. */
+static const struct crc32_consts_s crc32_consts ALIGNED_16 =
+{
+  { /* k[6] = reverse_33bits( x^(32*y) mod P(x) ) */
+    U64_C(0x154442bd4), U64_C(0x1c6e41596), /* y = { 17, 15 } */
+    U64_C(0x1751997d0), U64_C(0x0ccaa009e), /* y = { 5, 3 } */
+    U64_C(0x163cd6124), 0                   /* y = 2 */
+  },
+  { /* my_p[2] = reverse_33bits ( { floor(x^64 / P(x)), P(x) } ) */
+    U64_C(0x1f7011641), U64_C(0x1db710641)
+  }
+};
+
+/* CLMUL constants for CRC24RFC2440 (polynomial multiplied with x⁸). */
+static const struct crc32_consts_s crc24rfc2440_consts ALIGNED_16 =
+{
+  { /* k[6] = x^(32*y) mod P(x) << 32*/
+    U64_C(0x08289a00) << 32, U64_C(0x74b44a00) << 32, /* y = { 17, 15 } */
+    U64_C(0xc4b14d00) << 32, U64_C(0xfd7e0c00) << 32, /* y = { 5, 3 } */
+    U64_C(0xd9fe8c00) << 32, 0                        /* y = 2 */
+  },
+  { /* my_p[2] = { floor(x^64 / P(x)), P(x) } */
+    U64_C(0x1f845fe24), U64_C(0x1864cfb00)
+  }
+};
+
+/* Common constants for CRC32 algorithms. */
+static const byte crc32_refl_shuf_shift[3 * 16] ALIGNED_16 =
+  {
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  };
+static const byte crc32_shuf_shift[3 * 16] ALIGNED_16 =
+  {
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
+    0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  };
+static const byte *crc32_bswap_shuf = &crc32_shuf_shift[16];
+static const byte crc32_partial_fold_input_mask[16 + 16] ALIGNED_16 =
+  {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  };
+static const u64 crc32_merge9to15_shuf[15 - 9 + 1][2] ALIGNED_16 =
+  {
+    { U64_C(0x0706050403020100), U64_C(0xffffffffffffff0f) }, /* 9 */
+    { U64_C(0x0706050403020100), U64_C(0xffffffffffff0f0e) },
+    { U64_C(0x0706050403020100), U64_C(0xffffffffff0f0e0d) },
+    { U64_C(0x0706050403020100), U64_C(0xffffffff0f0e0d0c) },
+    { U64_C(0x0706050403020100), U64_C(0xffffff0f0e0d0c0b) },
+    { U64_C(0x0706050403020100), U64_C(0xffff0f0e0d0c0b0a) },
+    { U64_C(0x0706050403020100), U64_C(0xff0f0e0d0c0b0a09) }, /* 15 */
+  };
+static const u64 crc32_merge5to7_shuf[7 - 5 + 1][2] ALIGNED_16 =
+  {
+    { U64_C(0xffffff0703020100), U64_C(0xffffffffffffffff) }, /* 5 */
+    { U64_C(0xffff070603020100), U64_C(0xffffffffffffffff) },
+    { U64_C(0xff07060503020100), U64_C(0xffffffffffffffff) }, /* 7 */
+  };
+
+/* PCLMUL functions for reflected CRC32. */
+static inline void
+crc32_reflected_bulk (u32 *pcrc, const byte *inbuf, size_t inlen,
+                     const struct crc32_consts_s *consts)
+{
+  if (inlen >= 8 * 16)
+    {
+      asm volatile ("movd %[crc], %%xmm4\n\t"
+                   "movdqu %[inbuf_0], %%xmm0\n\t"
+                   "movdqu %[inbuf_1], %%xmm1\n\t"
+                   "movdqu %[inbuf_2], %%xmm2\n\t"
+                   "movdqu %[inbuf_3], %%xmm3\n\t"
+                   "pxor %%xmm4, %%xmm0\n\t"
+                   :
+                   : [inbuf_0] "m" (inbuf[0 * 16]),
+                     [inbuf_1] "m" (inbuf[1 * 16]),
+                     [inbuf_2] "m" (inbuf[2 * 16]),
+                     [inbuf_3] "m" (inbuf[3 * 16]),
+                     [crc] "m" (*pcrc)
+                   );
+
+      inbuf += 4 * 16;
+      inlen -= 4 * 16;
+
+      asm volatile ("movdqa %[k1k2], %%xmm4\n\t"
+                   :
+                   : [k1k2] "m" (consts->k[1 - 1])
+                   );
+
+      /* Fold by 4. */
+      while (inlen >= 4 * 16)
+       {
+         asm volatile ("movdqu %[inbuf_0], %%xmm5\n\t"
+                       "movdqa %%xmm0, %%xmm6\n\t"
+                       "pclmulqdq $0x00, %%xmm4, %%xmm0\n\t"
+                       "pclmulqdq $0x11, %%xmm4, %%xmm6\n\t"
+                       "pxor %%xmm5, %%xmm0\n\t"
+                       "pxor %%xmm6, %%xmm0\n\t"
+
+                       "movdqu %[inbuf_1], %%xmm5\n\t"
+                       "movdqa %%xmm1, %%xmm6\n\t"
+                       "pclmulqdq $0x00, %%xmm4, %%xmm1\n\t"
+                       "pclmulqdq $0x11, %%xmm4, %%xmm6\n\t"
+                       "pxor %%xmm5, %%xmm1\n\t"
+                       "pxor %%xmm6, %%xmm1\n\t"
+
+                       "movdqu %[inbuf_2], %%xmm5\n\t"
+                       "movdqa %%xmm2, %%xmm6\n\t"
+                       "pclmulqdq $0x00, %%xmm4, %%xmm2\n\t"
+                       "pclmulqdq $0x11, %%xmm4, %%xmm6\n\t"
+                       "pxor %%xmm5, %%xmm2\n\t"
+                       "pxor %%xmm6, %%xmm2\n\t"
+
+                       "movdqu %[inbuf_3], %%xmm5\n\t"
+                       "movdqa %%xmm3, %%xmm6\n\t"
+                       "pclmulqdq $0x00, %%xmm4, %%xmm3\n\t"
+                       "pclmulqdq $0x11, %%xmm4, %%xmm6\n\t"
+                       "pxor %%xmm5, %%xmm3\n\t"
+                       "pxor %%xmm6, %%xmm3\n\t"
+                       :
+                       : [inbuf_0] "m" (inbuf[0 * 16]),
+                         [inbuf_1] "m" (inbuf[1 * 16]),
+                         [inbuf_2] "m" (inbuf[2 * 16]),
+                         [inbuf_3] "m" (inbuf[3 * 16])
+                       );
+
+         inbuf += 4 * 16;
+         inlen -= 4 * 16;
+       }
+
+      asm volatile ("movdqa %[k3k4], %%xmm6\n\t"
+                   "movdqa %[my_p], %%xmm5\n\t"
+                   :
+                   : [k3k4] "m" (consts->k[3 - 1]),
+                     [my_p] "m" (consts->my_p[0])
+                   );
+
+      /* Fold 4 to 1. */
+
+      asm volatile ("movdqa %%xmm0, %%xmm4\n\t"
+                   "pclmulqdq $0x00, %%xmm6, %%xmm0\n\t"
+                   "pclmulqdq $0x11, %%xmm6, %%xmm4\n\t"
+                   "pxor %%xmm1, %%xmm0\n\t"
+                   "pxor %%xmm4, %%xmm0\n\t"
+
+                   "movdqa %%xmm0, %%xmm4\n\t"
+                   "pclmulqdq $0x00, %%xmm6, %%xmm0\n\t"
+                   "pclmulqdq $0x11, %%xmm6, %%xmm4\n\t"
+                   "pxor %%xmm2, %%xmm0\n\t"
+                   "pxor %%xmm4, %%xmm0\n\t"
+
+                   "movdqa %%xmm0, %%xmm4\n\t"
+                   "pclmulqdq $0x00, %%xmm6, %%xmm0\n\t"
+                   "pclmulqdq $0x11, %%xmm6, %%xmm4\n\t"
+                   "pxor %%xmm3, %%xmm0\n\t"
+                   "pxor %%xmm4, %%xmm0\n\t"
+                   :
+                   :
+                   );
+    }
+  else
+    {
+      asm volatile ("movd %[crc], %%xmm1\n\t"
+                   "movdqu %[inbuf], %%xmm0\n\t"
+                   "movdqa %[k3k4], %%xmm6\n\t"
+                   "pxor %%xmm1, %%xmm0\n\t"
+                   "movdqa %[my_p], %%xmm5\n\t"
+                   :
+                   : [inbuf] "m" (*inbuf),
+                     [crc] "m" (*pcrc),
+                     [k3k4] "m" (consts->k[3 - 1]),
+                     [my_p] "m" (consts->my_p[0])
+                   );
+
+      inbuf += 16;
+      inlen -= 16;
+    }
+
+  /* Fold by 1. */
+  if (inlen >= 16)
+    {
+      while (inlen >= 16)
+       {
+         /* Load next block to XMM2. Fold XMM0 to XMM0:XMM1. */
+         asm volatile ("movdqu %[inbuf], %%xmm2\n\t"
+                       "movdqa %%xmm0, %%xmm1\n\t"
+                       "pclmulqdq $0x00, %%xmm6, %%xmm0\n\t"
+                       "pclmulqdq $0x11, %%xmm6, %%xmm1\n\t"
+                       "pxor %%xmm2, %%xmm0\n\t"
+                       "pxor %%xmm1, %%xmm0\n\t"
+                       :
+                       : [inbuf] "m" (*inbuf)
+                       );
+
+         inbuf += 16;
+         inlen -= 16;
+       }
+    }
+
+  /* Partial fold. */
+  if (inlen)
+    {
+      /* Load last input and add padding zeros. */
+      asm volatile ("movdqu %[shr_shuf], %%xmm3\n\t"
+                   "movdqu %[shl_shuf], %%xmm4\n\t"
+                   "movdqu %[mask], %%xmm2\n\t"
+
+                   "movdqa %%xmm0, %%xmm1\n\t"
+                   "pshufb %%xmm4, %%xmm0\n\t"
+                   "movdqu %[inbuf], %%xmm4\n\t"
+                   "pshufb %%xmm3, %%xmm1\n\t"
+                   "pand %%xmm4, %%xmm2\n\t"
+                   "por %%xmm1, %%xmm2\n\t"
+
+                   "movdqa %%xmm0, %%xmm1\n\t"
+                   "pclmulqdq $0x00, %%xmm6, %%xmm0\n\t"
+                   "pclmulqdq $0x11, %%xmm6, %%xmm1\n\t"
+                   "pxor %%xmm2, %%xmm0\n\t"
+                   "pxor %%xmm1, %%xmm0\n\t"
+                   :
+                   : [inbuf] "m" (*(inbuf - 16 + inlen)),
+                     [mask] "m" (crc32_partial_fold_input_mask[inlen]),
+                     [shl_shuf] "m" (crc32_refl_shuf_shift[inlen]),
+                     [shr_shuf] "m" (crc32_refl_shuf_shift[inlen + 16])
+                   );
+
+      inbuf += inlen;
+      inlen -= inlen;
+    }
+
+  /* Final fold. */
+  asm volatile (/* reduce 128-bits to 96-bits */
+               "movdqa %%xmm0, %%xmm1\n\t"
+               "pclmulqdq $0x10, %%xmm6, %%xmm0\n\t"
+               "psrldq $8, %%xmm1\n\t"
+               "pxor %%xmm1, %%xmm0\n\t"
+
+               /* reduce 96-bits to 64-bits */
+               "pshufd $0xfc, %%xmm0, %%xmm1\n\t" /* [00][00][00][x] */
+               "pshufd $0xf9, %%xmm0, %%xmm0\n\t" /* [00][00][x>>64][x>>32] */
+               "pclmulqdq $0x00, %[k5], %%xmm1\n\t" /* [00][00][xx][xx] */
+               "pxor %%xmm1, %%xmm0\n\t" /* top 64-bit are zero */
+
+               /* barrett reduction */
+               "pshufd $0xf3, %%xmm0, %%xmm1\n\t" /* [00][00][x>>32][00] */
+               "pslldq $4, %%xmm0\n\t" /* [??][x>>32][??][??] */
+               "pclmulqdq $0x00, %%xmm5, %%xmm1\n\t" /* [00][xx][xx][00] */
+               "pclmulqdq $0x10, %%xmm5, %%xmm1\n\t" /* [00][xx][xx][00] */
+               "pxor %%xmm1, %%xmm0\n\t"
+
+               /* store CRC */
+               "pextrd $2, %%xmm0, %[out]\n\t"
+               : [out] "=m" (*pcrc)
+               : [k5] "m" (consts->k[5 - 1])
+               );
+}
+
+static inline void
+crc32_reflected_less_than_16 (u32 *pcrc, const byte *inbuf, size_t inlen,
+                             const struct crc32_consts_s *consts)
+{
+  if (inlen < 4)
+    {
+      u32 crc = *pcrc;
+      u32 data;
+
+      asm volatile ("movdqa %[my_p], %%xmm5\n\t"
+                   :
+                   : [my_p] "m" (consts->my_p[0])
+                   );
+
+      if (inlen == 1)
+       {
+         data = inbuf[0];
+         data ^= crc;
+         data <<= 24;
+         crc >>= 8;
+       }
+      else if (inlen == 2)
+       {
+         data = *((const u16 *)inbuf);
+         data ^= crc;
+         data <<= 16;
+         crc >>= 16;
+       }
+      else
+       {
+         data = *((const u16 *)inbuf);
+         data |= inbuf[2] << 16;
+         data ^= crc;
+         data <<= 8;
+         crc >>= 24;
+       }
+
+      /* Barrett reduction */
+      asm volatile ("movd %[in], %%xmm0\n\t"
+                   "movd %[crc], %%xmm1\n\t"
+
+                   "pclmulqdq $0x00, %%xmm5, %%xmm0\n\t" /* [00][00][xx][xx] */
+                   "psllq $32, %%xmm1\n\t"
+                   "pshufd $0xfc, %%xmm0, %%xmm0\n\t" /* [00][00][00][x] */
+                   "pclmulqdq $0x10, %%xmm5, %%xmm0\n\t" /* [00][00][xx][xx] */
+                   "pxor %%xmm1, %%xmm0\n\t"
+
+                   "pextrd $1, %%xmm0, %[out]\n\t"
+                   : [out] "=m" (*pcrc)
+                   : [in] "rm" (data),
+                     [crc] "rm" (crc)
+                   );
+    }
+  else if (inlen == 4)
+    {
+      /* Barrett reduction */
+      asm volatile ("movd %[crc], %%xmm1\n\t"
+                   "movd %[in], %%xmm0\n\t"
+                   "movdqa %[my_p], %%xmm5\n\t"
+                   "pxor %%xmm1, %%xmm0\n\t"
+
+                   "pclmulqdq $0x00, %%xmm5, %%xmm0\n\t" /* [00][00][xx][xx] */
+                   "pshufd $0xfc, %%xmm0, %%xmm0\n\t" /* [00][00][00][x] */
+                   "pclmulqdq $0x10, %%xmm5, %%xmm0\n\t" /* [00][00][xx][xx] */
+
+                   "pextrd $1, %%xmm0, %[out]\n\t"
+                   : [out] "=m" (*pcrc)
+                   : [in] "m" (*inbuf),
+                     [crc] "m" (*pcrc),
+                     [my_p] "m" (consts->my_p[0])
+                   );
+    }
+  else
+    {
+      asm volatile ("movdqu %[shuf], %%xmm4\n\t"
+                   "movd %[crc], %%xmm1\n\t"
+                   "movdqa %[my_p], %%xmm5\n\t"
+                   "movdqa %[k3k4], %%xmm6\n\t"
+                   :
+                   : [shuf] "m" (crc32_refl_shuf_shift[inlen]),
+                     [crc] "m" (*pcrc),
+                     [my_p] "m" (consts->my_p[0]),
+                     [k3k4] "m" (consts->k[3 - 1])
+                   );
+
+      if (inlen >= 8)
+       {
+         asm volatile ("movq %[inbuf], %%xmm0\n\t"
+                       :
+                       : [inbuf] "m" (*inbuf)
+                       );
+         if (inlen > 8)
+           {
+             asm volatile (/*"pinsrq $1, %[inbuf_tail], %%xmm0\n\t"*/
+                           "movq %[inbuf_tail], %%xmm2\n\t"
+                           "punpcklqdq %%xmm2, %%xmm0\n\t"
+                           "pshufb %[merge_shuf], %%xmm0\n\t"
+                           :
+                           : [inbuf_tail] "m" (inbuf[inlen - 8]),
+                             [merge_shuf] "m"
+                               (*crc32_merge9to15_shuf[inlen - 9])
+                           );
+           }
+       }
+      else
+       {
+         asm volatile ("movd %[inbuf], %%xmm0\n\t"
+                       "pinsrd $1, %[inbuf_tail], %%xmm0\n\t"
+                       "pshufb %[merge_shuf], %%xmm0\n\t"
+                       :
+                       : [inbuf] "m" (*inbuf),
+                         [inbuf_tail] "m" (inbuf[inlen - 4]),
+                         [merge_shuf] "m"
+                           (*crc32_merge5to7_shuf[inlen - 5])
+                       );
+       }
+
+      /* Final fold. */
+      asm volatile ("pxor %%xmm1, %%xmm0\n\t"
+                   "pshufb %%xmm4, %%xmm0\n\t"
+
+                   /* reduce 128-bits to 96-bits */
+                   "movdqa %%xmm0, %%xmm1\n\t"
+                   "pclmulqdq $0x10, %%xmm6, %%xmm0\n\t"
+                   "psrldq $8, %%xmm1\n\t"
+                   "pxor %%xmm1, %%xmm0\n\t" /* top 32-bit are zero */
+
+                   /* reduce 96-bits to 64-bits */
+                   "pshufd $0xfc, %%xmm0, %%xmm1\n\t" /* [00][00][00][x] */
+                   "pshufd $0xf9, %%xmm0, %%xmm0\n\t" /* [00][00][x>>64][x>>32] */
+                   "pclmulqdq $0x00, %[k5], %%xmm1\n\t" /* [00][00][xx][xx] */
+                   "pxor %%xmm1, %%xmm0\n\t" /* top 64-bit are zero */
+
+                   /* barrett reduction */
+                   "pshufd $0xf3, %%xmm0, %%xmm1\n\t" /* [00][00][x>>32][00] */
+                   "pslldq $4, %%xmm0\n\t" /* [??][x>>32][??][??] */
+                   "pclmulqdq $0x00, %%xmm5, %%xmm1\n\t" /* [00][xx][xx][00] */
+                   "pclmulqdq $0x10, %%xmm5, %%xmm1\n\t" /* [00][xx][xx][00] */
+                   "pxor %%xmm1, %%xmm0\n\t"
+
+                   /* store CRC */
+                   "pextrd $2, %%xmm0, %[out]\n\t"
+                   : [out] "=m" (*pcrc)
+                   : [k5] "m" (consts->k[5 - 1])
+                   );
+    }
+}
+
+/* PCLMUL functions for non-reflected CRC32. */
+static inline void
+crc32_bulk (u32 *pcrc, const byte *inbuf, size_t inlen,
+           const struct crc32_consts_s *consts)
+{
+  asm volatile ("movdqa %[bswap], %%xmm7\n\t"
+               :
+               : [bswap] "m" (*crc32_bswap_shuf)
+               );
+
+  if (inlen >= 8 * 16)
+    {
+      asm volatile ("movd %[crc], %%xmm4\n\t"
+                   "movdqu %[inbuf_0], %%xmm0\n\t"
+                   "movdqu %[inbuf_1], %%xmm1\n\t"
+                   "movdqu %[inbuf_2], %%xmm2\n\t"
+                   "pxor %%xmm4, %%xmm0\n\t"
+                   "movdqu %[inbuf_3], %%xmm3\n\t"
+                   "pshufb %%xmm7, %%xmm0\n\t"
+                   "pshufb %%xmm7, %%xmm1\n\t"
+                   "pshufb %%xmm7, %%xmm2\n\t"
+                   "pshufb %%xmm7, %%xmm3\n\t"
+                   :
+                   : [inbuf_0] "m" (inbuf[0 * 16]),
+                     [inbuf_1] "m" (inbuf[1 * 16]),
+                     [inbuf_2] "m" (inbuf[2 * 16]),
+                     [inbuf_3] "m" (inbuf[3 * 16]),
+                     [crc] "m" (*pcrc)
+                   );
+
+      inbuf += 4 * 16;
+      inlen -= 4 * 16;
+
+      asm volatile ("movdqa %[k1k2], %%xmm4\n\t"
+                   :
+                   : [k1k2] "m" (consts->k[1 - 1])
+                   );
+
+      /* Fold by 4. */
+      while (inlen >= 4 * 16)
+       {
+         asm volatile ("movdqu %[inbuf_0], %%xmm5\n\t"
+                       "movdqa %%xmm0, %%xmm6\n\t"
+                       "pshufb %%xmm7, %%xmm5\n\t"
+                       "pclmulqdq $0x01, %%xmm4, %%xmm0\n\t"
+                       "pclmulqdq $0x10, %%xmm4, %%xmm6\n\t"
+                       "pxor %%xmm5, %%xmm0\n\t"
+                       "pxor %%xmm6, %%xmm0\n\t"
+
+                       "movdqu %[inbuf_1], %%xmm5\n\t"
+                       "movdqa %%xmm1, %%xmm6\n\t"
+                       "pshufb %%xmm7, %%xmm5\n\t"
+                       "pclmulqdq $0x01, %%xmm4, %%xmm1\n\t"
+                       "pclmulqdq $0x10, %%xmm4, %%xmm6\n\t"
+                       "pxor %%xmm5, %%xmm1\n\t"
+                       "pxor %%xmm6, %%xmm1\n\t"
+
+                       "movdqu %[inbuf_2], %%xmm5\n\t"
+                       "movdqa %%xmm2, %%xmm6\n\t"
+                       "pshufb %%xmm7, %%xmm5\n\t"
+                       "pclmulqdq $0x01, %%xmm4, %%xmm2\n\t"
+                       "pclmulqdq $0x10, %%xmm4, %%xmm6\n\t"
+                       "pxor %%xmm5, %%xmm2\n\t"
+                       "pxor %%xmm6, %%xmm2\n\t"
+
+                       "movdqu %[inbuf_3], %%xmm5\n\t"
+                       "movdqa %%xmm3, %%xmm6\n\t"
+                       "pshufb %%xmm7, %%xmm5\n\t"
+                       "pclmulqdq $0x01, %%xmm4, %%xmm3\n\t"
+                       "pclmulqdq $0x10, %%xmm4, %%xmm6\n\t"
+                       "pxor %%xmm5, %%xmm3\n\t"
+                       "pxor %%xmm6, %%xmm3\n\t"
+                       :
+                       : [inbuf_0] "m" (inbuf[0 * 16]),
+                         [inbuf_1] "m" (inbuf[1 * 16]),
+                         [inbuf_2] "m" (inbuf[2 * 16]),
+                         [inbuf_3] "m" (inbuf[3 * 16])
+                       );
+
+         inbuf += 4 * 16;
+         inlen -= 4 * 16;
+       }
+
+      asm volatile ("movdqa %[k3k4], %%xmm6\n\t"
+                   "movdqa %[my_p], %%xmm5\n\t"
+                   :
+                   : [k3k4] "m" (consts->k[3 - 1]),
+                     [my_p] "m" (consts->my_p[0])
+                   );
+
+      /* Fold 4 to 1. */
+
+      asm volatile ("movdqa %%xmm0, %%xmm4\n\t"
+                   "pclmulqdq $0x01, %%xmm6, %%xmm0\n\t"
+                   "pclmulqdq $0x10, %%xmm6, %%xmm4\n\t"
+                   "pxor %%xmm1, %%xmm0\n\t"
+                   "pxor %%xmm4, %%xmm0\n\t"
+
+                   "movdqa %%xmm0, %%xmm4\n\t"
+                   "pclmulqdq $0x01, %%xmm6, %%xmm0\n\t"
+                   "pclmulqdq $0x10, %%xmm6, %%xmm4\n\t"
+                   "pxor %%xmm2, %%xmm0\n\t"
+                   "pxor %%xmm4, %%xmm0\n\t"
+
+                   "movdqa %%xmm0, %%xmm4\n\t"
+                   "pclmulqdq $0x01, %%xmm6, %%xmm0\n\t"
+                   "pclmulqdq $0x10, %%xmm6, %%xmm4\n\t"
+                   "pxor %%xmm3, %%xmm0\n\t"
+                   "pxor %%xmm4, %%xmm0\n\t"
+                   :
+                   :
+                   );
+    }
+  else
+    {
+      asm volatile ("movd %[crc], %%xmm1\n\t"
+                   "movdqu %[inbuf], %%xmm0\n\t"
+                   "movdqa %[k3k4], %%xmm6\n\t"
+                   "pxor %%xmm1, %%xmm0\n\t"
+                   "movdqa %[my_p], %%xmm5\n\t"
+                   "pshufb %%xmm7, %%xmm0\n\t"
+                   :
+                   : [inbuf] "m" (*inbuf),
+                     [crc] "m" (*pcrc),
+                     [k3k4] "m" (consts->k[3 - 1]),
+                     [my_p] "m" (consts->my_p[0])
+                   );
+
+      inbuf += 16;
+      inlen -= 16;
+    }
+
+  /* Fold by 1. */
+  if (inlen >= 16)
+    {
+      while (inlen >= 16)
+       {
+         /* Load next block to XMM2. Fold XMM0 to XMM0:XMM1. */
+         asm volatile ("movdqu %[inbuf], %%xmm2\n\t"
+                       "movdqa %%xmm0, %%xmm1\n\t"
+                       "pclmulqdq $0x01, %%xmm6, %%xmm0\n\t"
+                       "pshufb %%xmm7, %%xmm2\n\t"
+                       "pclmulqdq $0x10, %%xmm6, %%xmm1\n\t"
+                       "pxor %%xmm2, %%xmm0\n\t"
+                       "pxor %%xmm1, %%xmm0\n\t"
+                       :
+                       : [inbuf] "m" (*inbuf)
+                       );
+
+         inbuf += 16;
+         inlen -= 16;
+       }
+    }
+
+  /* Partial fold. */
+  if (inlen)
+    {
+      /* Load last input and add padding zeros. */
+      asm volatile ("movdqu %[shl_shuf], %%xmm4\n\t"
+                   "movdqu %[shr_shuf], %%xmm3\n\t"
+                   "movdqu %[mask], %%xmm2\n\t"
+
+                   "movdqa %%xmm0, %%xmm1\n\t"
+                   "pshufb %%xmm4, %%xmm0\n\t"
+                   "movdqu %[inbuf], %%xmm4\n\t"
+                   "pshufb %%xmm3, %%xmm1\n\t"
+                   "pand %%xmm4, %%xmm2\n\t"
+                   "por %%xmm1, %%xmm2\n\t"
+
+                   "pshufb %%xmm7, %%xmm2\n\t"
+
+                   "movdqa %%xmm0, %%xmm1\n\t"
+                   "pclmulqdq $0x01, %%xmm6, %%xmm0\n\t"
+                   "pclmulqdq $0x10, %%xmm6, %%xmm1\n\t"
+                   "pxor %%xmm2, %%xmm0\n\t"
+                   "pxor %%xmm1, %%xmm0\n\t"
+                   :
+                   : [inbuf] "m" (*(inbuf - 16 + inlen)),
+                     [mask] "m" (crc32_partial_fold_input_mask[inlen]),
+                     [shl_shuf] "m" (crc32_refl_shuf_shift[32 - inlen]),
+                     [shr_shuf] "m" (crc32_shuf_shift[inlen + 16])
+                   );
+
+      inbuf += inlen;
+      inlen -= inlen;
+    }
+
+  /* Final fold. */
+  asm volatile (/* reduce 128-bits to 96-bits */
+               "movdqa %%xmm0, %%xmm1\n\t"
+               "pclmulqdq $0x11, %%xmm6, %%xmm0\n\t"
+               "pslldq $8, %%xmm1\n\t"
+               "pxor %%xmm1, %%xmm0\n\t" /* bottom 32-bit are zero */
+
+               /* reduce 96-bits to 64-bits */
+               "pshufd $0x30, %%xmm0, %%xmm1\n\t" /* [00][x>>96][00][00] */
+               "pshufd $0x24, %%xmm0, %%xmm0\n\t" /* [00][xx][xx][00] */
+               "pclmulqdq $0x01, %[k5], %%xmm1\n\t" /* [00][xx][xx][00] */
+               "pxor %%xmm1, %%xmm0\n\t" /* top and bottom 32-bit are zero */
+
+               /* barrett reduction */
+               "pshufd $0x01, %%xmm0, %%xmm1\n\t" /* [00][00][00][x>>32] */
+               "pclmulqdq $0x01, %%xmm5, %%xmm0\n\t" /* [00][xx][xx][xx] */
+               "psrldq $4, %%xmm0\n\t" /* [00][00][xx][xx] */
+               "pclmulqdq $0x10, %%xmm5, %%xmm0\n\t"
+               "pxor %%xmm1, %%xmm0\n\t"
+
+               /* store CRC in input endian */
+               "movd %%xmm0, %%eax\n\t"
+               "bswapl %%eax\n\t"
+               "movl %%eax, %[out]\n\t"
+               : [out] "=m" (*pcrc)
+               : [k5] "m" (consts->k[5 - 1])
+               : "eax" );
+}
+
+static inline void
+crc32_less_than_16 (u32 *pcrc, const byte *inbuf, size_t inlen,
+                   const struct crc32_consts_s *consts)
+{
+  if (inlen < 4)
+    {
+      u32 crc = *pcrc;
+      u32 data;
+
+      asm volatile ("movdqa %[my_p], %%xmm5\n\t"
+                   :
+                   : [my_p] "m" (consts->my_p[0])
+                   );
+
+      if (inlen == 1)
+       {
+         data = inbuf[0];
+         data ^= crc;
+         data = _gcry_bswap32(data << 24);
+         crc = _gcry_bswap32(crc >> 8);
+       }
+      else if (inlen == 2)
+       {
+         data = *((const u16 *)inbuf);
+         data ^= crc;
+         data = _gcry_bswap32(data << 16);
+         crc = _gcry_bswap32(crc >> 16);
+       }
+      else
+       {
+         data = *((const u16 *)inbuf);
+         data |= inbuf[2] << 16;
+         data ^= crc;
+         data = _gcry_bswap32(data << 8);
+         crc = _gcry_bswap32(crc >> 24);
+       }
+
+      /* Barrett reduction */
+      asm volatile ("movd %[in], %%xmm0\n\t"
+                   "psllq $32, %%xmm0\n\t" /* [00][00][xx][00] */
+                   "movd %[crc], %%xmm1\n\t"
+
+                   "pclmulqdq $0x00, %%xmm5, %%xmm0\n\t" /* [00][xx][xx][00] */
+                   "pclmulqdq $0x11, %%xmm5, %%xmm0\n\t" /* [00][00][xx][xx] */
+                   "pxor %%xmm1, %%xmm0\n\t"
+
+                   /* store CRC in input endian */
+                   "movd %%xmm0, %%eax\n\t"
+                   "bswapl %%eax\n\t"
+                   "movl %%eax, %[out]\n\t"
+                   : [out] "=m" (*pcrc)
+                   : [in] "r" (data),
+                     [crc] "r" (crc)
+                   : "eax" );
+    }
+  else if (inlen == 4)
+    {
+      /* Barrett reduction */
+      asm volatile ("movd %[crc], %%xmm0\n\t"
+                   "movd %[in], %%xmm1\n\t"
+                   "movdqa %[my_p], %%xmm5\n\t"
+                   "pxor %%xmm1, %%xmm0\n\t"
+                   "pshufb %[bswap], %%xmm0\n\t" /* [xx][00][00][00] */
+
+                   "pclmulqdq $0x01, %%xmm5, %%xmm0\n\t" /* [00][xx][xx][00] */
+                   "pclmulqdq $0x11, %%xmm5, %%xmm0\n\t" /* [00][00][xx][xx] */
+
+                   /* store CRC in input endian */
+                   "movd %%xmm0, %%eax\n\t"
+                   "bswapl %%eax\n\t"
+                   "movl %%eax, %[out]\n\t"
+                   : [out] "=m" (*pcrc)
+                   : [in] "m" (*inbuf),
+                     [crc] "m" (*pcrc),
+                     [my_p] "m" (consts->my_p[0]),
+                     [bswap] "m" (*crc32_bswap_shuf)
+                   : "eax" );
+    }
+  else
+    {
+      asm volatile ("movdqu %[shuf], %%xmm7\n\t"
+                   "movd %[crc], %%xmm1\n\t"
+                   "movdqa %[my_p], %%xmm5\n\t"
+                   "movdqa %[k3k4], %%xmm6\n\t"
+                   :
+                   : [shuf] "m" (crc32_shuf_shift[32 - inlen]),
+                     [crc] "m" (*pcrc),
+                     [my_p] "m" (consts->my_p[0]),
+                     [k3k4] "m" (consts->k[3 - 1])
+                   );
+
+      if (inlen >= 8)
+       {
+         asm volatile ("movq %[inbuf], %%xmm0\n\t"
+                       :
+                       : [inbuf] "m" (*inbuf)
+                       );
+         if (inlen > 8)
+           {
+             asm volatile (/*"pinsrq $1, %[inbuf_tail], %%xmm0\n\t"*/
+                           "movq %[inbuf_tail], %%xmm2\n\t"
+                           "punpcklqdq %%xmm2, %%xmm0\n\t"
+                           "pshufb %[merge_shuf], %%xmm0\n\t"
+                           :
+                           : [inbuf_tail] "m" (inbuf[inlen - 8]),
+                             [merge_shuf] "m"
+                               (*crc32_merge9to15_shuf[inlen - 9])
+                           );
+           }
+       }
+      else
+       {
+         asm volatile ("movd %[inbuf], %%xmm0\n\t"
+                       "pinsrd $1, %[inbuf_tail], %%xmm0\n\t"
+                       "pshufb %[merge_shuf], %%xmm0\n\t"
+                       :
+                       : [inbuf] "m" (*inbuf),
+                         [inbuf_tail] "m" (inbuf[inlen - 4]),
+                         [merge_shuf] "m"
+                           (*crc32_merge5to7_shuf[inlen - 5])
+                       );
+       }
+
+      /* Final fold. */
+      asm volatile ("pxor %%xmm1, %%xmm0\n\t"
+                   "pshufb %%xmm7, %%xmm0\n\t"
+
+                   /* reduce 128-bits to 96-bits */
+                   "movdqa %%xmm0, %%xmm1\n\t"
+                   "pclmulqdq $0x11, %%xmm6, %%xmm0\n\t"
+                   "pslldq $8, %%xmm1\n\t"
+                   "pxor %%xmm1, %%xmm0\n\t" /* bottom 32-bit are zero */
+
+                   /* reduce 96-bits to 64-bits */
+                   "pshufd $0x30, %%xmm0, %%xmm1\n\t" /* [00][x>>96][00][00] */
+                   "pshufd $0x24, %%xmm0, %%xmm0\n\t" /* [00][xx][xx][00] */
+                   "pclmulqdq $0x01, %[k5], %%xmm1\n\t" /* [00][xx][xx][00] */
+                   "pxor %%xmm1, %%xmm0\n\t" /* top and bottom 32-bit are zero */
+
+                   /* barrett reduction */
+                   "pshufd $0x01, %%xmm0, %%xmm1\n\t" /* [00][00][00][x>>32] */
+                   "pclmulqdq $0x01, %%xmm5, %%xmm0\n\t" /* [00][xx][xx][xx] */
+                   "psrldq $4, %%xmm0\n\t" /* [00][00][xx][xx] */
+                   "pclmulqdq $0x10, %%xmm5, %%xmm0\n\t"
+                   "pxor %%xmm1, %%xmm0\n\t"
+
+                   /* store CRC in input endian */
+                   "movd %%xmm0, %%eax\n\t"
+                   "bswapl %%eax\n\t"
+                   "movl %%eax, %[out]\n\t"
+                   : [out] "=m" (*pcrc)
+                   : [k5] "m" (consts->k[5 - 1])
+                   : "eax" );
+    }
+}
+
+void
+_gcry_crc32_intel_pclmul (u32 *pcrc, const byte *inbuf, size_t inlen)
+{
+  const struct crc32_consts_s *consts = &crc32_consts;
+#if defined(__x86_64__) && defined(__WIN64__)
+  char win64tmp[2 * 16];
+
+  /* XMM6-XMM7 need to be restored after use. */
+  asm volatile ("movdqu %%xmm6, 0*16(%0)\n\t"
+                "movdqu %%xmm7, 1*16(%0)\n\t"
+                :
+                : "r" (win64tmp)
+                : "memory");
+#endif
+
+  if (!inlen)
+    return;
+
+  if (inlen >= 16)
+    crc32_reflected_bulk(pcrc, inbuf, inlen, consts);
+  else
+    crc32_reflected_less_than_16(pcrc, inbuf, inlen, consts);
+
+#if defined(__x86_64__) && defined(__WIN64__)
+  /* Restore used registers. */
+  asm volatile("movdqu 0*16(%0), %%xmm6\n\t"
+               "movdqu 1*16(%0), %%xmm7\n\t"
+               :
+               : "r" (win64tmp)
+               : "memory");
+#endif
+}
+
+void
+_gcry_crc24rfc2440_intel_pclmul (u32 *pcrc, const byte *inbuf, size_t inlen)
+{
+  const struct crc32_consts_s *consts = &crc24rfc2440_consts;
+#if defined(__x86_64__) && defined(__WIN64__)
+  char win64tmp[2 * 16];
+
+  /* XMM6-XMM7 need to be restored after use. */
+  asm volatile ("movdqu %%xmm6, 0*16(%0)\n\t"
+                "movdqu %%xmm7, 1*16(%0)\n\t"
+                :
+                : "r" (win64tmp)
+                : "memory");
+#endif
+
+  if (!inlen)
+    return;
+
+  /* Note: *pcrc in input endian. */
+
+  if (inlen >= 16)
+    crc32_bulk(pcrc, inbuf, inlen, consts);
+  else
+    crc32_less_than_16(pcrc, inbuf, inlen, consts);
+
+#if defined(__x86_64__) && defined(__WIN64__)
+  /* Restore used registers. */
+  asm volatile("movdqu 0*16(%0), %%xmm6\n\t"
+               "movdqu 1*16(%0), %%xmm7\n\t"
+               :
+               : "r" (win64tmp)
+               : "memory");
+#endif
+}
+
+#endif /* USE_INTEL_PCLMUL */
index 1322f0d..a1ce50b 100644 (file)
 #include "cipher.h"
 
 #include "bithelp.h"
+#include "bufhelp.h"
 
-/* Table of CRCs of all 8-bit messages.  Generated by running code
-   from RFC 1952 modified to print out the table. */
-static u32 crc32_table[256] = {
-  0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
-  0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
-  0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
-  0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
-  0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
-  0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
-  0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
-  0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
-  0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
-  0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
-  0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
-  0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
-  0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
-  0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
-  0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
-  0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
-  0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
-  0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
-  0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
-  0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
-  0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
-  0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
-  0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
-  0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
-  0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
-  0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
-  0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
-  0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
-  0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
-  0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
-  0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
-  0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
-  0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
-  0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
-  0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
-  0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
-  0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
-  0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
-  0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
-  0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
-  0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
-  0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
-  0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
-};
 
-/*
- * The following function was extracted from RFC 1952 by Simon
- * Josefsson, for the Shishi project, and modified to be compatible
- * with the modified CRC-32 used by RFC 1510, and subsequently
- * modified for GNU Libgcrypt to allow it to be used for calculating
- * both unmodified CRC-32 and modified CRC-32 values.  Original
- * copyright and notice from the document follows:
- *
- *    Copyright (c) 1996 L. Peter Deutsch
- *
- *    Permission is granted to copy and distribute this document for
- *    any purpose and without charge, including translations into
- *    other languages and incorporation into compilations, provided
- *    that the copyright notice and this notice are preserved, and
- *    that any substantive changes or deletions from the original are
- *    clearly marked.
- *
- * The copyright on RFCs, and consequently the function below, are
- * supposedly also retroactively claimed by the Internet Society
- * (according to rfc-editor@rfc-editor.org), with the following
- * copyright notice:
- *
- *    Copyright (C) The Internet Society.  All Rights Reserved.
- *
- *    This document and translations of it may be copied and furnished
- *    to others, and derivative works that comment on or otherwise
- *    explain it or assist in its implementation may be prepared,
- *    copied, published and distributed, in whole or in part, without
- *    restriction of any kind, provided that the above copyright
- *    notice and this paragraph are included on all such copies and
- *    derivative works.  However, this document itself may not be
- *    modified in any way, such as by removing the copyright notice or
- *    references to the Internet Society or other Internet
- *    organizations, except as needed for the purpose of developing
- *    Internet standards in which case the procedures for copyrights
- *    defined in the Internet Standards process must be followed, or
- *    as required to translate it into languages other than English.
- *
- *    The limited permissions granted above are perpetual and will not be
- *    revoked by the Internet Society or its successors or assigns.
- *
- *    This document and the information contained herein is provided
- *    on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET
- *    ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR
- *    IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE
- *    OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY
- *    IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
- *    PARTICULAR PURPOSE.
- *
- */
-static u32
-update_crc32 (u32 crc, const void *buf_arg, size_t len)
-{
-  const char *buf = buf_arg;
-  size_t n;
-
-  for (n = 0; n < len; n++)
-    crc = crc32_table[(crc ^ buf[n]) & 0xff] ^ (crc >> 8);
+/* USE_INTEL_PCLMUL indicates whether to compile CRC with Intel PCLMUL/SSE4.1
+ * code.  */
+#undef USE_INTEL_PCLMUL
+#if defined(ENABLE_PCLMUL_SUPPORT) && defined(ENABLE_SSE41_SUPPORT)
+# if ((defined(__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__))
+#  if __GNUC__ >= 4
+#   define USE_INTEL_PCLMUL 1
+#  endif
+# endif
+#endif /* USE_INTEL_PCLMUL */
 
-  return crc;
-}
 
 typedef struct
 {
   u32 CRC;
+#ifdef USE_INTEL_PCLMUL
+  unsigned int use_pclmul:1;           /* Intel PCLMUL shall be used.  */
+#endif
   byte buf[4];
 }
 CRC_CONTEXT;
 
+
+#ifdef USE_INTEL_PCLMUL
+/*-- crc-intel-pclmul.c --*/
+void _gcry_crc32_intel_pclmul (u32 *pcrc, const byte *inbuf, size_t inlen);
+void _gcry_crc24rfc2440_intel_pclmul (u32 *pcrc, const byte *inbuf,
+                                     size_t inlen);
+#endif
+
+
+/*
+ * Code generated by universal_crc by Danjel McGougan
+ *
+ * CRC parameters used:
+ *   bits:       32
+ *   poly:       0x04c11db7
+ *   init:       0xffffffff
+ *   xor:        0xffffffff
+ *   reverse:    true
+ *   non-direct: false
+ *
+ * CRC of the string "123456789" is 0xcbf43926
+ */
+
+static const u32 crc32_table[1024] = {
+  0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
+  0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+  0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+  0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+  0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+  0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+  0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
+  0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+  0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+  0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+  0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
+  0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+  0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
+  0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+  0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+  0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+  0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
+  0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+  0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
+  0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+  0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+  0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+  0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
+  0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+  0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+  0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+  0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+  0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+  0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
+  0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+  0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
+  0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+  0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+  0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+  0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+  0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+  0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
+  0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+  0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+  0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+  0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
+  0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+  0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
+  0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+  0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+  0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+  0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
+  0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+  0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
+  0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+  0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+  0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+  0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
+  0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+  0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+  0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+  0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+  0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+  0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
+  0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+  0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
+  0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+  0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+  0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
+  0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3,
+  0x646cc504, 0x7d77f445, 0x565aa786, 0x4f4196c7,
+  0xc8d98a08, 0xd1c2bb49, 0xfaefe88a, 0xe3f4d9cb,
+  0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, 0x87981ccf,
+  0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192,
+  0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496,
+  0x821b9859, 0x9b00a918, 0xb02dfadb, 0xa936cb9a,
+  0xe6775d5d, 0xff6c6c1c, 0xd4413fdf, 0xcd5a0e9e,
+  0x958424a2, 0x8c9f15e3, 0xa7b24620, 0xbea97761,
+  0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265,
+  0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69,
+  0x39316bae, 0x202a5aef, 0x0b07092c, 0x121c386d,
+  0xdf4636f3, 0xc65d07b2, 0xed705471, 0xf46b6530,
+  0xbb2af3f7, 0xa231c2b6, 0x891c9175, 0x9007a034,
+  0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38,
+  0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c,
+  0xf0794f05, 0xe9627e44, 0xc24f2d87, 0xdb541cc6,
+  0x94158a01, 0x8d0ebb40, 0xa623e883, 0xbf38d9c2,
+  0x38a0c50d, 0x21bbf44c, 0x0a96a78f, 0x138d96ce,
+  0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca,
+  0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97,
+  0xded79850, 0xc7cca911, 0xece1fad2, 0xf5facb93,
+  0x7262d75c, 0x6b79e61d, 0x4054b5de, 0x594f849f,
+  0x160e1258, 0x0f152319, 0x243870da, 0x3d23419b,
+  0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864,
+  0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60,
+  0xad24e1af, 0xb43fd0ee, 0x9f12832d, 0x8609b26c,
+  0xc94824ab, 0xd05315ea, 0xfb7e4629, 0xe2657768,
+  0x2f3f79f6, 0x362448b7, 0x1d091b74, 0x04122a35,
+  0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31,
+  0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d,
+  0x838a36fa, 0x9a9107bb, 0xb1bc5478, 0xa8a76539,
+  0x3b83984b, 0x2298a90a, 0x09b5fac9, 0x10aecb88,
+  0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, 0x74c20e8c,
+  0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180,
+  0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484,
+  0x71418a1a, 0x685abb5b, 0x4377e898, 0x5a6cd9d9,
+  0x152d4f1e, 0x0c367e5f, 0x271b2d9c, 0x3e001cdd,
+  0xb9980012, 0xa0833153, 0x8bae6290, 0x92b553d1,
+  0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5,
+  0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a,
+  0xca6b79ed, 0xd37048ac, 0xf85d1b6f, 0xe1462a2e,
+  0x66de36e1, 0x7fc507a0, 0x54e85463, 0x4df36522,
+  0x02b2f3e5, 0x1ba9c2a4, 0x30849167, 0x299fa026,
+  0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b,
+  0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f,
+  0x2c1c24b0, 0x350715f1, 0x1e2a4632, 0x07317773,
+  0x4870e1b4, 0x516bd0f5, 0x7a468336, 0x635db277,
+  0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, 0xe0d7848d,
+  0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189,
+  0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85,
+  0x674f9842, 0x7e54a903, 0x5579fac0, 0x4c62cb81,
+  0x8138c51f, 0x9823f45e, 0xb30ea79d, 0xaa1596dc,
+  0xe554001b, 0xfc4f315a, 0xd7626299, 0xce7953d8,
+  0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4,
+  0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0,
+  0x5e7ef3ec, 0x4765c2ad, 0x6c48916e, 0x7553a02f,
+  0x3a1236e8, 0x230907a9, 0x0824546a, 0x113f652b,
+  0x96a779e4, 0x8fbc48a5, 0xa4911b66, 0xbd8a2a27,
+  0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23,
+  0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e,
+  0x70d024b9, 0x69cb15f8, 0x42e6463b, 0x5bfd777a,
+  0xdc656bb5, 0xc57e5af4, 0xee530937, 0xf7483876,
+  0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, 0x9324fd72,
+  0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59,
+  0x0709a8dc, 0x06cbc2eb, 0x048d7cb2, 0x054f1685,
+  0x0e1351b8, 0x0fd13b8f, 0x0d9785d6, 0x0c55efe1,
+  0x091af964, 0x08d89353, 0x0a9e2d0a, 0x0b5c473d,
+  0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29,
+  0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5,
+  0x1235f2c8, 0x13f798ff, 0x11b126a6, 0x10734c91,
+  0x153c5a14, 0x14fe3023, 0x16b88e7a, 0x177ae44d,
+  0x384d46e0, 0x398f2cd7, 0x3bc9928e, 0x3a0bf8b9,
+  0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065,
+  0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901,
+  0x3157bf84, 0x3095d5b3, 0x32d36bea, 0x331101dd,
+  0x246be590, 0x25a98fa7, 0x27ef31fe, 0x262d5bc9,
+  0x23624d4c, 0x22a0277b, 0x20e69922, 0x2124f315,
+  0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71,
+  0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad,
+  0x709a8dc0, 0x7158e7f7, 0x731e59ae, 0x72dc3399,
+  0x7793251c, 0x76514f2b, 0x7417f172, 0x75d59b45,
+  0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, 0x7ccf6221,
+  0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd,
+  0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9,
+  0x6bb5866c, 0x6a77ec5b, 0x68315202, 0x69f33835,
+  0x62af7f08, 0x636d153f, 0x612bab66, 0x60e9c151,
+  0x65a6d7d4, 0x6464bde3, 0x662203ba, 0x67e0698d,
+  0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579,
+  0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5,
+  0x46c49a98, 0x4706f0af, 0x45404ef6, 0x448224c1,
+  0x41cd3244, 0x400f5873, 0x4249e62a, 0x438b8c1d,
+  0x54f16850, 0x55330267, 0x5775bc3e, 0x56b7d609,
+  0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5,
+  0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1,
+  0x5deb9134, 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d,
+  0xe1351b80, 0xe0f771b7, 0xe2b1cfee, 0xe373a5d9,
+  0xe63cb35c, 0xe7fed96b, 0xe5b86732, 0xe47a0d05,
+  0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461,
+  0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd,
+  0xfd13b8f0, 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9,
+  0xfa1a102c, 0xfbd87a1b, 0xf99ec442, 0xf85cae75,
+  0xf300e948, 0xf2c2837f, 0xf0843d26, 0xf1465711,
+  0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd,
+  0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339,
+  0xde71f5bc, 0xdfb39f8b, 0xddf521d2, 0xdc374be5,
+  0xd76b0cd8, 0xd6a966ef, 0xd4efd8b6, 0xd52db281,
+  0xd062a404, 0xd1a0ce33, 0xd3e6706a, 0xd2241a5d,
+  0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049,
+  0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895,
+  0xcb4dafa8, 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1,
+  0xcc440774, 0xcd866d43, 0xcfc0d31a, 0xce02b92d,
+  0x91af9640, 0x906dfc77, 0x922b422e, 0x93e92819,
+  0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5,
+  0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1,
+  0x98b56f24, 0x99770513, 0x9b31bb4a, 0x9af3d17d,
+  0x8d893530, 0x8c4b5f07, 0x8e0de15e, 0x8fcf8b69,
+  0x8a809dec, 0x8b42f7db, 0x89044982, 0x88c623b5,
+  0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1,
+  0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d,
+  0xa9e2d0a0, 0xa820ba97, 0xaa6604ce, 0xaba46ef9,
+  0xaeeb787c, 0xaf29124b, 0xad6fac12, 0xacadc625,
+  0xa7f18118, 0xa633eb2f, 0xa4755576, 0xa5b73f41,
+  0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d,
+  0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89,
+  0xb2cddb0c, 0xb30fb13b, 0xb1490f62, 0xb08b6555,
+  0xbbd72268, 0xba15485f, 0xb853f606, 0xb9919c31,
+  0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, 0xbe9834ed,
+  0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee,
+  0x8f629757, 0x37def032, 0x256b5fdc, 0x9dd738b9,
+  0xc5b428ef, 0x7d084f8a, 0x6fbde064, 0xd7018701,
+  0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, 0x58631056,
+  0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871,
+  0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26,
+  0x95ad7f70, 0x2d111815, 0x3fa4b7fb, 0x8718d09e,
+  0x1acfe827, 0xa2738f42, 0xb0c620ac, 0x087a47c9,
+  0xa032af3e, 0x188ec85b, 0x0a3b67b5, 0xb28700d0,
+  0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787,
+  0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f,
+  0xeae41086, 0x525877e3, 0x40edd80d, 0xf851bf68,
+  0xf02bf8a1, 0x48979fc4, 0x5a22302a, 0xe29e574f,
+  0x7f496ff6, 0xc7f50893, 0xd540a77d, 0x6dfcc018,
+  0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0,
+  0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7,
+  0x9b14583d, 0x23a83f58, 0x311d90b6, 0x89a1f7d3,
+  0x1476cf6a, 0xaccaa80f, 0xbe7f07e1, 0x06c36084,
+  0x5ea070d2, 0xe61c17b7, 0xf4a9b859, 0x4c15df3c,
+  0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b,
+  0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c,
+  0x446f98f5, 0xfcd3ff90, 0xee66507e, 0x56da371b,
+  0x0eb9274d, 0xb6054028, 0xa4b0efc6, 0x1c0c88a3,
+  0x81dbb01a, 0x3967d77f, 0x2bd27891, 0x936e1ff4,
+  0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed,
+  0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba,
+  0xfe92dfec, 0x462eb889, 0x549b1767, 0xec277002,
+  0x71f048bb, 0xc94c2fde, 0xdbf98030, 0x6345e755,
+  0x6b3fa09c, 0xd383c7f9, 0xc1366817, 0x798a0f72,
+  0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825,
+  0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d,
+  0x21e91f24, 0x99557841, 0x8be0d7af, 0x335cb0ca,
+  0xed59b63b, 0x55e5d15e, 0x47507eb0, 0xffec19d5,
+  0x623b216c, 0xda874609, 0xc832e9e7, 0x708e8e82,
+  0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a,
+  0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d,
+  0xbd40e1a4, 0x05fc86c1, 0x1749292f, 0xaff54e4a,
+  0x322276f3, 0x8a9e1196, 0x982bbe78, 0x2097d91d,
+  0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, 0x6a4166a5,
+  0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2,
+  0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb,
+  0xc2098e52, 0x7ab5e937, 0x680046d9, 0xd0bc21bc,
+  0x88df31ea, 0x3063568f, 0x22d6f961, 0x9a6a9e04,
+  0x07bda6bd, 0xbf01c1d8, 0xadb46e36, 0x15080953,
+  0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174,
+  0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623,
+  0xd8c66675, 0x607a0110, 0x72cfaefe, 0xca73c99b,
+  0x57a4f122, 0xef189647, 0xfdad39a9, 0x45115ecc,
+  0x764dee06, 0xcef18963, 0xdc44268d, 0x64f841e8,
+  0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf,
+  0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907,
+  0x3c9b51be, 0x842736db, 0x96929935, 0x2e2efe50,
+  0x2654b999, 0x9ee8defc, 0x8c5d7112, 0x34e11677,
+  0xa9362ece, 0x118a49ab, 0x033fe645, 0xbb838120,
+  0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98,
+  0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf,
+  0xd67f4138, 0x6ec3265d, 0x7c7689b3, 0xc4caeed6,
+  0x591dd66f, 0xe1a1b10a, 0xf3141ee4, 0x4ba87981,
+  0x13cb69d7, 0xab770eb2, 0xb9c2a15c, 0x017ec639,
+  0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e,
+  0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949,
+  0x090481f0, 0xb1b8e695, 0xa30d497b, 0x1bb12e1e,
+  0x43d23e48, 0xfb6e592d, 0xe9dbf6c3, 0x516791a6,
+  0xccb0a91f, 0x740cce7a, 0x66b96194, 0xde0506f1
+};
+
 /* CRC32 */
 
+static inline u32
+crc32_next (u32 crc, byte data)
+{
+  return (crc >> 8) ^ crc32_table[(crc & 0xff) ^ data];
+}
+
+/*
+ * Process 4 bytes in one go
+ */
+static inline u32
+crc32_next4 (u32 crc, u32 data)
+{
+  crc ^= data;
+  crc = crc32_table[(crc & 0xff) + 0x300] ^
+        crc32_table[((crc >> 8) & 0xff) + 0x200] ^
+        crc32_table[((crc >> 16) & 0xff) + 0x100] ^
+        crc32_table[(crc >> 24) & 0xff];
+  return crc;
+}
+
 static void
 crc32_init (void *context, unsigned int flags)
 {
   CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+#ifdef USE_INTEL_PCLMUL
+  u32 hwf = _gcry_get_hw_features ();
+
+  ctx->use_pclmul = (hwf & HWF_INTEL_SSE4_1) && (hwf & HWF_INTEL_PCLMUL);
+#endif
 
   (void)flags;
 
@@ -159,12 +373,48 @@ crc32_init (void *context, unsigned int flags)
 }
 
 static void
-crc32_write (void *context, const void *inbuf, size_t inlen)
+crc32_write (void *context, const void *inbuf_arg, size_t inlen)
 {
   CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
-  if (!inbuf)
+  const byte *inbuf = inbuf_arg;
+  u32 crc;
+
+#ifdef USE_INTEL_PCLMUL
+  if (ctx->use_pclmul)
+    {
+      _gcry_crc32_intel_pclmul(&ctx->CRC, inbuf, inlen);
+      return;
+    }
+#endif
+
+  if (!inbuf || !inlen)
     return;
-  ctx->CRC = update_crc32 (ctx->CRC, inbuf, inlen);
+
+  crc = ctx->CRC;
+
+  while (inlen >= 16)
+    {
+      inlen -= 16;
+      crc = crc32_next4(crc, buf_get_le32(&inbuf[0]));
+      crc = crc32_next4(crc, buf_get_le32(&inbuf[4]));
+      crc = crc32_next4(crc, buf_get_le32(&inbuf[8]));
+      crc = crc32_next4(crc, buf_get_le32(&inbuf[12]));
+      inbuf += 16;
+    }
+
+  while (inlen >= 4)
+    {
+      inlen -= 4;
+      crc = crc32_next4(crc, buf_get_le32(inbuf));
+      inbuf += 4;
+    }
+
+  while (inlen--)
+    {
+      crc = crc32_next(crc, *inbuf++);
+    }
+
+  ctx->CRC = crc;
 }
 
 static byte *
@@ -179,17 +429,21 @@ crc32_final (void *context)
 {
   CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
   ctx->CRC ^= 0xffffffffL;
-  ctx->buf[0] = (ctx->CRC >> 24) & 0xFF;
-  ctx->buf[1] = (ctx->CRC >> 16) & 0xFF;
-  ctx->buf[2] = (ctx->CRC >>  8) & 0xFF;
-  ctx->buf[3] = (ctx->CRC      ) & 0xFF;
+  buf_put_be32 (ctx->buf, ctx->CRC);
 }
 
 /* CRC32 a'la RFC 1510 */
+/* CRC of the string "123456789" is 0x2dfd2d88 */
+
 static void
 crc32rfc1510_init (void *context, unsigned int flags)
 {
   CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+#ifdef USE_INTEL_PCLMUL
+  u32 hwf = _gcry_get_hw_features ();
+
+  ctx->use_pclmul = (hwf & HWF_INTEL_SSE4_1) && (hwf & HWF_INTEL_PCLMUL);
+#endif
 
   (void)flags;
 
@@ -200,85 +454,383 @@ static void
 crc32rfc1510_final (void *context)
 {
   CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
-  ctx->buf[0] = (ctx->CRC >> 24) & 0xFF;
-  ctx->buf[1] = (ctx->CRC >> 16) & 0xFF;
-  ctx->buf[2] = (ctx->CRC >>  8) & 0xFF;
-  ctx->buf[3] = (ctx->CRC      ) & 0xFF;
+  buf_put_be32(ctx->buf, ctx->CRC);
 }
 
 /* CRC24 a'la RFC 2440 */
 /*
- * The following CRC 24 routines are adapted from RFC 2440, which has
- * the following copyright notice:
- *
- *   Copyright (C) The Internet Society (1998).  All Rights Reserved.
+ * Code generated by universal_crc by Danjel McGougan
  *
- *   This document and translations of it may be copied and furnished
- *   to others, and derivative works that comment on or otherwise
- *   explain it or assist in its implementation may be prepared,
- *   copied, published and distributed, in whole or in part, without
- *   restriction of any kind, provided that the above copyright notice
- *   and this paragraph are included on all such copies and derivative
- *   works.  However, this document itself may not be modified in any
- *   way, such as by removing the copyright notice or references to
- *   the Internet Society or other Internet organizations, except as
- *   needed for the purpose of developing Internet standards in which
- *   case the procedures for copyrights defined in the Internet
- *   Standards process must be followed, or as required to translate
- *   it into languages other than English.
+ * CRC parameters used:
+ *   bits:       24
+ *   poly:       0x864cfb
+ *   init:       0xb704ce
+ *   xor:        0x000000
+ *   reverse:    false
+ *   non-direct: false
  *
- *   The limited permissions granted above are perpetual and will not be
- *   revoked by the Internet Society or its successors or assigns.
- *
- *   This document and the information contained herein is provided on
- *   an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET
- *   ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR
- *   IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE
- *   OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY
- *   IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
- *   PURPOSE.
+ * CRC of the string "123456789" is 0x21cf02
  */
 
-#define CRC24_INIT 0xb704ceL
-#define CRC24_POLY 0x1864cfbL
+static const u32 crc24_table[1024] =
+{
+  0x00000000, 0x00fb4c86, 0x000dd58a, 0x00f6990c,
+  0x00e1e693, 0x001aaa15, 0x00ec3319, 0x00177f9f,
+  0x003981a1, 0x00c2cd27, 0x0034542b, 0x00cf18ad,
+  0x00d86732, 0x00232bb4, 0x00d5b2b8, 0x002efe3e,
+  0x00894ec5, 0x00720243, 0x00849b4f, 0x007fd7c9,
+  0x0068a856, 0x0093e4d0, 0x00657ddc, 0x009e315a,
+  0x00b0cf64, 0x004b83e2, 0x00bd1aee, 0x00465668,
+  0x005129f7, 0x00aa6571, 0x005cfc7d, 0x00a7b0fb,
+  0x00e9d10c, 0x00129d8a, 0x00e40486, 0x001f4800,
+  0x0008379f, 0x00f37b19, 0x0005e215, 0x00feae93,
+  0x00d050ad, 0x002b1c2b, 0x00dd8527, 0x0026c9a1,
+  0x0031b63e, 0x00cafab8, 0x003c63b4, 0x00c72f32,
+  0x00609fc9, 0x009bd34f, 0x006d4a43, 0x009606c5,
+  0x0081795a, 0x007a35dc, 0x008cacd0, 0x0077e056,
+  0x00591e68, 0x00a252ee, 0x0054cbe2, 0x00af8764,
+  0x00b8f8fb, 0x0043b47d, 0x00b52d71, 0x004e61f7,
+  0x00d2a319, 0x0029ef9f, 0x00df7693, 0x00243a15,
+  0x0033458a, 0x00c8090c, 0x003e9000, 0x00c5dc86,
+  0x00eb22b8, 0x00106e3e, 0x00e6f732, 0x001dbbb4,
+  0x000ac42b, 0x00f188ad, 0x000711a1, 0x00fc5d27,
+  0x005beddc, 0x00a0a15a, 0x00563856, 0x00ad74d0,
+  0x00ba0b4f, 0x004147c9, 0x00b7dec5, 0x004c9243,
+  0x00626c7d, 0x009920fb, 0x006fb9f7, 0x0094f571,
+  0x00838aee, 0x0078c668, 0x008e5f64, 0x007513e2,
+  0x003b7215, 0x00c03e93, 0x0036a79f, 0x00cdeb19,
+  0x00da9486, 0x0021d800, 0x00d7410c, 0x002c0d8a,
+  0x0002f3b4, 0x00f9bf32, 0x000f263e, 0x00f46ab8,
+  0x00e31527, 0x001859a1, 0x00eec0ad, 0x00158c2b,
+  0x00b23cd0, 0x00497056, 0x00bfe95a, 0x0044a5dc,
+  0x0053da43, 0x00a896c5, 0x005e0fc9, 0x00a5434f,
+  0x008bbd71, 0x0070f1f7, 0x008668fb, 0x007d247d,
+  0x006a5be2, 0x00911764, 0x00678e68, 0x009cc2ee,
+  0x00a44733, 0x005f0bb5, 0x00a992b9, 0x0052de3f,
+  0x0045a1a0, 0x00beed26, 0x0048742a, 0x00b338ac,
+  0x009dc692, 0x00668a14, 0x00901318, 0x006b5f9e,
+  0x007c2001, 0x00876c87, 0x0071f58b, 0x008ab90d,
+  0x002d09f6, 0x00d64570, 0x0020dc7c, 0x00db90fa,
+  0x00ccef65, 0x0037a3e3, 0x00c13aef, 0x003a7669,
+  0x00148857, 0x00efc4d1, 0x00195ddd, 0x00e2115b,
+  0x00f56ec4, 0x000e2242, 0x00f8bb4e, 0x0003f7c8,
+  0x004d963f, 0x00b6dab9, 0x004043b5, 0x00bb0f33,
+  0x00ac70ac, 0x00573c2a, 0x00a1a526, 0x005ae9a0,
+  0x0074179e, 0x008f5b18, 0x0079c214, 0x00828e92,
+  0x0095f10d, 0x006ebd8b, 0x00982487, 0x00636801,
+  0x00c4d8fa, 0x003f947c, 0x00c90d70, 0x003241f6,
+  0x00253e69, 0x00de72ef, 0x0028ebe3, 0x00d3a765,
+  0x00fd595b, 0x000615dd, 0x00f08cd1, 0x000bc057,
+  0x001cbfc8, 0x00e7f34e, 0x00116a42, 0x00ea26c4,
+  0x0076e42a, 0x008da8ac, 0x007b31a0, 0x00807d26,
+  0x009702b9, 0x006c4e3f, 0x009ad733, 0x00619bb5,
+  0x004f658b, 0x00b4290d, 0x0042b001, 0x00b9fc87,
+  0x00ae8318, 0x0055cf9e, 0x00a35692, 0x00581a14,
+  0x00ffaaef, 0x0004e669, 0x00f27f65, 0x000933e3,
+  0x001e4c7c, 0x00e500fa, 0x001399f6, 0x00e8d570,
+  0x00c62b4e, 0x003d67c8, 0x00cbfec4, 0x0030b242,
+  0x0027cddd, 0x00dc815b, 0x002a1857, 0x00d154d1,
+  0x009f3526, 0x006479a0, 0x0092e0ac, 0x0069ac2a,
+  0x007ed3b5, 0x00859f33, 0x0073063f, 0x00884ab9,
+  0x00a6b487, 0x005df801, 0x00ab610d, 0x00502d8b,
+  0x00475214, 0x00bc1e92, 0x004a879e, 0x00b1cb18,
+  0x00167be3, 0x00ed3765, 0x001bae69, 0x00e0e2ef,
+  0x00f79d70, 0x000cd1f6, 0x00fa48fa, 0x0001047c,
+  0x002ffa42, 0x00d4b6c4, 0x00222fc8, 0x00d9634e,
+  0x00ce1cd1, 0x00355057, 0x00c3c95b, 0x003885dd,
+  0x00000000, 0x00488f66, 0x00901ecd, 0x00d891ab,
+  0x00db711c, 0x0093fe7a, 0x004b6fd1, 0x0003e0b7,
+  0x00b6e338, 0x00fe6c5e, 0x0026fdf5, 0x006e7293,
+  0x006d9224, 0x00251d42, 0x00fd8ce9, 0x00b5038f,
+  0x006cc771, 0x00244817, 0x00fcd9bc, 0x00b456da,
+  0x00b7b66d, 0x00ff390b, 0x0027a8a0, 0x006f27c6,
+  0x00da2449, 0x0092ab2f, 0x004a3a84, 0x0002b5e2,
+  0x00015555, 0x0049da33, 0x00914b98, 0x00d9c4fe,
+  0x00d88ee3, 0x00900185, 0x0048902e, 0x00001f48,
+  0x0003ffff, 0x004b7099, 0x0093e132, 0x00db6e54,
+  0x006e6ddb, 0x0026e2bd, 0x00fe7316, 0x00b6fc70,
+  0x00b51cc7, 0x00fd93a1, 0x0025020a, 0x006d8d6c,
+  0x00b44992, 0x00fcc6f4, 0x0024575f, 0x006cd839,
+  0x006f388e, 0x0027b7e8, 0x00ff2643, 0x00b7a925,
+  0x0002aaaa, 0x004a25cc, 0x0092b467, 0x00da3b01,
+  0x00d9dbb6, 0x009154d0, 0x0049c57b, 0x00014a1d,
+  0x004b5141, 0x0003de27, 0x00db4f8c, 0x0093c0ea,
+  0x0090205d, 0x00d8af3b, 0x00003e90, 0x0048b1f6,
+  0x00fdb279, 0x00b53d1f, 0x006dacb4, 0x002523d2,
+  0x0026c365, 0x006e4c03, 0x00b6dda8, 0x00fe52ce,
+  0x00279630, 0x006f1956, 0x00b788fd, 0x00ff079b,
+  0x00fce72c, 0x00b4684a, 0x006cf9e1, 0x00247687,
+  0x00917508, 0x00d9fa6e, 0x00016bc5, 0x0049e4a3,
+  0x004a0414, 0x00028b72, 0x00da1ad9, 0x009295bf,
+  0x0093dfa2, 0x00db50c4, 0x0003c16f, 0x004b4e09,
+  0x0048aebe, 0x000021d8, 0x00d8b073, 0x00903f15,
+  0x00253c9a, 0x006db3fc, 0x00b52257, 0x00fdad31,
+  0x00fe4d86, 0x00b6c2e0, 0x006e534b, 0x0026dc2d,
+  0x00ff18d3, 0x00b797b5, 0x006f061e, 0x00278978,
+  0x002469cf, 0x006ce6a9, 0x00b47702, 0x00fcf864,
+  0x0049fbeb, 0x0001748d, 0x00d9e526, 0x00916a40,
+  0x00928af7, 0x00da0591, 0x0002943a, 0x004a1b5c,
+  0x0096a282, 0x00de2de4, 0x0006bc4f, 0x004e3329,
+  0x004dd39e, 0x00055cf8, 0x00ddcd53, 0x00954235,
+  0x002041ba, 0x0068cedc, 0x00b05f77, 0x00f8d011,
+  0x00fb30a6, 0x00b3bfc0, 0x006b2e6b, 0x0023a10d,
+  0x00fa65f3, 0x00b2ea95, 0x006a7b3e, 0x0022f458,
+  0x002114ef, 0x00699b89, 0x00b10a22, 0x00f98544,
+  0x004c86cb, 0x000409ad, 0x00dc9806, 0x00941760,
+  0x0097f7d7, 0x00df78b1, 0x0007e91a, 0x004f667c,
+  0x004e2c61, 0x0006a307, 0x00de32ac, 0x0096bdca,
+  0x00955d7d, 0x00ddd21b, 0x000543b0, 0x004dccd6,
+  0x00f8cf59, 0x00b0403f, 0x0068d194, 0x00205ef2,
+  0x0023be45, 0x006b3123, 0x00b3a088, 0x00fb2fee,
+  0x0022eb10, 0x006a6476, 0x00b2f5dd, 0x00fa7abb,
+  0x00f99a0c, 0x00b1156a, 0x006984c1, 0x00210ba7,
+  0x00940828, 0x00dc874e, 0x000416e5, 0x004c9983,
+  0x004f7934, 0x0007f652, 0x00df67f9, 0x0097e89f,
+  0x00ddf3c3, 0x00957ca5, 0x004ded0e, 0x00056268,
+  0x000682df, 0x004e0db9, 0x00969c12, 0x00de1374,
+  0x006b10fb, 0x00239f9d, 0x00fb0e36, 0x00b38150,
+  0x00b061e7, 0x00f8ee81, 0x00207f2a, 0x0068f04c,
+  0x00b134b2, 0x00f9bbd4, 0x00212a7f, 0x0069a519,
+  0x006a45ae, 0x0022cac8, 0x00fa5b63, 0x00b2d405,
+  0x0007d78a, 0x004f58ec, 0x0097c947, 0x00df4621,
+  0x00dca696, 0x009429f0, 0x004cb85b, 0x0004373d,
+  0x00057d20, 0x004df246, 0x009563ed, 0x00ddec8b,
+  0x00de0c3c, 0x0096835a, 0x004e12f1, 0x00069d97,
+  0x00b39e18, 0x00fb117e, 0x002380d5, 0x006b0fb3,
+  0x0068ef04, 0x00206062, 0x00f8f1c9, 0x00b07eaf,
+  0x0069ba51, 0x00213537, 0x00f9a49c, 0x00b12bfa,
+  0x00b2cb4d, 0x00fa442b, 0x0022d580, 0x006a5ae6,
+  0x00df5969, 0x0097d60f, 0x004f47a4, 0x0007c8c2,
+  0x00042875, 0x004ca713, 0x009436b8, 0x00dcb9de,
+  0x00000000, 0x00d70983, 0x00555f80, 0x00825603,
+  0x0051f286, 0x0086fb05, 0x0004ad06, 0x00d3a485,
+  0x0059a88b, 0x008ea108, 0x000cf70b, 0x00dbfe88,
+  0x00085a0d, 0x00df538e, 0x005d058d, 0x008a0c0e,
+  0x00491c91, 0x009e1512, 0x001c4311, 0x00cb4a92,
+  0x0018ee17, 0x00cfe794, 0x004db197, 0x009ab814,
+  0x0010b41a, 0x00c7bd99, 0x0045eb9a, 0x0092e219,
+  0x0041469c, 0x00964f1f, 0x0014191c, 0x00c3109f,
+  0x006974a4, 0x00be7d27, 0x003c2b24, 0x00eb22a7,
+  0x00388622, 0x00ef8fa1, 0x006dd9a2, 0x00bad021,
+  0x0030dc2f, 0x00e7d5ac, 0x006583af, 0x00b28a2c,
+  0x00612ea9, 0x00b6272a, 0x00347129, 0x00e378aa,
+  0x00206835, 0x00f761b6, 0x007537b5, 0x00a23e36,
+  0x00719ab3, 0x00a69330, 0x0024c533, 0x00f3ccb0,
+  0x0079c0be, 0x00aec93d, 0x002c9f3e, 0x00fb96bd,
+  0x00283238, 0x00ff3bbb, 0x007d6db8, 0x00aa643b,
+  0x0029a4ce, 0x00fead4d, 0x007cfb4e, 0x00abf2cd,
+  0x00785648, 0x00af5fcb, 0x002d09c8, 0x00fa004b,
+  0x00700c45, 0x00a705c6, 0x002553c5, 0x00f25a46,
+  0x0021fec3, 0x00f6f740, 0x0074a143, 0x00a3a8c0,
+  0x0060b85f, 0x00b7b1dc, 0x0035e7df, 0x00e2ee5c,
+  0x00314ad9, 0x00e6435a, 0x00641559, 0x00b31cda,
+  0x003910d4, 0x00ee1957, 0x006c4f54, 0x00bb46d7,
+  0x0068e252, 0x00bfebd1, 0x003dbdd2, 0x00eab451,
+  0x0040d06a, 0x0097d9e9, 0x00158fea, 0x00c28669,
+  0x001122ec, 0x00c62b6f, 0x00447d6c, 0x009374ef,
+  0x001978e1, 0x00ce7162, 0x004c2761, 0x009b2ee2,
+  0x00488a67, 0x009f83e4, 0x001dd5e7, 0x00cadc64,
+  0x0009ccfb, 0x00dec578, 0x005c937b, 0x008b9af8,
+  0x00583e7d, 0x008f37fe, 0x000d61fd, 0x00da687e,
+  0x00506470, 0x00876df3, 0x00053bf0, 0x00d23273,
+  0x000196f6, 0x00d69f75, 0x0054c976, 0x0083c0f5,
+  0x00a9041b, 0x007e0d98, 0x00fc5b9b, 0x002b5218,
+  0x00f8f69d, 0x002fff1e, 0x00ada91d, 0x007aa09e,
+  0x00f0ac90, 0x0027a513, 0x00a5f310, 0x0072fa93,
+  0x00a15e16, 0x00765795, 0x00f40196, 0x00230815,
+  0x00e0188a, 0x00371109, 0x00b5470a, 0x00624e89,
+  0x00b1ea0c, 0x0066e38f, 0x00e4b58c, 0x0033bc0f,
+  0x00b9b001, 0x006eb982, 0x00ecef81, 0x003be602,
+  0x00e84287, 0x003f4b04, 0x00bd1d07, 0x006a1484,
+  0x00c070bf, 0x0017793c, 0x00952f3f, 0x004226bc,
+  0x00918239, 0x00468bba, 0x00c4ddb9, 0x0013d43a,
+  0x0099d834, 0x004ed1b7, 0x00cc87b4, 0x001b8e37,
+  0x00c82ab2, 0x001f2331, 0x009d7532, 0x004a7cb1,
+  0x00896c2e, 0x005e65ad, 0x00dc33ae, 0x000b3a2d,
+  0x00d89ea8, 0x000f972b, 0x008dc128, 0x005ac8ab,
+  0x00d0c4a5, 0x0007cd26, 0x00859b25, 0x005292a6,
+  0x00813623, 0x00563fa0, 0x00d469a3, 0x00036020,
+  0x0080a0d5, 0x0057a956, 0x00d5ff55, 0x0002f6d6,
+  0x00d15253, 0x00065bd0, 0x00840dd3, 0x00530450,
+  0x00d9085e, 0x000e01dd, 0x008c57de, 0x005b5e5d,
+  0x0088fad8, 0x005ff35b, 0x00dda558, 0x000aacdb,
+  0x00c9bc44, 0x001eb5c7, 0x009ce3c4, 0x004bea47,
+  0x00984ec2, 0x004f4741, 0x00cd1142, 0x001a18c1,
+  0x009014cf, 0x00471d4c, 0x00c54b4f, 0x001242cc,
+  0x00c1e649, 0x0016efca, 0x0094b9c9, 0x0043b04a,
+  0x00e9d471, 0x003eddf2, 0x00bc8bf1, 0x006b8272,
+  0x00b826f7, 0x006f2f74, 0x00ed7977, 0x003a70f4,
+  0x00b07cfa, 0x00677579, 0x00e5237a, 0x00322af9,
+  0x00e18e7c, 0x003687ff, 0x00b4d1fc, 0x0063d87f,
+  0x00a0c8e0, 0x0077c163, 0x00f59760, 0x00229ee3,
+  0x00f13a66, 0x002633e5, 0x00a465e6, 0x00736c65,
+  0x00f9606b, 0x002e69e8, 0x00ac3feb, 0x007b3668,
+  0x00a892ed, 0x007f9b6e, 0x00fdcd6d, 0x002ac4ee,
+  0x00000000, 0x00520936, 0x00a4126c, 0x00f61b5a,
+  0x004825d8, 0x001a2cee, 0x00ec37b4, 0x00be3e82,
+  0x006b0636, 0x00390f00, 0x00cf145a, 0x009d1d6c,
+  0x002323ee, 0x00712ad8, 0x00873182, 0x00d538b4,
+  0x00d60c6c, 0x0084055a, 0x00721e00, 0x00201736,
+  0x009e29b4, 0x00cc2082, 0x003a3bd8, 0x006832ee,
+  0x00bd0a5a, 0x00ef036c, 0x00191836, 0x004b1100,
+  0x00f52f82, 0x00a726b4, 0x00513dee, 0x000334d8,
+  0x00ac19d8, 0x00fe10ee, 0x00080bb4, 0x005a0282,
+  0x00e43c00, 0x00b63536, 0x00402e6c, 0x0012275a,
+  0x00c71fee, 0x009516d8, 0x00630d82, 0x003104b4,
+  0x008f3a36, 0x00dd3300, 0x002b285a, 0x0079216c,
+  0x007a15b4, 0x00281c82, 0x00de07d8, 0x008c0eee,
+  0x0032306c, 0x0060395a, 0x00962200, 0x00c42b36,
+  0x00111382, 0x00431ab4, 0x00b501ee, 0x00e708d8,
+  0x0059365a, 0x000b3f6c, 0x00fd2436, 0x00af2d00,
+  0x00a37f36, 0x00f17600, 0x00076d5a, 0x0055646c,
+  0x00eb5aee, 0x00b953d8, 0x004f4882, 0x001d41b4,
+  0x00c87900, 0x009a7036, 0x006c6b6c, 0x003e625a,
+  0x00805cd8, 0x00d255ee, 0x00244eb4, 0x00764782,
+  0x0075735a, 0x00277a6c, 0x00d16136, 0x00836800,
+  0x003d5682, 0x006f5fb4, 0x009944ee, 0x00cb4dd8,
+  0x001e756c, 0x004c7c5a, 0x00ba6700, 0x00e86e36,
+  0x005650b4, 0x00045982, 0x00f242d8, 0x00a04bee,
+  0x000f66ee, 0x005d6fd8, 0x00ab7482, 0x00f97db4,
+  0x00474336, 0x00154a00, 0x00e3515a, 0x00b1586c,
+  0x006460d8, 0x003669ee, 0x00c072b4, 0x00927b82,
+  0x002c4500, 0x007e4c36, 0x0088576c, 0x00da5e5a,
+  0x00d96a82, 0x008b63b4, 0x007d78ee, 0x002f71d8,
+  0x00914f5a, 0x00c3466c, 0x00355d36, 0x00675400,
+  0x00b26cb4, 0x00e06582, 0x00167ed8, 0x004477ee,
+  0x00fa496c, 0x00a8405a, 0x005e5b00, 0x000c5236,
+  0x0046ff6c, 0x0014f65a, 0x00e2ed00, 0x00b0e436,
+  0x000edab4, 0x005cd382, 0x00aac8d8, 0x00f8c1ee,
+  0x002df95a, 0x007ff06c, 0x0089eb36, 0x00dbe200,
+  0x0065dc82, 0x0037d5b4, 0x00c1ceee, 0x0093c7d8,
+  0x0090f300, 0x00c2fa36, 0x0034e16c, 0x0066e85a,
+  0x00d8d6d8, 0x008adfee, 0x007cc4b4, 0x002ecd82,
+  0x00fbf536, 0x00a9fc00, 0x005fe75a, 0x000dee6c,
+  0x00b3d0ee, 0x00e1d9d8, 0x0017c282, 0x0045cbb4,
+  0x00eae6b4, 0x00b8ef82, 0x004ef4d8, 0x001cfdee,
+  0x00a2c36c, 0x00f0ca5a, 0x0006d100, 0x0054d836,
+  0x0081e082, 0x00d3e9b4, 0x0025f2ee, 0x0077fbd8,
+  0x00c9c55a, 0x009bcc6c, 0x006dd736, 0x003fde00,
+  0x003cead8, 0x006ee3ee, 0x0098f8b4, 0x00caf182,
+  0x0074cf00, 0x0026c636, 0x00d0dd6c, 0x0082d45a,
+  0x0057ecee, 0x0005e5d8, 0x00f3fe82, 0x00a1f7b4,
+  0x001fc936, 0x004dc000, 0x00bbdb5a, 0x00e9d26c,
+  0x00e5805a, 0x00b7896c, 0x00419236, 0x00139b00,
+  0x00ada582, 0x00ffacb4, 0x0009b7ee, 0x005bbed8,
+  0x008e866c, 0x00dc8f5a, 0x002a9400, 0x00789d36,
+  0x00c6a3b4, 0x0094aa82, 0x0062b1d8, 0x0030b8ee,
+  0x00338c36, 0x00618500, 0x00979e5a, 0x00c5976c,
+  0x007ba9ee, 0x0029a0d8, 0x00dfbb82, 0x008db2b4,
+  0x00588a00, 0x000a8336, 0x00fc986c, 0x00ae915a,
+  0x0010afd8, 0x0042a6ee, 0x00b4bdb4, 0x00e6b482,
+  0x00499982, 0x001b90b4, 0x00ed8bee, 0x00bf82d8,
+  0x0001bc5a, 0x0053b56c, 0x00a5ae36, 0x00f7a700,
+  0x00229fb4, 0x00709682, 0x00868dd8, 0x00d484ee,
+  0x006aba6c, 0x0038b35a, 0x00cea800, 0x009ca136,
+  0x009f95ee, 0x00cd9cd8, 0x003b8782, 0x00698eb4,
+  0x00d7b036, 0x0085b900, 0x0073a25a, 0x0021ab6c,
+  0x00f493d8, 0x00a69aee, 0x005081b4, 0x00028882,
+  0x00bcb600, 0x00eebf36, 0x0018a46c, 0x004aad5a
+};
+
+static inline
+u32 crc24_init (void)
+{
+  /* Transformed to 32-bit CRC by multiplied by x⁸ and then byte swapped. */
+  return 0xce04b7; /* _gcry_bswap(0xb704ce << 8) */
+}
+
+static inline
+u32 crc24_next (u32 crc, byte data)
+{
+  return (crc >> 8) ^ crc24_table[(crc & 0xff) ^ data];
+}
+
+/*
+ * Process 4 bytes in one go
+ */
+static inline
+u32 crc24_next4 (u32 crc, u32 data)
+{
+  crc ^= data;
+  crc = crc24_table[(crc & 0xff) + 0x300] ^
+        crc24_table[((crc >> 8) & 0xff) + 0x200] ^
+        crc24_table[((crc >> 16) & 0xff) + 0x100] ^
+        crc24_table[(data >> 24) & 0xff];
+  return crc;
+}
+
+static inline
+u32 crc24_final (u32 crc)
+{
+  return crc & 0xffffff;
+}
 
 static void
 crc24rfc2440_init (void *context, unsigned int flags)
 {
   CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+#ifdef USE_INTEL_PCLMUL
+  u32 hwf = _gcry_get_hw_features ();
+
+  ctx->use_pclmul = (hwf & HWF_INTEL_SSE4_1) && (hwf & HWF_INTEL_PCLMUL);
+#endif
 
   (void)flags;
 
-  ctx->CRC = CRC24_INIT;
+  ctx->CRC = crc24_init();
 }
 
 static void
 crc24rfc2440_write (void *context, const void *inbuf_arg, size_t inlen)
 {
   const unsigned char *inbuf = inbuf_arg;
-  int i;
   CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+  u32 crc;
+
+#ifdef USE_INTEL_PCLMUL
+  if (ctx->use_pclmul)
+    {
+      _gcry_crc24rfc2440_intel_pclmul(&ctx->CRC, inbuf, inlen);
+      return;
+    }
+#endif
 
-  if (!inbuf)
+  if (!inbuf || !inlen)
     return;
 
-  while (inlen--) {
-    ctx->CRC ^= (*inbuf++) << 16;
-    for (i = 0; i < 8; i++) {
-      ctx->CRC <<= 1;
-      if (ctx->CRC & 0x1000000)
-       ctx->CRC ^= CRC24_POLY;
+  crc = ctx->CRC;
+
+  while (inlen >= 16)
+    {
+      inlen -= 16;
+      crc = crc24_next4(crc, buf_get_le32(&inbuf[0]));
+      crc = crc24_next4(crc, buf_get_le32(&inbuf[4]));
+      crc = crc24_next4(crc, buf_get_le32(&inbuf[8]));
+      crc = crc24_next4(crc, buf_get_le32(&inbuf[12]));
+      inbuf += 16;
     }
-  }
+
+  while (inlen >= 4)
+    {
+      inlen -= 4;
+      crc = crc24_next4(crc, buf_get_le32(inbuf));
+      inbuf += 4;
+    }
+
+  while (inlen--)
+    {
+      crc = crc24_next(crc, *inbuf++);
+    }
+
+  ctx->CRC = crc;
 }
 
 static void
 crc24rfc2440_final (void *context)
 {
   CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
-  ctx->buf[0] = (ctx->CRC >> 16) & 0xFF;
-  ctx->buf[1] = (ctx->CRC >>  8) & 0xFF;
-  ctx->buf[2] = (ctx->CRC      ) & 0xFF;
+  ctx->CRC = crc24_final(ctx->CRC);
+  buf_put_le32 (ctx->buf, ctx->CRC);
 }
 
 /* We allow the CRC algorithms even in FIPS mode because they are
@@ -288,7 +840,7 @@ gcry_md_spec_t _gcry_digest_spec_crc32 =
   {
     GCRY_MD_CRC32, {0, 1},
     "CRC32", NULL, 0, NULL, 4,
-    crc32_init, crc32_write, crc32_final, crc32_read,
+    crc32_init, crc32_write, crc32_final, crc32_read, NULL,
     sizeof (CRC_CONTEXT)
   };
 
@@ -296,8 +848,7 @@ gcry_md_spec_t _gcry_digest_spec_crc32_rfc1510 =
   {
     GCRY_MD_CRC32_RFC1510, {0, 1},
     "CRC32RFC1510", NULL, 0, NULL, 4,
-    crc32rfc1510_init, crc32_write,
-    crc32rfc1510_final, crc32_read,
+    crc32rfc1510_init, crc32_write, crc32rfc1510_final, crc32_read, NULL,
     sizeof (CRC_CONTEXT)
   };
 
@@ -305,7 +856,6 @@ gcry_md_spec_t _gcry_digest_spec_crc24_rfc2440 =
   {
     GCRY_MD_CRC24_RFC2440, {0, 1},
     "CRC24RFC2440", NULL, 0, NULL, 3,
-    crc24rfc2440_init, crc24rfc2440_write,
-    crc24rfc2440_final, crc32_read,
+    crc24rfc2440_init, crc24rfc2440_write, crc24rfc2440_final, crc32_read, NULL,
     sizeof (CRC_CONTEXT)
   };
diff --git a/cipher/des-amd64.S b/cipher/des-amd64.S
new file mode 100644 (file)
index 0000000..307d211
--- /dev/null
@@ -0,0 +1,1037 @@
+/* des-amd64.S  -  AMD64 assembly implementation of 3DES cipher
+ *
+ * Copyright (C) 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef __x86_64
+#include <config.h>
+#if defined(USE_DES) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+    defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+
+#ifdef __PIC__
+#  define RIP (%rip)
+#else
+#  define RIP
+#endif
+
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
+
+.text
+
+#define s1 0
+#define s2 ((s1) + (64*8))
+#define s3 ((s2) + (64*8))
+#define s4 ((s3) + (64*8))
+#define s5 ((s4) + (64*8))
+#define s6 ((s5) + (64*8))
+#define s7 ((s6) + (64*8))
+#define s8 ((s7) + (64*8))
+
+/* register macros */
+#define CTX %rdi
+#define SBOXES %rbp
+
+#define RL0 %r8
+#define RL1 %r9
+#define RL2 %r10
+
+#define RL0d %r8d
+#define RL1d %r9d
+#define RL2d %r10d
+
+#define RR0 %r11
+#define RR1 %r12
+#define RR2 %r13
+
+#define RR0d %r11d
+#define RR1d %r12d
+#define RR2d %r13d
+
+#define RW0 %rax
+#define RW1 %rbx
+#define RW2 %rcx
+
+#define RW0d %eax
+#define RW1d %ebx
+#define RW2d %ecx
+
+#define RW0bl %al
+#define RW1bl %bl
+#define RW2bl %cl
+
+#define RW0bh %ah
+#define RW1bh %bh
+#define RW2bh %ch
+
+#define RT0 %r15
+#define RT1 %rsi
+#define RT2 %r14
+#define RT3 %rdx
+
+#define RT0d %r15d
+#define RT1d %esi
+#define RT2d %r14d
+#define RT3d %edx
+
+/***********************************************************************
+ * 1-way 3DES
+ ***********************************************************************/
+#define do_permutation(a, b, offset, mask) \
+       movl a, RT0d; \
+       shrl $(offset), RT0d; \
+       xorl b, RT0d; \
+       andl $(mask), RT0d; \
+       xorl RT0d, b; \
+       shll $(offset), RT0d; \
+       xorl RT0d, a;
+
+#define expand_to_64bits(val, mask) \
+       movl val##d, RT0d; \
+       rorl $4, RT0d; \
+       shlq $32, RT0; \
+       orq RT0, val; \
+       andq mask, val;
+
+#define compress_to_64bits(val) \
+       movq val, RT0; \
+       shrq $32, RT0; \
+       roll $4, RT0d; \
+       orl RT0d, val##d;
+
+#define initial_permutation(left, right) \
+       do_permutation(left##d, right##d,  4, 0x0f0f0f0f); \
+       do_permutation(left##d, right##d, 16, 0x0000ffff); \
+       do_permutation(right##d, left##d,  2, 0x33333333); \
+       do_permutation(right##d, left##d,  8, 0x00ff00ff); \
+       movabs $0x3f3f3f3f3f3f3f3f, RT3; \
+       movl left##d, RW0d; \
+       roll $1, right##d; \
+       xorl right##d, RW0d; \
+       andl $0xaaaaaaaa, RW0d; \
+       xorl RW0d, left##d; \
+       xorl RW0d, right##d; \
+       roll $1, left##d; \
+       expand_to_64bits(right, RT3); \
+       expand_to_64bits(left, RT3);
+
+#define final_permutation(left, right) \
+       compress_to_64bits(right); \
+       compress_to_64bits(left); \
+       movl right##d, RW0d; \
+       rorl $1, left##d; \
+       xorl left##d, RW0d; \
+       andl $0xaaaaaaaa, RW0d; \
+       xorl RW0d, right##d; \
+       xorl RW0d, left##d; \
+       rorl $1, right##d; \
+       do_permutation(right##d, left##d,  8, 0x00ff00ff); \
+       do_permutation(right##d, left##d,  2, 0x33333333); \
+       do_permutation(left##d, right##d, 16, 0x0000ffff); \
+       do_permutation(left##d, right##d,  4, 0x0f0f0f0f);
+
+#define round1(n, from, to, load_next_key) \
+       xorq from, RW0; \
+       \
+       movzbl RW0bl, RT0d; \
+       movzbl RW0bh, RT1d; \
+       shrq $16, RW0; \
+       movzbl RW0bl, RT2d; \
+       movzbl RW0bh, RT3d; \
+       shrq $16, RW0; \
+       movq s8(SBOXES, RT0, 8), RT0; \
+       xorq s6(SBOXES, RT1, 8), to; \
+       movzbl RW0bl, RL1d; \
+       movzbl RW0bh, RT1d; \
+       shrl $16, RW0d; \
+       xorq s4(SBOXES, RT2, 8), RT0; \
+       xorq s2(SBOXES, RT3, 8), to; \
+       movzbl RW0bl, RT2d; \
+       movzbl RW0bh, RT3d; \
+       xorq s7(SBOXES, RL1, 8), RT0; \
+       xorq s5(SBOXES, RT1, 8), to; \
+       xorq s3(SBOXES, RT2, 8), RT0; \
+       load_next_key(n, RW0); \
+       xorq RT0, to; \
+       xorq s1(SBOXES, RT3, 8), to; \
+
+#define load_next_key(n, RWx) \
+       movq (((n) + 1) * 8)(CTX), RWx;
+
+#define dummy2(a, b) /*_*/
+
+#define read_block(io, left, right) \
+       movl    (io), left##d; \
+       movl   4(io), right##d; \
+       bswapl left##d; \
+       bswapl right##d;
+
+#define write_block(io, left, right) \
+       bswapl left##d; \
+       bswapl right##d; \
+       movl   left##d,   (io); \
+       movl   right##d, 4(io);
+
+.align 8
+.globl _gcry_3des_amd64_crypt_block
+ELF(.type  _gcry_3des_amd64_crypt_block,@function;)
+
+_gcry_3des_amd64_crypt_block:
+       /* input:
+        *      %rdi: round keys, CTX
+        *      %rsi: dst
+        *      %rdx: src
+        */
+       pushq %rbp;
+       pushq %rbx;
+       pushq %r12;
+       pushq %r13;
+       pushq %r14;
+       pushq %r15;
+       pushq %rsi; /*dst*/
+
+       leaq .L_s1 RIP, SBOXES;
+
+       read_block(%rdx, RL0, RR0);
+       initial_permutation(RL0, RR0);
+
+       movq (CTX), RW0;
+
+       round1(0, RR0, RL0, load_next_key);
+       round1(1, RL0, RR0, load_next_key);
+       round1(2, RR0, RL0, load_next_key);
+       round1(3, RL0, RR0, load_next_key);
+       round1(4, RR0, RL0, load_next_key);
+       round1(5, RL0, RR0, load_next_key);
+       round1(6, RR0, RL0, load_next_key);
+       round1(7, RL0, RR0, load_next_key);
+       round1(8, RR0, RL0, load_next_key);
+       round1(9, RL0, RR0, load_next_key);
+       round1(10, RR0, RL0, load_next_key);
+       round1(11, RL0, RR0, load_next_key);
+       round1(12, RR0, RL0, load_next_key);
+       round1(13, RL0, RR0, load_next_key);
+       round1(14, RR0, RL0, load_next_key);
+       round1(15, RL0, RR0, load_next_key);
+
+       round1(16+0, RL0, RR0, load_next_key);
+       round1(16+1, RR0, RL0, load_next_key);
+       round1(16+2, RL0, RR0, load_next_key);
+       round1(16+3, RR0, RL0, load_next_key);
+       round1(16+4, RL0, RR0, load_next_key);
+       round1(16+5, RR0, RL0, load_next_key);
+       round1(16+6, RL0, RR0, load_next_key);
+       round1(16+7, RR0, RL0, load_next_key);
+       round1(16+8, RL0, RR0, load_next_key);
+       round1(16+9, RR0, RL0, load_next_key);
+       round1(16+10, RL0, RR0, load_next_key);
+       round1(16+11, RR0, RL0, load_next_key);
+       round1(16+12, RL0, RR0, load_next_key);
+       round1(16+13, RR0, RL0, load_next_key);
+       round1(16+14, RL0, RR0, load_next_key);
+       round1(16+15, RR0, RL0, load_next_key);
+
+       round1(32+0, RR0, RL0, load_next_key);
+       round1(32+1, RL0, RR0, load_next_key);
+       round1(32+2, RR0, RL0, load_next_key);
+       round1(32+3, RL0, RR0, load_next_key);
+       round1(32+4, RR0, RL0, load_next_key);
+       round1(32+5, RL0, RR0, load_next_key);
+       round1(32+6, RR0, RL0, load_next_key);
+       round1(32+7, RL0, RR0, load_next_key);
+       round1(32+8, RR0, RL0, load_next_key);
+       round1(32+9, RL0, RR0, load_next_key);
+       round1(32+10, RR0, RL0, load_next_key);
+       round1(32+11, RL0, RR0, load_next_key);
+       round1(32+12, RR0, RL0, load_next_key);
+       round1(32+13, RL0, RR0, load_next_key);
+       round1(32+14, RR0, RL0, load_next_key);
+       round1(32+15, RL0, RR0, dummy2);
+
+       popq RW2; /*dst*/
+       final_permutation(RR0, RL0);
+       write_block(RW2, RR0, RL0);
+
+       popq %r15;
+       popq %r14;
+       popq %r13;
+       popq %r12;
+       popq %rbx;
+       popq %rbp;
+
+       ret;
+ELF(.size _gcry_3des_amd64_crypt_block,.-_gcry_3des_amd64_crypt_block;)
+
+/***********************************************************************
+ * 3-way 3DES
+ ***********************************************************************/
+#define expand_to_64bits(val, mask) \
+       movl val##d, RT0d; \
+       rorl $4, RT0d; \
+       shlq $32, RT0; \
+       orq RT0, val; \
+       andq mask, val;
+
+#define compress_to_64bits(val) \
+       movq val, RT0; \
+       shrq $32, RT0; \
+       roll $4, RT0d; \
+       orl RT0d, val##d;
+
+#define initial_permutation3(left, right) \
+       do_permutation(left##0d, right##0d,  4, 0x0f0f0f0f); \
+       do_permutation(left##0d, right##0d, 16, 0x0000ffff); \
+         do_permutation(left##1d, right##1d,  4, 0x0f0f0f0f); \
+         do_permutation(left##1d, right##1d, 16, 0x0000ffff); \
+           do_permutation(left##2d, right##2d,  4, 0x0f0f0f0f); \
+           do_permutation(left##2d, right##2d, 16, 0x0000ffff); \
+           \
+       do_permutation(right##0d, left##0d,  2, 0x33333333); \
+       do_permutation(right##0d, left##0d,  8, 0x00ff00ff); \
+         do_permutation(right##1d, left##1d,  2, 0x33333333); \
+         do_permutation(right##1d, left##1d,  8, 0x00ff00ff); \
+           do_permutation(right##2d, left##2d,  2, 0x33333333); \
+           do_permutation(right##2d, left##2d,  8, 0x00ff00ff); \
+           \
+       movabs $0x3f3f3f3f3f3f3f3f, RT3; \
+           \
+       movl left##0d, RW0d; \
+       roll $1, right##0d; \
+       xorl right##0d, RW0d; \
+       andl $0xaaaaaaaa, RW0d; \
+       xorl RW0d, left##0d; \
+       xorl RW0d, right##0d; \
+       roll $1, left##0d; \
+       expand_to_64bits(right##0, RT3); \
+       expand_to_64bits(left##0, RT3); \
+         movl left##1d, RW1d; \
+         roll $1, right##1d; \
+         xorl right##1d, RW1d; \
+         andl $0xaaaaaaaa, RW1d; \
+         xorl RW1d, left##1d; \
+         xorl RW1d, right##1d; \
+         roll $1, left##1d; \
+         expand_to_64bits(right##1, RT3); \
+         expand_to_64bits(left##1, RT3); \
+           movl left##2d, RW2d; \
+           roll $1, right##2d; \
+           xorl right##2d, RW2d; \
+           andl $0xaaaaaaaa, RW2d; \
+           xorl RW2d, left##2d; \
+           xorl RW2d, right##2d; \
+           roll $1, left##2d; \
+           expand_to_64bits(right##2, RT3); \
+           expand_to_64bits(left##2, RT3);
+
+#define final_permutation3(left, right) \
+       compress_to_64bits(right##0); \
+       compress_to_64bits(left##0); \
+       movl right##0d, RW0d; \
+       rorl $1, left##0d; \
+       xorl left##0d, RW0d; \
+       andl $0xaaaaaaaa, RW0d; \
+       xorl RW0d, right##0d; \
+       xorl RW0d, left##0d; \
+       rorl $1, right##0d; \
+         compress_to_64bits(right##1); \
+         compress_to_64bits(left##1); \
+         movl right##1d, RW1d; \
+         rorl $1, left##1d; \
+         xorl left##1d, RW1d; \
+         andl $0xaaaaaaaa, RW1d; \
+         xorl RW1d, right##1d; \
+         xorl RW1d, left##1d; \
+         rorl $1, right##1d; \
+           compress_to_64bits(right##2); \
+           compress_to_64bits(left##2); \
+           movl right##2d, RW2d; \
+           rorl $1, left##2d; \
+           xorl left##2d, RW2d; \
+           andl $0xaaaaaaaa, RW2d; \
+           xorl RW2d, right##2d; \
+           xorl RW2d, left##2d; \
+           rorl $1, right##2d; \
+           \
+       do_permutation(right##0d, left##0d,  8, 0x00ff00ff); \
+       do_permutation(right##0d, left##0d,  2, 0x33333333); \
+         do_permutation(right##1d, left##1d,  8, 0x00ff00ff); \
+         do_permutation(right##1d, left##1d,  2, 0x33333333); \
+           do_permutation(right##2d, left##2d,  8, 0x00ff00ff); \
+           do_permutation(right##2d, left##2d,  2, 0x33333333); \
+           \
+       do_permutation(left##0d, right##0d, 16, 0x0000ffff); \
+       do_permutation(left##0d, right##0d,  4, 0x0f0f0f0f); \
+         do_permutation(left##1d, right##1d, 16, 0x0000ffff); \
+         do_permutation(left##1d, right##1d,  4, 0x0f0f0f0f); \
+           do_permutation(left##2d, right##2d, 16, 0x0000ffff); \
+           do_permutation(left##2d, right##2d,  4, 0x0f0f0f0f);
+
+#define round3(n, from, to, load_next_key, do_movq) \
+       xorq from##0, RW0; \
+       movzbl RW0bl, RT3d; \
+       movzbl RW0bh, RT1d; \
+       shrq $16, RW0; \
+       xorq s8(SBOXES, RT3, 8), to##0; \
+       xorq s6(SBOXES, RT1, 8), to##0; \
+       movzbl RW0bl, RT3d; \
+       movzbl RW0bh, RT1d; \
+       shrq $16, RW0; \
+       xorq s4(SBOXES, RT3, 8), to##0; \
+       xorq s2(SBOXES, RT1, 8), to##0; \
+       movzbl RW0bl, RT3d; \
+       movzbl RW0bh, RT1d; \
+       shrl $16, RW0d; \
+       xorq s7(SBOXES, RT3, 8), to##0; \
+       xorq s5(SBOXES, RT1, 8), to##0; \
+       movzbl RW0bl, RT3d; \
+       movzbl RW0bh, RT1d; \
+       load_next_key(n, RW0); \
+       xorq s3(SBOXES, RT3, 8), to##0; \
+       xorq s1(SBOXES, RT1, 8), to##0; \
+               xorq from##1, RW1; \
+               movzbl RW1bl, RT3d; \
+               movzbl RW1bh, RT1d; \
+               shrq $16, RW1; \
+               xorq s8(SBOXES, RT3, 8), to##1; \
+               xorq s6(SBOXES, RT1, 8), to##1; \
+               movzbl RW1bl, RT3d; \
+               movzbl RW1bh, RT1d; \
+               shrq $16, RW1; \
+               xorq s4(SBOXES, RT3, 8), to##1; \
+               xorq s2(SBOXES, RT1, 8), to##1; \
+               movzbl RW1bl, RT3d; \
+               movzbl RW1bh, RT1d; \
+               shrl $16, RW1d; \
+               xorq s7(SBOXES, RT3, 8), to##1; \
+               xorq s5(SBOXES, RT1, 8), to##1; \
+               movzbl RW1bl, RT3d; \
+               movzbl RW1bh, RT1d; \
+               do_movq(RW0, RW1); \
+               xorq s3(SBOXES, RT3, 8), to##1; \
+               xorq s1(SBOXES, RT1, 8), to##1; \
+                       xorq from##2, RW2; \
+                       movzbl RW2bl, RT3d; \
+                       movzbl RW2bh, RT1d; \
+                       shrq $16, RW2; \
+                       xorq s8(SBOXES, RT3, 8), to##2; \
+                       xorq s6(SBOXES, RT1, 8), to##2; \
+                       movzbl RW2bl, RT3d; \
+                       movzbl RW2bh, RT1d; \
+                       shrq $16, RW2; \
+                       xorq s4(SBOXES, RT3, 8), to##2; \
+                       xorq s2(SBOXES, RT1, 8), to##2; \
+                       movzbl RW2bl, RT3d; \
+                       movzbl RW2bh, RT1d; \
+                       shrl $16, RW2d; \
+                       xorq s7(SBOXES, RT3, 8), to##2; \
+                       xorq s5(SBOXES, RT1, 8), to##2; \
+                       movzbl RW2bl, RT3d; \
+                       movzbl RW2bh, RT1d; \
+                       do_movq(RW0, RW2); \
+                       xorq s3(SBOXES, RT3, 8), to##2; \
+                       xorq s1(SBOXES, RT1, 8), to##2;
+
+#define __movq(src, dst) \
+       movq src, dst;
+
+#define read_block(io, left, right) \
+       movl    (io), left##d; \
+       movl   4(io), right##d; \
+       bswapl left##d; \
+       bswapl right##d;
+
+#define write_block(io, left, right) \
+       bswapl left##d; \
+       bswapl right##d; \
+       movl   left##d,   (io); \
+       movl   right##d, 4(io);
+
+.align 8
+ELF(.type  _gcry_3des_amd64_crypt_blk3,@function;)
+_gcry_3des_amd64_crypt_blk3:
+       /* input:
+        *  %rdi: round keys, CTX
+        *  RL0d, RR0d, RL1d, RR1d, RL2d, RR2d: 3 input blocks
+        *  RR0d, RL0d, RR1d, RL1d, RR2d, RL2d: 3 output blocks
+        */
+
+       leaq .L_s1 RIP, SBOXES;
+
+       initial_permutation3(RL, RR);
+
+       movq 0(CTX), RW0;
+       movq RW0, RW1;
+       movq RW0, RW2;
+
+       round3(0, RR, RL, load_next_key, __movq);
+       round3(1, RL, RR, load_next_key, __movq);
+       round3(2, RR, RL, load_next_key, __movq);
+       round3(3, RL, RR, load_next_key, __movq);
+       round3(4, RR, RL, load_next_key, __movq);
+       round3(5, RL, RR, load_next_key, __movq);
+       round3(6, RR, RL, load_next_key, __movq);
+       round3(7, RL, RR, load_next_key, __movq);
+       round3(8, RR, RL, load_next_key, __movq);
+       round3(9, RL, RR, load_next_key, __movq);
+       round3(10, RR, RL, load_next_key, __movq);
+       round3(11, RL, RR, load_next_key, __movq);
+       round3(12, RR, RL, load_next_key, __movq);
+       round3(13, RL, RR, load_next_key, __movq);
+       round3(14, RR, RL, load_next_key, __movq);
+       round3(15, RL, RR, load_next_key, __movq);
+
+       round3(16+0, RL, RR, load_next_key, __movq);
+       round3(16+1, RR, RL, load_next_key, __movq);
+       round3(16+2, RL, RR, load_next_key, __movq);
+       round3(16+3, RR, RL, load_next_key, __movq);
+       round3(16+4, RL, RR, load_next_key, __movq);
+       round3(16+5, RR, RL, load_next_key, __movq);
+       round3(16+6, RL, RR, load_next_key, __movq);
+       round3(16+7, RR, RL, load_next_key, __movq);
+       round3(16+8, RL, RR, load_next_key, __movq);
+       round3(16+9, RR, RL, load_next_key, __movq);
+       round3(16+10, RL, RR, load_next_key, __movq);
+       round3(16+11, RR, RL, load_next_key, __movq);
+       round3(16+12, RL, RR, load_next_key, __movq);
+       round3(16+13, RR, RL, load_next_key, __movq);
+       round3(16+14, RL, RR, load_next_key, __movq);
+       round3(16+15, RR, RL, load_next_key, __movq);
+
+       round3(32+0, RR, RL, load_next_key, __movq);
+       round3(32+1, RL, RR, load_next_key, __movq);
+       round3(32+2, RR, RL, load_next_key, __movq);
+       round3(32+3, RL, RR, load_next_key, __movq);
+       round3(32+4, RR, RL, load_next_key, __movq);
+       round3(32+5, RL, RR, load_next_key, __movq);
+       round3(32+6, RR, RL, load_next_key, __movq);
+       round3(32+7, RL, RR, load_next_key, __movq);
+       round3(32+8, RR, RL, load_next_key, __movq);
+       round3(32+9, RL, RR, load_next_key, __movq);
+       round3(32+10, RR, RL, load_next_key, __movq);
+       round3(32+11, RL, RR, load_next_key, __movq);
+       round3(32+12, RR, RL, load_next_key, __movq);
+       round3(32+13, RL, RR, load_next_key, __movq);
+       round3(32+14, RR, RL, load_next_key, __movq);
+       round3(32+15, RL, RR, dummy2, dummy2);
+
+       final_permutation3(RR, RL);
+
+       ret;
+ELF(.size _gcry_3des_amd64_crypt_blk3,.-_gcry_3des_amd64_crypt_blk3;)
+
+.align 8
+.globl  _gcry_3des_amd64_cbc_dec
+ELF(.type   _gcry_3des_amd64_cbc_dec,@function;)
+_gcry_3des_amd64_cbc_dec:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (3 blocks)
+        *      %rdx: src (3 blocks)
+        *      %rcx: iv (64bit)
+        */
+
+       pushq %rbp;
+       pushq %rbx;
+       pushq %r12;
+       pushq %r13;
+       pushq %r14;
+       pushq %r15;
+
+       pushq %rsi; /*dst*/
+       pushq %rdx; /*src*/
+       pushq %rcx; /*iv*/
+
+       /* load input */
+       movl 0 * 4(%rdx), RL0d;
+       movl 1 * 4(%rdx), RR0d;
+       movl 2 * 4(%rdx), RL1d;
+       movl 3 * 4(%rdx), RR1d;
+       movl 4 * 4(%rdx), RL2d;
+       movl 5 * 4(%rdx), RR2d;
+
+       bswapl RL0d;
+       bswapl RR0d;
+       bswapl RL1d;
+       bswapl RR1d;
+       bswapl RL2d;
+       bswapl RR2d;
+
+       call _gcry_3des_amd64_crypt_blk3;
+
+       popq %rcx; /*iv*/
+       popq %rdx; /*src*/
+       popq %rsi; /*dst*/
+
+       bswapl RR0d;
+       bswapl RL0d;
+       bswapl RR1d;
+       bswapl RL1d;
+       bswapl RR2d;
+       bswapl RL2d;
+
+       movq 2 * 8(%rdx), RT0;
+       xorl 0 * 4(%rcx), RR0d;
+       xorl 1 * 4(%rcx), RL0d;
+       xorl 0 * 4(%rdx), RR1d;
+       xorl 1 * 4(%rdx), RL1d;
+       xorl 2 * 4(%rdx), RR2d;
+       xorl 3 * 4(%rdx), RL2d;
+       movq RT0, (%rcx); /* store new IV */
+
+       movl RR0d, 0 * 4(%rsi);
+       movl RL0d, 1 * 4(%rsi);
+       movl RR1d, 2 * 4(%rsi);
+       movl RL1d, 3 * 4(%rsi);
+       movl RR2d, 4 * 4(%rsi);
+       movl RL2d, 5 * 4(%rsi);
+
+       popq %r15;
+       popq %r14;
+       popq %r13;
+       popq %r12;
+       popq %rbx;
+       popq %rbp;
+
+       ret;
+ELF(.size _gcry_3des_amd64_cbc_dec,.-_gcry_3des_amd64_cbc_dec;)
+
+.align 8
+.globl  _gcry_3des_amd64_ctr_enc
+ELF(.type   _gcry_3des_amd64_ctr_enc,@function;)
+_gcry_3des_amd64_ctr_enc:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (3 blocks)
+        *      %rdx: src (3 blocks)
+        *      %rcx: iv (64bit)
+        */
+
+       pushq %rbp;
+       pushq %rbx;
+       pushq %r12;
+       pushq %r13;
+       pushq %r14;
+       pushq %r15;
+
+       pushq %rsi; /*dst*/
+       pushq %rdx; /*src*/
+       movq %rcx, RW2;
+
+       /* load IV and byteswap */
+       movq (RW2), RT0;
+       bswapq RT0;
+       movq RT0, RR0;
+
+       /* construct IVs */
+       leaq 1(RT0), RR1;
+       leaq 2(RT0), RR2;
+       leaq 3(RT0), RT0;
+       movq RR0, RL0;
+       movq RR1, RL1;
+       movq RR2, RL2;
+       bswapq RT0;
+       shrq $32, RL0;
+       shrq $32, RL1;
+       shrq $32, RL2;
+
+       /* store new IV */
+       movq RT0, (RW2);
+
+       call _gcry_3des_amd64_crypt_blk3;
+
+       popq %rdx; /*src*/
+       popq %rsi; /*dst*/
+
+       bswapl RR0d;
+       bswapl RL0d;
+       bswapl RR1d;
+       bswapl RL1d;
+       bswapl RR2d;
+       bswapl RL2d;
+
+       xorl 0 * 4(%rdx), RR0d;
+       xorl 1 * 4(%rdx), RL0d;
+       xorl 2 * 4(%rdx), RR1d;
+       xorl 3 * 4(%rdx), RL1d;
+       xorl 4 * 4(%rdx), RR2d;
+       xorl 5 * 4(%rdx), RL2d;
+
+       movl RR0d, 0 * 4(%rsi);
+       movl RL0d, 1 * 4(%rsi);
+       movl RR1d, 2 * 4(%rsi);
+       movl RL1d, 3 * 4(%rsi);
+       movl RR2d, 4 * 4(%rsi);
+       movl RL2d, 5 * 4(%rsi);
+
+       popq %r15;
+       popq %r14;
+       popq %r13;
+       popq %r12;
+       popq %rbx;
+       popq %rbp;
+
+       ret;
+ELF(.size _gcry_3des_amd64_cbc_dec,.-_gcry_3des_amd64_cbc_dec;)
+
+.align 8
+.globl  _gcry_3des_amd64_cfb_dec
+ELF(.type   _gcry_3des_amd64_cfb_dec,@function;)
+_gcry_3des_amd64_cfb_dec:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (3 blocks)
+        *      %rdx: src (3 blocks)
+        *      %rcx: iv (64bit)
+        */
+       pushq %rbp;
+       pushq %rbx;
+       pushq %r12;
+       pushq %r13;
+       pushq %r14;
+       pushq %r15;
+
+       pushq %rsi; /*dst*/
+       pushq %rdx; /*src*/
+       movq %rcx, RW2;
+
+       /* Load input */
+       movl 0 * 4(RW2), RL0d;
+       movl 1 * 4(RW2), RR0d;
+       movl 0 * 4(%rdx), RL1d;
+       movl 1 * 4(%rdx), RR1d;
+       movl 2 * 4(%rdx), RL2d;
+       movl 3 * 4(%rdx), RR2d;
+
+       bswapl RL0d;
+       bswapl RR0d;
+       bswapl RL1d;
+       bswapl RR1d;
+       bswapl RL2d;
+       bswapl RR2d;
+
+       /* Update IV */
+       movq 4 * 4(%rdx), RW0;
+       movq RW0, (RW2);
+
+       call _gcry_3des_amd64_crypt_blk3;
+
+       popq %rdx; /*src*/
+       popq %rsi; /*dst*/
+
+       bswapl RR0d;
+       bswapl RL0d;
+       bswapl RR1d;
+       bswapl RL1d;
+       bswapl RR2d;
+       bswapl RL2d;
+
+       xorl 0 * 4(%rdx), RR0d;
+       xorl 1 * 4(%rdx), RL0d;
+       xorl 2 * 4(%rdx), RR1d;
+       xorl 3 * 4(%rdx), RL1d;
+       xorl 4 * 4(%rdx), RR2d;
+       xorl 5 * 4(%rdx), RL2d;
+
+       movl RR0d, 0 * 4(%rsi);
+       movl RL0d, 1 * 4(%rsi);
+       movl RR1d, 2 * 4(%rsi);
+       movl RL1d, 3 * 4(%rsi);
+       movl RR2d, 4 * 4(%rsi);
+       movl RL2d, 5 * 4(%rsi);
+
+       popq %r15;
+       popq %r14;
+       popq %r13;
+       popq %r12;
+       popq %rbx;
+       popq %rbp;
+       ret;
+ELF(.size _gcry_3des_amd64_cfb_dec,.-_gcry_3des_amd64_cfb_dec;)
+
+.data
+.align 16
+.L_s1:
+       .quad 0x0010100001010400, 0x0000000000000000
+       .quad 0x0000100000010000, 0x0010100001010404
+       .quad 0x0010100001010004, 0x0000100000010404
+       .quad 0x0000000000000004, 0x0000100000010000
+       .quad 0x0000000000000400, 0x0010100001010400
+       .quad 0x0010100001010404, 0x0000000000000400
+       .quad 0x0010000001000404, 0x0010100001010004
+       .quad 0x0010000001000000, 0x0000000000000004
+       .quad 0x0000000000000404, 0x0010000001000400
+       .quad 0x0010000001000400, 0x0000100000010400
+       .quad 0x0000100000010400, 0x0010100001010000
+       .quad 0x0010100001010000, 0x0010000001000404
+       .quad 0x0000100000010004, 0x0010000001000004
+       .quad 0x0010000001000004, 0x0000100000010004
+       .quad 0x0000000000000000, 0x0000000000000404
+       .quad 0x0000100000010404, 0x0010000001000000
+       .quad 0x0000100000010000, 0x0010100001010404
+       .quad 0x0000000000000004, 0x0010100001010000
+       .quad 0x0010100001010400, 0x0010000001000000
+       .quad 0x0010000001000000, 0x0000000000000400
+       .quad 0x0010100001010004, 0x0000100000010000
+       .quad 0x0000100000010400, 0x0010000001000004
+       .quad 0x0000000000000400, 0x0000000000000004
+       .quad 0x0010000001000404, 0x0000100000010404
+       .quad 0x0010100001010404, 0x0000100000010004
+       .quad 0x0010100001010000, 0x0010000001000404
+       .quad 0x0010000001000004, 0x0000000000000404
+       .quad 0x0000100000010404, 0x0010100001010400
+       .quad 0x0000000000000404, 0x0010000001000400
+       .quad 0x0010000001000400, 0x0000000000000000
+       .quad 0x0000100000010004, 0x0000100000010400
+       .quad 0x0000000000000000, 0x0010100001010004
+.L_s2:
+       .quad 0x0801080200100020, 0x0800080000000000
+       .quad 0x0000080000000000, 0x0001080200100020
+       .quad 0x0001000000100000, 0x0000000200000020
+       .quad 0x0801000200100020, 0x0800080200000020
+       .quad 0x0800000200000020, 0x0801080200100020
+       .quad 0x0801080000100000, 0x0800000000000000
+       .quad 0x0800080000000000, 0x0001000000100000
+       .quad 0x0000000200000020, 0x0801000200100020
+       .quad 0x0001080000100000, 0x0001000200100020
+       .quad 0x0800080200000020, 0x0000000000000000
+       .quad 0x0800000000000000, 0x0000080000000000
+       .quad 0x0001080200100020, 0x0801000000100000
+       .quad 0x0001000200100020, 0x0800000200000020
+       .quad 0x0000000000000000, 0x0001080000100000
+       .quad 0x0000080200000020, 0x0801080000100000
+       .quad 0x0801000000100000, 0x0000080200000020
+       .quad 0x0000000000000000, 0x0001080200100020
+       .quad 0x0801000200100020, 0x0001000000100000
+       .quad 0x0800080200000020, 0x0801000000100000
+       .quad 0x0801080000100000, 0x0000080000000000
+       .quad 0x0801000000100000, 0x0800080000000000
+       .quad 0x0000000200000020, 0x0801080200100020
+       .quad 0x0001080200100020, 0x0000000200000020
+       .quad 0x0000080000000000, 0x0800000000000000
+       .quad 0x0000080200000020, 0x0801080000100000
+       .quad 0x0001000000100000, 0x0800000200000020
+       .quad 0x0001000200100020, 0x0800080200000020
+       .quad 0x0800000200000020, 0x0001000200100020
+       .quad 0x0001080000100000, 0x0000000000000000
+       .quad 0x0800080000000000, 0x0000080200000020
+       .quad 0x0800000000000000, 0x0801000200100020
+       .quad 0x0801080200100020, 0x0001080000100000
+.L_s3:
+       .quad 0x0000002000000208, 0x0000202008020200
+       .quad 0x0000000000000000, 0x0000200008020008
+       .quad 0x0000002008000200, 0x0000000000000000
+       .quad 0x0000202000020208, 0x0000002008000200
+       .quad 0x0000200000020008, 0x0000000008000008
+       .quad 0x0000000008000008, 0x0000200000020000
+       .quad 0x0000202008020208, 0x0000200000020008
+       .quad 0x0000200008020000, 0x0000002000000208
+       .quad 0x0000000008000000, 0x0000000000000008
+       .quad 0x0000202008020200, 0x0000002000000200
+       .quad 0x0000202000020200, 0x0000200008020000
+       .quad 0x0000200008020008, 0x0000202000020208
+       .quad 0x0000002008000208, 0x0000202000020200
+       .quad 0x0000200000020000, 0x0000002008000208
+       .quad 0x0000000000000008, 0x0000202008020208
+       .quad 0x0000002000000200, 0x0000000008000000
+       .quad 0x0000202008020200, 0x0000000008000000
+       .quad 0x0000200000020008, 0x0000002000000208
+       .quad 0x0000200000020000, 0x0000202008020200
+       .quad 0x0000002008000200, 0x0000000000000000
+       .quad 0x0000002000000200, 0x0000200000020008
+       .quad 0x0000202008020208, 0x0000002008000200
+       .quad 0x0000000008000008, 0x0000002000000200
+       .quad 0x0000000000000000, 0x0000200008020008
+       .quad 0x0000002008000208, 0x0000200000020000
+       .quad 0x0000000008000000, 0x0000202008020208
+       .quad 0x0000000000000008, 0x0000202000020208
+       .quad 0x0000202000020200, 0x0000000008000008
+       .quad 0x0000200008020000, 0x0000002008000208
+       .quad 0x0000002000000208, 0x0000200008020000
+       .quad 0x0000202000020208, 0x0000000000000008
+       .quad 0x0000200008020008, 0x0000202000020200
+.L_s4:
+       .quad 0x1008020000002001, 0x1000020800002001
+       .quad 0x1000020800002001, 0x0000000800000000
+       .quad 0x0008020800002000, 0x1008000800000001
+       .quad 0x1008000000000001, 0x1000020000002001
+       .quad 0x0000000000000000, 0x0008020000002000
+       .quad 0x0008020000002000, 0x1008020800002001
+       .quad 0x1000000800000001, 0x0000000000000000
+       .quad 0x0008000800000000, 0x1008000000000001
+       .quad 0x1000000000000001, 0x0000020000002000
+       .quad 0x0008000000000000, 0x1008020000002001
+       .quad 0x0000000800000000, 0x0008000000000000
+       .quad 0x1000020000002001, 0x0000020800002000
+       .quad 0x1008000800000001, 0x1000000000000001
+       .quad 0x0000020800002000, 0x0008000800000000
+       .quad 0x0000020000002000, 0x0008020800002000
+       .quad 0x1008020800002001, 0x1000000800000001
+       .quad 0x0008000800000000, 0x1008000000000001
+       .quad 0x0008020000002000, 0x1008020800002001
+       .quad 0x1000000800000001, 0x0000000000000000
+       .quad 0x0000000000000000, 0x0008020000002000
+       .quad 0x0000020800002000, 0x0008000800000000
+       .quad 0x1008000800000001, 0x1000000000000001
+       .quad 0x1008020000002001, 0x1000020800002001
+       .quad 0x1000020800002001, 0x0000000800000000
+       .quad 0x1008020800002001, 0x1000000800000001
+       .quad 0x1000000000000001, 0x0000020000002000
+       .quad 0x1008000000000001, 0x1000020000002001
+       .quad 0x0008020800002000, 0x1008000800000001
+       .quad 0x1000020000002001, 0x0000020800002000
+       .quad 0x0008000000000000, 0x1008020000002001
+       .quad 0x0000000800000000, 0x0008000000000000
+       .quad 0x0000020000002000, 0x0008020800002000
+.L_s5:
+       .quad 0x0000001000000100, 0x0020001002080100
+       .quad 0x0020000002080000, 0x0420001002000100
+       .quad 0x0000000000080000, 0x0000001000000100
+       .quad 0x0400000000000000, 0x0020000002080000
+       .quad 0x0400001000080100, 0x0000000000080000
+       .quad 0x0020001002000100, 0x0400001000080100
+       .quad 0x0420001002000100, 0x0420000002080000
+       .quad 0x0000001000080100, 0x0400000000000000
+       .quad 0x0020000002000000, 0x0400000000080000
+       .quad 0x0400000000080000, 0x0000000000000000
+       .quad 0x0400001000000100, 0x0420001002080100
+       .quad 0x0420001002080100, 0x0020001002000100
+       .quad 0x0420000002080000, 0x0400001000000100
+       .quad 0x0000000000000000, 0x0420000002000000
+       .quad 0x0020001002080100, 0x0020000002000000
+       .quad 0x0420000002000000, 0x0000001000080100
+       .quad 0x0000000000080000, 0x0420001002000100
+       .quad 0x0000001000000100, 0x0020000002000000
+       .quad 0x0400000000000000, 0x0020000002080000
+       .quad 0x0420001002000100, 0x0400001000080100
+       .quad 0x0020001002000100, 0x0400000000000000
+       .quad 0x0420000002080000, 0x0020001002080100
+       .quad 0x0400001000080100, 0x0000001000000100
+       .quad 0x0020000002000000, 0x0420000002080000
+       .quad 0x0420001002080100, 0x0000001000080100
+       .quad 0x0420000002000000, 0x0420001002080100
+       .quad 0x0020000002080000, 0x0000000000000000
+       .quad 0x0400000000080000, 0x0420000002000000
+       .quad 0x0000001000080100, 0x0020001002000100
+       .quad 0x0400001000000100, 0x0000000000080000
+       .quad 0x0000000000000000, 0x0400000000080000
+       .quad 0x0020001002080100, 0x0400001000000100
+.L_s6:
+       .quad 0x0200000120000010, 0x0204000020000000
+       .quad 0x0000040000000000, 0x0204040120000010
+       .quad 0x0204000020000000, 0x0000000100000010
+       .quad 0x0204040120000010, 0x0004000000000000
+       .quad 0x0200040020000000, 0x0004040100000010
+       .quad 0x0004000000000000, 0x0200000120000010
+       .quad 0x0004000100000010, 0x0200040020000000
+       .quad 0x0200000020000000, 0x0000040100000010
+       .quad 0x0000000000000000, 0x0004000100000010
+       .quad 0x0200040120000010, 0x0000040000000000
+       .quad 0x0004040000000000, 0x0200040120000010
+       .quad 0x0000000100000010, 0x0204000120000010
+       .quad 0x0204000120000010, 0x0000000000000000
+       .quad 0x0004040100000010, 0x0204040020000000
+       .quad 0x0000040100000010, 0x0004040000000000
+       .quad 0x0204040020000000, 0x0200000020000000
+       .quad 0x0200040020000000, 0x0000000100000010
+       .quad 0x0204000120000010, 0x0004040000000000
+       .quad 0x0204040120000010, 0x0004000000000000
+       .quad 0x0000040100000010, 0x0200000120000010
+       .quad 0x0004000000000000, 0x0200040020000000
+       .quad 0x0200000020000000, 0x0000040100000010
+       .quad 0x0200000120000010, 0x0204040120000010
+       .quad 0x0004040000000000, 0x0204000020000000
+       .quad 0x0004040100000010, 0x0204040020000000
+       .quad 0x0000000000000000, 0x0204000120000010
+       .quad 0x0000000100000010, 0x0000040000000000
+       .quad 0x0204000020000000, 0x0004040100000010
+       .quad 0x0000040000000000, 0x0004000100000010
+       .quad 0x0200040120000010, 0x0000000000000000
+       .quad 0x0204040020000000, 0x0200000020000000
+       .quad 0x0004000100000010, 0x0200040120000010
+.L_s7:
+       .quad 0x0002000000200000, 0x2002000004200002
+       .quad 0x2000000004000802, 0x0000000000000000
+       .quad 0x0000000000000800, 0x2000000004000802
+       .quad 0x2002000000200802, 0x0002000004200800
+       .quad 0x2002000004200802, 0x0002000000200000
+       .quad 0x0000000000000000, 0x2000000004000002
+       .quad 0x2000000000000002, 0x0000000004000000
+       .quad 0x2002000004200002, 0x2000000000000802
+       .quad 0x0000000004000800, 0x2002000000200802
+       .quad 0x2002000000200002, 0x0000000004000800
+       .quad 0x2000000004000002, 0x0002000004200000
+       .quad 0x0002000004200800, 0x2002000000200002
+       .quad 0x0002000004200000, 0x0000000000000800
+       .quad 0x2000000000000802, 0x2002000004200802
+       .quad 0x0002000000200800, 0x2000000000000002
+       .quad 0x0000000004000000, 0x0002000000200800
+       .quad 0x0000000004000000, 0x0002000000200800
+       .quad 0x0002000000200000, 0x2000000004000802
+       .quad 0x2000000004000802, 0x2002000004200002
+       .quad 0x2002000004200002, 0x2000000000000002
+       .quad 0x2002000000200002, 0x0000000004000000
+       .quad 0x0000000004000800, 0x0002000000200000
+       .quad 0x0002000004200800, 0x2000000000000802
+       .quad 0x2002000000200802, 0x0002000004200800
+       .quad 0x2000000000000802, 0x2000000004000002
+       .quad 0x2002000004200802, 0x0002000004200000
+       .quad 0x0002000000200800, 0x0000000000000000
+       .quad 0x2000000000000002, 0x2002000004200802
+       .quad 0x0000000000000000, 0x2002000000200802
+       .quad 0x0002000004200000, 0x0000000000000800
+       .quad 0x2000000004000002, 0x0000000004000800
+       .quad 0x0000000000000800, 0x2002000000200002
+.L_s8:
+       .quad 0x0100010410001000, 0x0000010000001000
+       .quad 0x0000000000040000, 0x0100010410041000
+       .quad 0x0100000010000000, 0x0100010410001000
+       .quad 0x0000000400000000, 0x0100000010000000
+       .quad 0x0000000400040000, 0x0100000010040000
+       .quad 0x0100010410041000, 0x0000010000041000
+       .quad 0x0100010010041000, 0x0000010400041000
+       .quad 0x0000010000001000, 0x0000000400000000
+       .quad 0x0100000010040000, 0x0100000410000000
+       .quad 0x0100010010001000, 0x0000010400001000
+       .quad 0x0000010000041000, 0x0000000400040000
+       .quad 0x0100000410040000, 0x0100010010041000
+       .quad 0x0000010400001000, 0x0000000000000000
+       .quad 0x0000000000000000, 0x0100000410040000
+       .quad 0x0100000410000000, 0x0100010010001000
+       .quad 0x0000010400041000, 0x0000000000040000
+       .quad 0x0000010400041000, 0x0000000000040000
+       .quad 0x0100010010041000, 0x0000010000001000
+       .quad 0x0000000400000000, 0x0100000410040000
+       .quad 0x0000010000001000, 0x0000010400041000
+       .quad 0x0100010010001000, 0x0000000400000000
+       .quad 0x0100000410000000, 0x0100000010040000
+       .quad 0x0100000410040000, 0x0100000010000000
+       .quad 0x0000000000040000, 0x0100010410001000
+       .quad 0x0000000000000000, 0x0100010410041000
+       .quad 0x0000000400040000, 0x0100000410000000
+       .quad 0x0100000010040000, 0x0100010010001000
+       .quad 0x0100010410001000, 0x0000000000000000
+       .quad 0x0100010410041000, 0x0000010000041000
+       .quad 0x0000010000041000, 0x0000010400001000
+       .quad 0x0000010400001000, 0x0000000400040000
+       .quad 0x0100000010000000, 0x0100010010041000
+
+#endif
+#endif
index 6611fd3..5c99f50 100644 (file)
@@ -49,7 +49,7 @@
  * encrypt or decrypt data in 64bit blocks in Electronic Codebook Mode.
  *
  * (In the examples below the slashes at the beginning and ending of comments
- * are omited.)
+ * are omitted.)
  *
  * DES Example
  * -----------
@@ -68,7 +68,7 @@
  *     * Encrypt the plaintext *
  *     des_ecb_encrypt(context, plaintext, ciphertext);
  *
- *     * To recover the orginal plaintext from ciphertext use: *
+ *     * To recover the original plaintext from ciphertext use: *
  *     des_ecb_decrypt(context, ciphertext, recoverd);
  *
  *
 #include "g10lib.h"
 #include "cipher.h"
 #include "bufhelp.h"
+#include "cipher-selftest.h"
+
+
+#define DES_BLOCKSIZE 8
+
+
+/* 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) || \
+    defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define USE_AMD64_ASM 1
+#endif
+
+/* Helper macro to force alignment to 16 bytes.  */
+#ifdef HAVE_GCC_ATTRIBUTE_ALIGNED
+# define ATTR_ALIGNED_16  __attribute__ ((aligned (16)))
+#else
+# define ATTR_ALIGNED_16
+#endif
 
 #if defined(__GNUC__) && defined(__GNU_LIBRARY__)
-#define working_memcmp memcmp
+# define working_memcmp memcmp
 #else
 /*
  * According to the SunOS man page, memcmp returns indeterminate sign
  * depending on whether characters are signed or not.
  */
 static int
-working_memcmp( const char *a, const char *b, size_t n )
+working_memcmp( const void *_a, const void *_b, size_t n )
 {
+    const char *a = _a;
+    const char *b = _b;
     for( ; n; n--, a++, b++ )
        if( *a != *b )
            return (int)(*(byte*)a) - (int)(*(byte*)b);
@@ -171,6 +192,12 @@ static int tripledes_ecb_crypt (struct _tripledes_ctx *,
                                 const byte *, byte *, int);
 static int is_weak_key ( const byte *key );
 static const char *selftest (void);
+static unsigned int do_tripledes_encrypt(void *context, byte *outbuf,
+                                        const byte *inbuf );
+static unsigned int do_tripledes_decrypt(void *context, byte *outbuf,
+                                        const byte *inbuf );
+static gcry_err_code_t do_tripledes_setkey(void *context, const byte *key,
+                                           unsigned keylen);
 
 static int initialized;
 
@@ -727,6 +754,98 @@ tripledes_set3keys (struct _tripledes_ctx *ctx,
 
 
 
+#ifdef USE_AMD64_ASM
+
+/* Assembly implementation of triple-DES. */
+extern void _gcry_3des_amd64_crypt_block(const void *keys, byte *out,
+                                         const byte *in);
+
+/* These assembly implementations process three blocks in parallel. */
+extern void _gcry_3des_amd64_ctr_enc(const void *keys, byte *out,
+                                     const byte *in, byte *ctr);
+
+extern void _gcry_3des_amd64_cbc_dec(const void *keys, byte *out,
+                                     const byte *in, byte *iv);
+
+extern void _gcry_3des_amd64_cfb_dec(const void *keys, byte *out,
+                                     const byte *in, byte *iv);
+
+#define TRIPLEDES_ECB_BURN_STACK (8 * sizeof(void *))
+
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+static inline void
+call_sysv_fn (const void *fn, const void *arg1, const void *arg2,
+              const void *arg3, const void *arg4)
+{
+  /* Call SystemV ABI function without storing non-volatile XMM registers,
+   * as target function does not use vector instruction sets. */
+  asm volatile ("callq *%0\n\t"
+                : "+a" (fn),
+                  "+D" (arg1),
+                  "+S" (arg2),
+                  "+d" (arg3),
+                  "+c" (arg4)
+                :
+                : "cc", "memory", "r8", "r9", "r10", "r11");
+}
+#endif
+
+/*
+ * Electronic Codebook Mode Triple-DES encryption/decryption of data
+ * according to 'mode'.  Sometimes this mode is named 'EDE' mode
+ * (Encryption-Decryption-Encryption).
+ */
+static inline int
+tripledes_ecb_crypt (struct _tripledes_ctx *ctx, const byte * from,
+                     byte * to, int mode)
+{
+  u32 *keys;
+
+  keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys;
+
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+  call_sysv_fn (_gcry_3des_amd64_crypt_block, keys, to, from, NULL);
+#else
+  _gcry_3des_amd64_crypt_block(keys, to, from);
+#endif
+
+  return 0;
+}
+
+static inline void
+tripledes_amd64_ctr_enc(const void *keys, byte *out, const byte *in, byte *ctr)
+{
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+  call_sysv_fn (_gcry_3des_amd64_ctr_enc, keys, out, in, ctr);
+#else
+  _gcry_3des_amd64_ctr_enc(keys, out, in, ctr);
+#endif
+}
+
+static inline void
+tripledes_amd64_cbc_dec(const void *keys, byte *out, const byte *in, byte *iv)
+{
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+  call_sysv_fn (_gcry_3des_amd64_cbc_dec, keys, out, in, iv);
+#else
+  _gcry_3des_amd64_cbc_dec(keys, out, in, iv);
+#endif
+}
+
+static inline void
+tripledes_amd64_cfb_dec(const void *keys, byte *out, const byte *in, byte *iv)
+{
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+  call_sysv_fn (_gcry_3des_amd64_cfb_dec, keys, out, in, iv);
+#else
+  _gcry_3des_amd64_cfb_dec(keys, out, in, iv);
+#endif
+}
+
+#else /*USE_AMD64_ASM*/
+
+#define TRIPLEDES_ECB_BURN_STACK 32
+
 /*
  * Electronic Codebook Mode Triple-DES encryption/decryption of data
  * according to 'mode'.  Sometimes this mode is named 'EDE' mode
@@ -777,9 +896,159 @@ tripledes_ecb_crypt (struct _tripledes_ctx *ctx, const byte * from,
   return 0;
 }
 
+#endif /*!USE_AMD64_ASM*/
 
 
 
+/* Bulk encryption of complete blocks in CTR mode.  This function is only
+   intended for the bulk encryption feature of cipher.c.  CTR is expected to be
+   of size DES_BLOCKSIZE. */
+void
+_gcry_3des_ctr_enc(void *context, unsigned char *ctr, void *outbuf_arg,
+                   const void *inbuf_arg, size_t nblocks)
+{
+  struct _tripledes_ctx *ctx = context;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  unsigned char tmpbuf[DES_BLOCKSIZE];
+  int burn_stack_depth = TRIPLEDES_ECB_BURN_STACK;
+  int i;
+
+#ifdef USE_AMD64_ASM
+  {
+    int asm_burn_depth = 9 * sizeof(void *);
+
+    if (nblocks >= 3 && burn_stack_depth < asm_burn_depth)
+      burn_stack_depth = asm_burn_depth;
+
+    /* Process data in 3 block chunks. */
+    while (nblocks >= 3)
+      {
+        tripledes_amd64_ctr_enc(ctx->encrypt_subkeys, outbuf, inbuf, ctr);
+
+        nblocks -= 3;
+        outbuf += 3 * DES_BLOCKSIZE;
+        inbuf  += 3 * DES_BLOCKSIZE;
+      }
+
+    /* Use generic code to handle smaller chunks... */
+  }
+#endif
+
+  for ( ;nblocks; nblocks-- )
+    {
+      /* Encrypt the counter. */
+      tripledes_ecb_encrypt (ctx, ctr, tmpbuf);
+      /* XOR the input with the encrypted counter and store in output.  */
+      buf_xor(outbuf, tmpbuf, inbuf, DES_BLOCKSIZE);
+      outbuf += DES_BLOCKSIZE;
+      inbuf  += DES_BLOCKSIZE;
+      /* Increment the counter.  */
+      for (i = DES_BLOCKSIZE; i > 0; i--)
+        {
+          ctr[i-1]++;
+          if (ctr[i-1])
+            break;
+        }
+    }
+
+  wipememory(tmpbuf, sizeof(tmpbuf));
+  _gcry_burn_stack(burn_stack_depth);
+}
+
+
+/* Bulk decryption of complete blocks in CBC mode.  This function is only
+   intended for the bulk encryption feature of cipher.c. */
+void
+_gcry_3des_cbc_dec(void *context, unsigned char *iv, void *outbuf_arg,
+                   const void *inbuf_arg, size_t nblocks)
+{
+  struct _tripledes_ctx *ctx = context;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  unsigned char savebuf[DES_BLOCKSIZE];
+  int burn_stack_depth = TRIPLEDES_ECB_BURN_STACK;
+
+#ifdef USE_AMD64_ASM
+  {
+    int asm_burn_depth = 10 * sizeof(void *);
+
+    if (nblocks >= 3 && burn_stack_depth < asm_burn_depth)
+      burn_stack_depth = asm_burn_depth;
+
+    /* Process data in 3 block chunks. */
+    while (nblocks >= 3)
+      {
+        tripledes_amd64_cbc_dec(ctx->decrypt_subkeys, outbuf, inbuf, iv);
+
+        nblocks -= 3;
+        outbuf += 3 * DES_BLOCKSIZE;
+        inbuf  += 3 * DES_BLOCKSIZE;
+      }
+
+    /* Use generic code to handle smaller chunks... */
+  }
+#endif
+
+  for ( ;nblocks; nblocks-- )
+    {
+      /* INBUF is needed later and it may be identical to OUTBUF, so store
+         the intermediate result to SAVEBUF.  */
+      tripledes_ecb_decrypt (ctx, inbuf, savebuf);
+
+      buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, DES_BLOCKSIZE);
+      inbuf += DES_BLOCKSIZE;
+      outbuf += DES_BLOCKSIZE;
+    }
+
+  wipememory(savebuf, sizeof(savebuf));
+  _gcry_burn_stack(burn_stack_depth);
+}
+
+
+/* Bulk decryption of complete blocks in CFB mode.  This function is only
+   intended for the bulk encryption feature of cipher.c. */
+void
+_gcry_3des_cfb_dec(void *context, unsigned char *iv, void *outbuf_arg,
+                  const void *inbuf_arg, size_t nblocks)
+{
+  struct _tripledes_ctx *ctx = context;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  int burn_stack_depth = TRIPLEDES_ECB_BURN_STACK;
+
+#ifdef USE_AMD64_ASM
+  {
+    int asm_burn_depth = 9 * sizeof(void *);
+
+    if (nblocks >= 3 && burn_stack_depth < asm_burn_depth)
+      burn_stack_depth = asm_burn_depth;
+
+    /* Process data in 3 block chunks. */
+    while (nblocks >= 3)
+      {
+        tripledes_amd64_cfb_dec(ctx->encrypt_subkeys, outbuf, inbuf, iv);
+
+        nblocks -= 3;
+        outbuf += 3 * DES_BLOCKSIZE;
+        inbuf  += 3 * DES_BLOCKSIZE;
+      }
+
+    /* Use generic code to handle smaller chunks... */
+  }
+#endif
+
+  for ( ;nblocks; nblocks-- )
+    {
+      tripledes_ecb_encrypt (ctx, iv, iv);
+      buf_xor_n_copy(outbuf, iv, inbuf, DES_BLOCKSIZE);
+      outbuf += DES_BLOCKSIZE;
+      inbuf  += DES_BLOCKSIZE;
+    }
+
+  _gcry_burn_stack(burn_stack_depth);
+}
+
 
 /*
  * Check whether the 8 byte key is weak.
@@ -815,6 +1084,67 @@ is_weak_key ( const byte *key )
 }
 
 
+/* Alternative setkey for selftests; need larger key than default. */
+static gcry_err_code_t
+bulk_selftest_setkey (void *context, const byte *__key, unsigned __keylen)
+{
+  static const unsigned char key[24] ATTR_ALIGNED_16 = {
+      0x66,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F,
+      0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x22,
+      0x18,0x2A,0x39,0x47,0x5E,0x6F,0x75,0x82
+    };
+
+  (void)__key;
+  (void)__keylen;
+
+  return do_tripledes_setkey(context, key, sizeof(key));
+}
+
+
+/* Run the self-tests for DES-CTR, tests IV increment of bulk CTR
+   encryption.  Returns NULL on success. */
+static const char *
+selftest_ctr (void)
+{
+  const int nblocks = 3+1;
+  const int blocksize = DES_BLOCKSIZE;
+  const int context_size = sizeof(struct _tripledes_ctx);
+
+  return _gcry_selftest_helper_ctr("3DES", &bulk_selftest_setkey,
+           &do_tripledes_encrypt, &_gcry_3des_ctr_enc, nblocks, blocksize,
+           context_size);
+}
+
+
+/* Run the self-tests for DES-CBC, tests bulk CBC decryption.
+   Returns NULL on success. */
+static const char *
+selftest_cbc (void)
+{
+  const int nblocks = 3+2;
+  const int blocksize = DES_BLOCKSIZE;
+  const int context_size = sizeof(struct _tripledes_ctx);
+
+  return _gcry_selftest_helper_cbc("3DES", &bulk_selftest_setkey,
+           &do_tripledes_encrypt, &_gcry_3des_cbc_dec, nblocks, blocksize,
+           context_size);
+}
+
+
+/* Run the self-tests for DES-CFB, tests bulk CBC decryption.
+   Returns NULL on success. */
+static const char *
+selftest_cfb (void)
+{
+  const int nblocks = 3+2;
+  const int blocksize = DES_BLOCKSIZE;
+  const int context_size = sizeof(struct _tripledes_ctx);
+
+  return _gcry_selftest_helper_cfb("3DES", &bulk_selftest_setkey,
+           &do_tripledes_encrypt, &_gcry_3des_cfb_dec, nblocks, blocksize,
+           context_size);
+}
+
 
 /*
  * Performs a selftest of this DES/Triple-DES implementation.
@@ -824,6 +1154,8 @@ is_weak_key ( const byte *key )
 static const char *
 selftest (void)
 {
+  const char *r;
+
   /*
    * Check if 'u32' is really 32 bits wide. This DES / 3DES implementation
    * need this.
@@ -1003,6 +1335,15 @@ selftest (void)
         return "DES weak key detection failed";
   }
 
+  if ( (r = selftest_cbc ()) )
+    return r;
+
+  if ( (r = selftest_cfb ()) )
+    return r;
+
+  if ( (r = selftest_ctr ()) )
+    return r;
+
   return 0;
 }
 
@@ -1060,7 +1401,7 @@ do_tripledes_encrypt( void *context, byte *outbuf, const byte *inbuf )
   struct _tripledes_ctx *ctx = (struct _tripledes_ctx *) context;
 
   tripledes_ecb_encrypt ( ctx, inbuf, outbuf );
-  return /*burn_stack*/ (32);
+  return /*burn_stack*/ TRIPLEDES_ECB_BURN_STACK;
 }
 
 static unsigned int
@@ -1068,7 +1409,7 @@ do_tripledes_decrypt( void *context, byte *outbuf, const byte *inbuf )
 {
   struct _tripledes_ctx *ctx = (struct _tripledes_ctx *) context;
   tripledes_ecb_decrypt ( ctx, inbuf, outbuf );
-  return /*burn_stack*/ (32);
+  return /*burn_stack*/ TRIPLEDES_ECB_BURN_STACK;
 }
 
 static gcry_err_code_t
index a5e42a2..6f2c2f9 100644 (file)
@@ -319,7 +319,7 @@ _gcry_dsa_gen_rfc6979_k (gcry_mpi_t *r_k,
 
   /* The caller may have requested that we introduce some extra loops.
      This is for example useful if the caller wants another value for
-     K because the last returned one yielded an R of 0.  Becuase this
+     K because the last returned one yielded an R of 0.  Because this
      is very unlikely we implement it in a straightforward way.  */
   if (extraloops)
     {
index 09cd969..22d8d78 100644 (file)
@@ -66,8 +66,10 @@ static const char *dsa_names[] =
   };
 
 
-/* A sample 1024 bit DSA key used for the selftests.  */
-static const char sample_secret_key[] =
+/* A sample 1024 bit DSA key used for the selftests.  Not anymore
+ * used, kept only for reference.  */
+#if 0
+static const char sample_secret_key_1024[] =
 "(private-key"
 " (dsa"
 "  (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
@@ -85,7 +87,7 @@ static const char sample_secret_key[] =
 "      42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)"
 "  (x #11D54E4ADBD3034160F2CED4B7CD292A4EBF3EC0#)))";
 /* A sample 1024 bit DSA key used for the selftests (public only).  */
-static const char sample_public_key[] =
+static const char sample_public_key_1024[] =
 "(public-key"
 " (dsa"
 "  (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
@@ -101,7 +103,25 @@ static const char sample_public_key[] =
 "      A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827"
 "      6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20"
 "      42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)))";
+#endif /*0*/
 
+/* 2048 DSA key from RFC 6979 A.2.2 */
+static const char sample_public_key_2048[] =
+"(public-key"
+" (dsa"
+"  (p #9DB6FB5951B66BB6FE1E140F1D2CE5502374161FD6538DF1648218642F0B5C48C8F7A41AADFA187324B87674FA1822B00F1ECF8136943D7C55757264E5A1A44FFE012E9936E00C1D3E9310B01C7D179805D3058B2A9F4BB6F9716BFE6117C6B5B3CC4D9BE341104AD4A80AD6C94E005F4B993E14F091EB51743BF33050C38DE235567E1B34C3D6A5C0CEAA1A0F368213C3D19843D0B4B09DCB9FC72D39C8DE41F1BF14D4BB4563CA28371621CAD3324B6A2D392145BEBFAC748805236F5CA2FE92B871CD8F9C36D3292B5509CA8CAA77A2ADFC7BFD77DDA6F71125A7456FEA153E433256A2261C6A06ED3693797E7995FAD5AABBCFBE3EDA2741E375404AE25B#)"
+"  (q #F2C3119374CE76C9356990B465374A17F23F9ED35089BD969F61C6DDE9998C1F#)"
+"  (g #5C7FF6B06F8F143FE8288433493E4769C4D988ACE5BE25A0E24809670716C613D7B0CEE6932F8FAA7C44D2CB24523DA53FBE4F6EC3595892D1AA58C4328A06C46A15662E7EAA703A1DECF8BBB2D05DBE2EB956C142A338661D10461C0D135472085057F3494309FFA73C611F78B32ADBB5740C361C9F35BE90997DB2014E2EF5AA61782F52ABEB8BD6432C4DD097BC5423B285DAFB60DC364E8161F4A2A35ACA3A10B1C4D203CC76A470A33AFDCBDD92959859ABD8B56E1725252D78EAC66E71BA9AE3F1DD2487199874393CD4D832186800654760E1E34C09E4D155179F9EC0DC4473F996BDCE6EED1CABED8B6F116F7AD9CF505DF0F998E34AB27514B0FFE7#)"
+"  (y #667098C654426C78D7F8201EAC6C203EF030D43605032C2F1FA937E5237DBD949F34A0A2564FE126DC8B715C5141802CE0979C8246463C40E6B6BDAA2513FA611728716C2E4FD53BC95B89E69949D96512E873B9C8F8DFD499CC312882561ADECB31F658E934C0C197F2C4D96B05CBAD67381E7B768891E4DA3843D24D94CDFB5126E9B8BF21E8358EE0E0A30EF13FD6A664C0DCE3731F7FB49A4845A4FD8254687972A2D382599C9BAC4E0ED7998193078913032558134976410B89D2C171D123AC35FD977219597AA7D15C1A9A428E59194F75C721EBCBCFAE44696A499AFA74E04299F132026601638CB87AB79190D4A0986315DA8EEC6561C938996BEADF#)))";
+
+static const char sample_secret_key_2048[] =
+"(private-key"
+" (dsa"
+"  (p #9DB6FB5951B66BB6FE1E140F1D2CE5502374161FD6538DF1648218642F0B5C48C8F7A41AADFA187324B87674FA1822B00F1ECF8136943D7C55757264E5A1A44FFE012E9936E00C1D3E9310B01C7D179805D3058B2A9F4BB6F9716BFE6117C6B5B3CC4D9BE341104AD4A80AD6C94E005F4B993E14F091EB51743BF33050C38DE235567E1B34C3D6A5C0CEAA1A0F368213C3D19843D0B4B09DCB9FC72D39C8DE41F1BF14D4BB4563CA28371621CAD3324B6A2D392145BEBFAC748805236F5CA2FE92B871CD8F9C36D3292B5509CA8CAA77A2ADFC7BFD77DDA6F71125A7456FEA153E433256A2261C6A06ED3693797E7995FAD5AABBCFBE3EDA2741E375404AE25B#)"
+"  (q #F2C3119374CE76C9356990B465374A17F23F9ED35089BD969F61C6DDE9998C1F#)"
+"  (g #5C7FF6B06F8F143FE8288433493E4769C4D988ACE5BE25A0E24809670716C613D7B0CEE6932F8FAA7C44D2CB24523DA53FBE4F6EC3595892D1AA58C4328A06C46A15662E7EAA703A1DECF8BBB2D05DBE2EB956C142A338661D10461C0D135472085057F3494309FFA73C611F78B32ADBB5740C361C9F35BE90997DB2014E2EF5AA61782F52ABEB8BD6432C4DD097BC5423B285DAFB60DC364E8161F4A2A35ACA3A10B1C4D203CC76A470A33AFDCBDD92959859ABD8B56E1725252D78EAC66E71BA9AE3F1DD2487199874393CD4D832186800654760E1E34C09E4D155179F9EC0DC4473F996BDCE6EED1CABED8B6F116F7AD9CF505DF0F998E34AB27514B0FFE7#)"
+"  (y #667098C654426C78D7F8201EAC6C203EF030D43605032C2F1FA937E5237DBD949F34A0A2564FE126DC8B715C5141802CE0979C8246463C40E6B6BDAA2513FA611728716C2E4FD53BC95B89E69949D96512E873B9C8F8DFD499CC312882561ADECB31F658E934C0C197F2C4D96B05CBAD67381E7B768891E4DA3843D24D94CDFB5126E9B8BF21E8358EE0E0A30EF13FD6A664C0DCE3731F7FB49A4845A4FD8254687972A2D382599C9BAC4E0ED7998193078913032558134976410B89D2C171D123AC35FD977219597AA7D15C1A9A428E59194F75C721EBCBCFAE44696A499AFA74E04299F132026601638CB87AB79190D4A0986315DA8EEC6561C938996BEADF#)"
+"  (x #69C7548C21D0DFEA6B9A51C9EAD4E27C33D3B3F180316E5BCAB92C933F0E4DBC#)))";
 
 
 \f
@@ -373,6 +393,8 @@ generate_fips186 (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
   gcry_mpi_t value_x = NULL; /* The secret exponent. */
   gcry_mpi_t value_h = NULL; /* Helper.  */
   gcry_mpi_t value_e = NULL; /* Helper.  */
+  gcry_mpi_t value_c = NULL; /* helper for x */
+  gcry_mpi_t value_qm2 = NULL; /* q - 2 */
 
   /* Preset return values.  */
   *r_counter = 0;
@@ -393,8 +415,8 @@ generate_fips186 (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
 
   /* Check that QBITS and NBITS match the standard.  Note that FIPS
      186-3 uses N for QBITS and L for NBITS.  */
-  if (nbits == 1024 && qbits == 160)
-    ;
+  if (nbits == 1024 && qbits == 160 && use_fips186_2)
+    ; /* Allowed in FIPS 186-2 mode.  */
   else if (nbits == 2048 && qbits == 224)
     ;
   else if (nbits == 2048 && qbits == 256)
@@ -425,30 +447,28 @@ generate_fips186 (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
           initial_seed.sexp = sexp_find_token (deriveparms, "seed", 0);
           if (initial_seed.sexp)
             initial_seed.seed = sexp_nth_data (initial_seed.sexp, 1,
-                                                    &initial_seed.seedlen);
+                                               &initial_seed.seedlen);
         }
 
-      /* Fixme: Enable 186-3 after it has been approved and after fixing
-         the generation function.  */
-      /*   if (use_fips186_2) */
-      (void)use_fips186_2;
-      ec = _gcry_generate_fips186_2_prime (nbits, qbits,
-                                           initial_seed.seed,
-                                           initial_seed.seedlen,
-                                           &prime_q, &prime_p,
-                                           r_counter,
-                                           r_seed, r_seedlen);
-      /*   else */
-      /*     ec = _gcry_generate_fips186_3_prime (nbits, qbits, NULL, 0, */
-      /*                                          &prime_q, &prime_p, */
-      /*                                          r_counter, */
-      /*                                          r_seed, r_seedlen, NULL); */
+      if (use_fips186_2)
+        ec = _gcry_generate_fips186_2_prime (nbits, qbits,
+                                             initial_seed.seed,
+                                             initial_seed.seedlen,
+                                             &prime_q, &prime_p,
+                                             r_counter,
+                                             r_seed, r_seedlen);
+      else
+        ec = _gcry_generate_fips186_3_prime (nbits, qbits, NULL, 0,
+                                             &prime_q, &prime_p,
+                                             r_counter,
+                                             r_seed, r_seedlen, NULL);
       sexp_release (initial_seed.sexp);
       if (ec)
         goto leave;
 
       /* Find a generator g (h and e are helpers).
-         e = (p-1)/q */
+       *    e = (p-1)/q
+       */
       value_e = mpi_alloc_like (prime_p);
       mpi_sub_ui (value_e, prime_p, 1);
       mpi_fdiv_q (value_e, value_e, prime_q );
@@ -463,17 +483,24 @@ generate_fips186 (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
       while (!mpi_cmp_ui (value_g, 1));  /* Continue until g != 1.  */
     }
 
-
-  /* Select a random number x with:  0 < x < q  */
+  value_c = mpi_snew (qbits);
   value_x = mpi_snew (qbits);
+  value_qm2 = mpi_snew (qbits);
+  mpi_sub_ui (value_qm2, prime_q, 2);
+
+  /* FIPS 186-4 B.1.2 steps 4-6 */
   do
     {
       if( DBG_CIPHER )
         progress('.');
-      _gcry_mpi_randomize (value_x, qbits, GCRY_VERY_STRONG_RANDOM);
-      mpi_clear_highbit (value_x, qbits+1);
+      _gcry_mpi_randomize (value_c, qbits, GCRY_VERY_STRONG_RANDOM);
+      mpi_clear_highbit (value_c, qbits+1);
     }
-  while (!(mpi_cmp_ui (value_x, 0) > 0 && mpi_cmp (value_x, prime_q) < 0));
+  while (!(mpi_cmp_ui (value_c, 0) > 0 && mpi_cmp (value_c, value_qm2) < 0));
+  /* while (mpi_cmp (value_c, value_qm2) > 0); */
+
+  /* x = c + 1 */
+  mpi_add_ui(value_x, value_c, 1);
 
   /* y = g^x mod p */
   value_y = mpi_alloc_like (prime_p);
@@ -506,6 +533,8 @@ generate_fips186 (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
   _gcry_mpi_release (value_x);
   _gcry_mpi_release (value_h);
   _gcry_mpi_release (value_e);
+  _gcry_mpi_release (value_c);
+  _gcry_mpi_release (value_qm2);
 
   /* As a last step test this keys (this should never fail of course). */
   if (!ec && test_keys (sk, qbits) )
@@ -972,8 +1001,8 @@ dsa_check_secret_key (gcry_sexp_t keyparms)
   DSA_secret_key sk = {NULL, NULL, NULL, NULL, NULL};
 
   rc = _gcry_sexp_extract_param (keyparms, NULL, "pqgyx",
-                                 &sk.p, &sk.q, &sk.g, &sk.y, &sk.x,
-                                 NULL);
+                                  &sk.p, &sk.q, &sk.g, &sk.y, &sk.x,
+                                  NULL);
   if (rc)
     goto leave;
 
@@ -1158,25 +1187,42 @@ dsa_get_nbits (gcry_sexp_t parms)
  */
 
 static const char *
-selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
+selftest_sign (gcry_sexp_t pkey, gcry_sexp_t skey)
 {
+  /* Sample data from RFC 6979 section A.2.2, hash is of message "sample" */
   static const char sample_data[] =
-    "(data (flags raw)"
-    " (value #a0b1c2d3e4f500102030405060708090a1b2c3d4#))";
+    "(data (flags rfc6979)"
+    " (hash sha256 #af2bdbe1aa9b6ec1e2ade1d694f41fc71a831d0268e9891562113d8a62add1bf#))";
   static const char sample_data_bad[] =
-    "(data (flags raw)"
-    " (value #a0b1c2d3e4f510102030405060708090a1b2c3d4#))";
+    "(data (flags rfc6979)"
+    " (hash sha256 #bf2bdbe1aa9b6ec1e2ade1d694f41fc71a831d0268e9891562113d8a62add1bf#))";
+  static const char signature_r[] =
+    "eace8bdbbe353c432a795d9ec556c6d021f7a03f42c36e9bc87e4ac7932cc809";
+  static const char signature_s[] =
+    "7081e175455f9247b812b74583e9e94f9ea79bd640dc962533b0680793a38d53";
 
   const char *errtxt = NULL;
   gcry_error_t err;
   gcry_sexp_t data = NULL;
   gcry_sexp_t data_bad = NULL;
   gcry_sexp_t sig = NULL;
+  gcry_sexp_t l1 = NULL;
+  gcry_sexp_t l2 = NULL;
+  gcry_mpi_t r = NULL;
+  gcry_mpi_t s = NULL;
+  gcry_mpi_t calculated_r = NULL;
+  gcry_mpi_t calculated_s = NULL;
+  int cmp;
 
   err = sexp_sscan (&data, NULL, sample_data, strlen (sample_data));
   if (!err)
     err = sexp_sscan (&data_bad, NULL,
                       sample_data_bad, strlen (sample_data_bad));
+  if (!err)
+    err = _gcry_mpi_scan (&r, GCRYMPI_FMT_HEX, signature_r, 0, NULL);
+  if (!err)
+    err = _gcry_mpi_scan (&s, GCRYMPI_FMT_HEX, signature_s, 0, NULL);
+
   if (err)
     {
       errtxt = "converting data failed";
@@ -1189,6 +1235,46 @@ selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
       errtxt = "signing failed";
       goto leave;
     }
+
+  /* check against known signature */
+  errtxt = "signature validity failed";
+  l1 = _gcry_sexp_find_token (sig, "sig-val", 0);
+  if (!l1)
+    goto leave;
+  l2 = _gcry_sexp_find_token (l1, "dsa", 0);
+  if (!l2)
+    goto leave;
+
+  sexp_release (l1);
+  l1 = l2;
+
+  l2 = _gcry_sexp_find_token (l1, "r", 0);
+  if (!l2)
+    goto leave;
+  calculated_r = _gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
+  if (!calculated_r)
+    goto leave;
+
+  sexp_release (l2);
+  l2 = _gcry_sexp_find_token (l1, "s", 0);
+  if (!l2)
+    goto leave;
+  calculated_s = _gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
+  if (!calculated_s)
+    goto leave;
+
+  errtxt = "known sig check failed";
+
+  cmp = _gcry_mpi_cmp (r, calculated_r);
+  if (cmp)
+    goto leave;
+  cmp = _gcry_mpi_cmp (s, calculated_s);
+  if (cmp)
+    goto leave;
+
+  errtxt = NULL;
+
+
   err = _gcry_pk_verify (sig, data, pkey);
   if (err)
     {
@@ -1204,6 +1290,12 @@ selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
 
 
  leave:
+  _gcry_mpi_release (calculated_s);
+  _gcry_mpi_release (calculated_r);
+  _gcry_mpi_release (s);
+  _gcry_mpi_release (r);
+  sexp_release (l2);
+  sexp_release (l1);
   sexp_release (sig);
   sexp_release (data_bad);
   sexp_release (data);
@@ -1212,7 +1304,7 @@ selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
 
 
 static gpg_err_code_t
-selftests_dsa (selftest_report_func_t report)
+selftests_dsa_2048 (selftest_report_func_t report)
 {
   const char *what;
   const char *errtxt;
@@ -1222,10 +1314,10 @@ selftests_dsa (selftest_report_func_t report)
 
   /* Convert the S-expressions into the internal representation.  */
   what = "convert";
-  err = sexp_sscan (&skey, NULL, sample_secret_key, strlen (sample_secret_key));
+  err = sexp_sscan (&skey, NULL, sample_secret_key_2048, strlen (sample_secret_key_2048));
   if (!err)
     err = sexp_sscan (&pkey, NULL,
-                      sample_public_key, strlen (sample_public_key));
+                      sample_public_key_2048, strlen (sample_public_key_2048));
   if (err)
     {
       errtxt = _gcry_strerror (err);
@@ -1241,7 +1333,7 @@ selftests_dsa (selftest_report_func_t report)
     }
 
   what = "sign";
-  errtxt = selftest_sign_1024 (pkey, skey);
+  errtxt = selftest_sign (pkey, skey);
   if (errtxt)
     goto failed;
 
@@ -1269,7 +1361,7 @@ run_selftests (int algo, int extended, selftest_report_func_t report)
   switch (algo)
     {
     case GCRY_PK_DSA:
-      ec = selftests_dsa (report);
+      ec = selftests_dsa_2048 (report);
       break;
     default:
       ec = GPG_ERR_PUBKEY_ALGO;
@@ -1280,7 +1372,6 @@ run_selftests (int algo, int extended, selftest_report_func_t report)
 }
 
 
-
 \f
 gcry_pk_spec_t _gcry_pubkey_spec_dsa =
   {
index f066b4b..748e6db 100644 (file)
@@ -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,
@@ -88,11 +89,11 @@ elliptic_curve_t _gcry_ecc_curve_copy (elliptic_curve_t E);
 const char *_gcry_ecc_model2str (enum gcry_mpi_ec_models model);
 const char *_gcry_ecc_dialect2str (enum ecc_dialects dialect);
 gcry_mpi_t   _gcry_ecc_ec2os (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t p);
-gcry_err_code_t _gcry_ecc_os2ec (mpi_point_t result, gcry_mpi_t value);
 
 mpi_point_t  _gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec,
                                        mpi_point_t G, gcry_mpi_t d);
 
+
 /*-- ecc.c --*/
 
 /*-- ecc-ecdsa.c --*/
@@ -112,17 +113,15 @@ gpg_err_code_t _gcry_ecc_eddsa_encodepoint (mpi_point_t point, mpi_ec_t ctx,
                                             unsigned int *r_buflen);
 gpg_err_code_t _gcry_ecc_eddsa_ensure_compact (gcry_mpi_t value,
                                                unsigned int nbits);
-gpg_err_code_t _gcry_ecc_eddsa_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx,
-                                            mpi_point_t result,
-                                            unsigned char **r_encpk,
-                                            unsigned int *r_encpklen);
+
+
 gpg_err_code_t _gcry_ecc_eddsa_compute_h_d (unsigned char **r_digest,
                                             gcry_mpi_t d, mpi_ec_t ec);
 
 gpg_err_code_t _gcry_ecc_eddsa_genkey (ECC_secret_key *sk,
                                        elliptic_curve_t *E,
                                        mpi_ec_t ctx,
-                                       gcry_random_level_t random_level);
+                                       int flags);
 gpg_err_code_t _gcry_ecc_eddsa_sign (gcry_mpi_t input,
                                      ECC_secret_key *sk,
                                      gcry_mpi_t r_r, gcry_mpi_t s,
index 306f2ad..3488ed3 100644 (file)
@@ -40,7 +40,7 @@ static const struct
   const char *other; /* Other name. */
 } curve_aliases[] =
   {
-  /*{ "Curve25519", "1.3.6.1.4.1.3029.1.5.1" },*/
+    { "Curve25519", "1.3.6.1.4.1.3029.1.5.1" },
     { "Ed25519",    "1.3.6.1.4.1.11591.15.1" },
 
     { "NIST P-192", "1.2.840.10045.3.1.1" }, /* X9.62 OID  */
@@ -73,6 +73,20 @@ static const struct
     { "brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11"},
     { "brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13"},
 
+    { "GOST2001-test", "1.2.643.2.2.35.0" },
+    { "GOST2001-CryptoPro-A", "1.2.643.2.2.35.1" },
+    { "GOST2001-CryptoPro-B", "1.2.643.2.2.35.2" },
+    { "GOST2001-CryptoPro-C", "1.2.643.2.2.35.3" },
+    { "GOST2001-CryptoPro-A", "GOST2001-CryptoPro-XchA" },
+    { "GOST2001-CryptoPro-C", "GOST2001-CryptoPro-XchB" },
+    { "GOST2001-CryptoPro-A", "1.2.643.2.2.36.0" },
+    { "GOST2001-CryptoPro-C", "1.2.643.2.2.36.1" },
+
+    { "GOST2012-tc26-A", "1.2.643.7.1.2.1.2.1" },
+    { "GOST2012-tc26-B", "1.2.643.7.1.2.1.2.2" },
+
+    { "secp256k1", "1.3.132.0.10" },
+
     { NULL, NULL}
   };
 
@@ -93,9 +107,11 @@ typedef struct
 
   const char *p;              /* The prime defining the field.  */
   const char *a, *b;          /* The coefficients.  For Twisted Edwards
-                                 Curves b is used for d.  */
+                                 Curves b is used for d.  For Montgomery
+                                 Curves (a,b) has ((A-2)/4,B^-1).  */
   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;
 
 
@@ -105,16 +121,46 @@ static const ecc_domain_parms_t domain_parms[] =
     {
       /* (-x^2 + y^2 = 1 + dx^2y^2) */
       "Ed25519", 256, 0,
-      MPI_EC_TWISTEDEDWARDS, ECC_DIALECT_ED25519,
+      MPI_EC_EDWARDS, ECC_DIALECT_ED25519,
       "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED",
       "-0x01",
       "-0x2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A",
       "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED",
       "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A",
-      "0x6666666666666666666666666666666666666666666666666666666666666658"
+      "0x6666666666666666666666666666666666666666666666666666666666666658",
+      "0x08"
+    },
+    {
+      /* (y^2 = x^3 + 486662*x^2 + x) */
+      "Curve25519", 256, 0,
+      MPI_EC_MONTGOMERY, ECC_DIALECT_STANDARD,
+      "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED",
+      "0x01DB41",
+      "0x01",
+      "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED",
+      "0x0000000000000000000000000000000000000000000000000000000000000009",
+      "0x20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9",
+      "0x08"
+    },
+#if 0 /* No real specs yet found.  */
+    {
+      /* x^2 + y^2 = 1 + 3617x^2y^2 mod 2^414 - 17 */
+      "Curve3617",
+      "0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+      "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF",
+      MPI_EC_EDWARDS, 0,
+      "0x01",
+      "0x0e21",
+      "0x07FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB3CC92414CF"
+      "706022B36F1C0338AD63CF181B0E71A5E106AF79",
+      "0x1A334905141443300218C0631C326E5FCD46369F44C03EC7F57FF35498A4AB4D"
+      "6D6BA111301A73FAA8537C64C4FD3812F3CBC595",
+      "0x22",
+      "0x08"
     },
+#endif /*0*/
     {
-      "NIST P-192", 192, 1,
+      "NIST P-192", 192, 0,
       MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
       "0xfffffffffffffffffffffffffffffffeffffffffffffffff",
       "0xfffffffffffffffffffffffffffffffefffffffffffffffc",
@@ -122,7 +168,8 @@ static const ecc_domain_parms_t domain_parms[] =
       "0xffffffffffffffffffffffff99def836146bc9b1b4d22831",
 
       "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012",
-      "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811"
+      "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811",
+      "0x01"
     },
     {
       "NIST P-224", 224, 1,
@@ -133,7 +180,8 @@ static const ecc_domain_parms_t domain_parms[] =
       "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" ,
 
       "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
-      "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34"
+      "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34",
+      "0x01"
     },
     {
       "NIST P-256", 256, 1,
@@ -144,7 +192,8 @@ static const ecc_domain_parms_t domain_parms[] =
       "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
 
       "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
-      "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"
+      "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
+      "0x01"
     },
     {
       "NIST P-384", 384, 1,
@@ -161,7 +210,8 @@ static const ecc_domain_parms_t domain_parms[] =
       "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38"
       "5502f25dbf55296c3a545e3872760ab7",
       "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0"
-      "0a60b1ce1d7e819d7a431d7c90ea0e5f"
+      "0a60b1ce1d7e819d7a431d7c90ea0e5f",
+      "0x01"
     },
     {
       "NIST P-521", 521, 1,
@@ -178,7 +228,8 @@ static const ecc_domain_parms_t domain_parms[] =
       "0x00c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d"
       "3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
       "0x011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e"
-      "662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650"
+      "662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
+      "0x01"
     },
 
     { "brainpoolP160r1", 160, 0,
@@ -188,7 +239,8 @@ static const ecc_domain_parms_t domain_parms[] =
       "0x1e589a8595423412134faa2dbdec95c8d8675e58",
       "0xe95e4a5f737059dc60df5991d45029409e60fc09",
       "0xbed5af16ea3f6a4f62938c4631eb5af7bdbcdbc3",
-      "0x1667cb477a1a8ec338f94741669c976316da6321"
+      "0x1667cb477a1a8ec338f94741669c976316da6321",
+      "0x01"
     },
 
     { "brainpoolP192r1", 192, 0,
@@ -198,7 +250,8 @@ static const ecc_domain_parms_t domain_parms[] =
       "0x469a28ef7c28cca3dc721d044f4496bcca7ef4146fbf25c9",
       "0xc302f41d932a36cda7a3462f9e9e916b5be8f1029ac4acc1",
       "0xc0a0647eaab6a48753b033c56cb0f0900a2f5c4853375fd6",
-      "0x14b690866abd5bb88b5f4828c1490002e6773fa2fa299b8f"
+      "0x14b690866abd5bb88b5f4828c1490002e6773fa2fa299b8f",
+      "0x01"
     },
 
     { "brainpoolP224r1", 224, 0,
@@ -208,7 +261,8 @@ static const ecc_domain_parms_t domain_parms[] =
       "0x2580f63ccfe44138870713b1a92369e33e2135d266dbb372386c400b",
       "0xd7c134aa264366862a18302575d0fb98d116bc4b6ddebca3a5a7939f",
       "0x0d9029ad2c7e5cf4340823b2a87dc68c9e4ce3174c1e6efdee12c07d",
-      "0x58aa56f772c0726f24c6b89e4ecdac24354b9e99caa3f6d3761402cd"
+      "0x58aa56f772c0726f24c6b89e4ecdac24354b9e99caa3f6d3761402cd",
+      "0x01"
     },
 
     { "brainpoolP256r1", 256, 0,
@@ -218,7 +272,8 @@ static const ecc_domain_parms_t domain_parms[] =
       "0x26dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b6",
       "0xa9fb57dba1eea9bc3e660a909d838d718c397aa3b561a6f7901e0e82974856a7",
       "0x8bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262",
-      "0x547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f046997"
+      "0x547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f046997",
+      "0x01"
     },
 
     { "brainpoolP320r1", 320, 0,
@@ -234,7 +289,8 @@ static const ecc_domain_parms_t domain_parms[] =
       "0x43bd7e9afb53d8b85289bcc48ee5bfe6f20137d10a087eb6e7871e2a10a599c7"
       "10af8d0d39e20611",
       "0x14fdd05545ec1cc8ab4093247f77275e0743ffed117182eaa9c77877aaac6ac7"
-      "d35245d1692e8ee1"
+      "d35245d1692e8ee1",
+      "0x01"
     },
 
     { "brainpoolP384r1", 384, 0,
@@ -250,7 +306,8 @@ static const ecc_domain_parms_t domain_parms[] =
       "0x1d1c64f068cf45ffa2a63a81b7c13f6b8847a3e77ef14fe3db7fcafe0cbd10e8"
       "e826e03436d646aaef87b2e247d4af1e",
       "0x8abe1d7520f9c2a45cb1eb8e95cfd55262b70b29feec5864e19c054ff9912928"
-      "0e4646217791811142820341263c5315"
+      "0e4646217791811142820341263c5315",
+      "0x01"
     },
 
     { "brainpoolP512r1", 512, 0,
@@ -266,7 +323,8 @@ static const ecc_domain_parms_t domain_parms[] =
       "0x81aee4bdd82ed9645a21322e9c4c6a9385ed9f70b5d916c1b43b62eef4d0098e"
       "ff3b1f78e2d0d48d50d1687b93b97d5f7c6d5047406a5e688b352209bcb9f822",
       "0x7dde385d566332ecc0eabfa9cf7822fdf209f70024a57b1aa000c55b881f8111"
-      "b2dcde494a5f485e5bca4bd88a2763aed1ca2b2fa8f0540678cd1e0f3ad80892"
+      "b2dcde494a5f485e5bca4bd88a2763aed1ca2b2fa8f0540678cd1e0f3ad80892",
+      "0x01"
     },
     {
       "GOST2001-test", 256, 0,
@@ -278,8 +336,41 @@ static const ecc_domain_parms_t domain_parms[] =
 
       "0x0000000000000000000000000000000000000000000000000000000000000002",
       "0x08e2a8a0e65147d4bd6316030e16d19c85c97f0a9ca267122b96abbcea7e8fc8",
+      "0x01"
+    },
+    {
+      "GOST2001-CryptoPro-A", 256, 0,
+      MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+      "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd97",
+      "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd94",
+      "0x00000000000000000000000000000000000000000000000000000000000000a6",
+      "0xffffffffffffffffffffffffffffffff6c611070995ad10045841b09b761b893",
+      "0x0000000000000000000000000000000000000000000000000000000000000001",
+      "0x8d91e471e0989cda27df505a453f2b7635294f2ddf23e3b122acc99c9e9f1e14",
+      "0x01"
+    },
+    {
+      "GOST2001-CryptoPro-B", 256, 0,
+      MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+      "0x8000000000000000000000000000000000000000000000000000000000000c99",
+      "0x8000000000000000000000000000000000000000000000000000000000000c96",
+      "0x3e1af419a269a5f866a7d3c25c3df80ae979259373ff2b182f49d4ce7e1bbc8b",
+      "0x800000000000000000000000000000015f700cfff1a624e5e497161bcc8a198f",
+      "0x0000000000000000000000000000000000000000000000000000000000000001",
+      "0x3fa8124359f96680b83d1c3eb2c070e5c545c9858d03ecfb744bf8d717717efc",
+      "0x01"
+    },
+    {
+      "GOST2001-CryptoPro-C", 256, 0,
+      MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+      "0x9b9f605f5a858107ab1ec85e6b41c8aacf846e86789051d37998f7b9022d759b",
+      "0x9b9f605f5a858107ab1ec85e6b41c8aacf846e86789051d37998f7b9022d7598",
+      "0x000000000000000000000000000000000000000000000000000000000000805a",
+      "0x9b9f605f5a858107ab1ec85e6b41c8aa582ca3511eddfb74f02f3a6598980bb9",
+      "0x0000000000000000000000000000000000000000000000000000000000000000",
+      "0x41ece55743711a8c3cbf3783cd08c0ee4d4dc440d4641a8f366e550dfdb3bb67",
+      "0x01"
     },
-
     {
       "GOST2012-test", 511, 0,
       MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
@@ -295,9 +386,56 @@ static const ecc_domain_parms_t domain_parms[] =
       "fd60611262cd838dc6b60aa7eee804e28bc849977fac33b4b530f1b120248a9a",
       "0x2bb312a43bd2ce6e0d020613c857acddcfbf061e91e5f2c3f32447c259f39b2"
       "c83ab156d77f1496bf7eb3351e1ee4e43dc1a18b91b24640b6dbb92cb1add371e",
+      "0x01"
+    },
+    {
+      "GOST2012-tc26-A", 512, 0,
+      MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+      "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+        "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc7",
+      "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+        "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc4",
+      "0xe8c2505dedfc86ddc1bd0b2b6667f1da34b82574761cb0e879bd081cfd0b6265"
+        "ee3cb090f30d27614cb4574010da90dd862ef9d4ebee4761503190785a71c760",
+      "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+        "27e69532f48d89116ff22b8d4e0560609b4b38abfad2b85dcacdb1411f10b275",
+      "0x0000000000000000000000000000000000000000000000000000000000000000"
+        "0000000000000000000000000000000000000000000000000000000000000003",
+      "0x7503cfe87a836ae3a61b8816e25450e6ce5e1c93acf1abc1778064fdcbefa921"
+        "df1626be4fd036e93d75e6a50e3a41e98028fe5fc235f5b889a589cb5215f2a4",
+      "0x01"
+    },
+    {
+      "GOST2012-tc26-B", 512, 0,
+      MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+      "0x8000000000000000000000000000000000000000000000000000000000000000"
+        "000000000000000000000000000000000000000000000000000000000000006f",
+      "0x8000000000000000000000000000000000000000000000000000000000000000"
+        "000000000000000000000000000000000000000000000000000000000000006c",
+      "0x687d1b459dc841457e3e06cf6f5e2517b97c7d614af138bcbf85dc806c4b289f"
+        "3e965d2db1416d217f8b276fad1ab69c50f78bee1fa3106efb8ccbc7c5140116",
+      "0x8000000000000000000000000000000000000000000000000000000000000001"
+        "49a1ec142565a545acfdb77bd9d40cfa8b996712101bea0ec6346c54374f25bd",
+      "0x0000000000000000000000000000000000000000000000000000000000000000"
+        "0000000000000000000000000000000000000000000000000000000000000002",
+      "0x1a8f7eda389b094c2c071e3647a8940f3c123b697578c213be6dd9e6c8ec7335"
+        "dcb228fd1edf4a39152cbcaaf8c0398828041055f94ceeec7e21340780fe41bd",
+      "0x01"
+    },
+
+    {
+      "secp256k1", 256, 0,
+      MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+      "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F",
+      "0x0000000000000000000000000000000000000000000000000000000000000000",
+      "0x0000000000000000000000000000000000000000000000000000000000000007",
+      "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",
+      "0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798",
+      "0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8",
+      "0x01"
     },
 
-    { NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL }
+    { NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }
   };
 
 
@@ -404,10 +542,9 @@ _gcry_ecc_fill_in_curve (unsigned int nbits, const char *name,
   switch (domain_parms[idx].model)
     {
     case MPI_EC_WEIERSTRASS:
-    case MPI_EC_TWISTEDEDWARDS:
-      break;
+    case MPI_EC_EDWARDS:
     case MPI_EC_MONTGOMERY:
-      return GPG_ERR_NOT_SUPPORTED;
+      break;
     default:
       return GPG_ERR_BUG;
     }
@@ -423,11 +560,21 @@ _gcry_ecc_fill_in_curve (unsigned int nbits, const char *name,
       if (!curve->p)
         curve->p = scanval (domain_parms[idx].p);
       if (!curve->a)
-        curve->a = scanval (domain_parms[idx].a);
+        {
+          curve->a = scanval (domain_parms[idx].a);
+          if (curve->a->sign)
+            mpi_add (curve->a, curve->p, curve->a);
+        }
       if (!curve->b)
-        curve->b = scanval (domain_parms[idx].b);
+        {
+          curve->b = scanval (domain_parms[idx].b);
+          if (curve->b->sign)
+            mpi_add (curve->b, curve->p, curve->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)
@@ -443,7 +590,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
@@ -451,7 +598,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;
 
@@ -501,6 +648,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;
 }
 
@@ -538,8 +690,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)
     {
@@ -597,17 +749,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;
+                                }
                             }
                         }
                     }
@@ -624,6 +781,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;
 }
 
@@ -755,6 +913,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;
@@ -797,6 +956,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
@@ -870,6 +1032,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);
     }
@@ -896,6 +1063,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
@@ -934,6 +1106,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;
@@ -948,7 +1121,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;
 
@@ -972,14 +1145,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++)
@@ -1006,6 +1180,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);
 
@@ -1039,7 +1215,7 @@ _gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy)
       if (name[1] != '@')
         return _gcry_mpi_ec_ec2os (ec->Q, ec);
 
-      if (!strcmp (name+2, "eddsa") && ec->model == MPI_EC_TWISTEDEDWARDS)
+      if (!strcmp (name+2, "eddsa") && ec->model == MPI_EC_EDWARDS)
         {
           unsigned char *encpk;
           unsigned int encpklen;
@@ -1104,6 +1280,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)
index 65024a3..f91f848 100644 (file)
@@ -251,7 +251,7 @@ _gcry_ecc_eddsa_recover_x (gcry_mpi_t x, gcry_mpi_t y, int sign, mpi_ec_t ec)
   mpi_mulm (t, x, x, ec->p);
   mpi_mulm (t, t, v, ec->p);
   /* -t == u ? x = x * sqrt(-1) */
-  mpi_neg (t, t);
+  mpi_sub (t, ec->p, t);
   if (!mpi_cmp (t, u))
     {
       static gcry_mpi_t m1;  /* Fixme: this is not thread-safe.  */
@@ -263,7 +263,7 @@ _gcry_ecc_eddsa_recover_x (gcry_mpi_t x, gcry_mpi_t y, int sign, mpi_ec_t ec)
       mpi_mulm (t, x, x, ec->p);
       mpi_mulm (t, t, v, ec->p);
       /* -t == u ? x = x * sqrt(-1) */
-      mpi_neg (t, t);
+      mpi_sub (t, ec->p, t);
       if (!mpi_cmp (t, u))
         rc = GPG_ERR_INV_OBJ;
     }
@@ -465,15 +465,28 @@ _gcry_ecc_eddsa_compute_h_d (unsigned char **r_digest,
 }
 
 
-/* Ed25519 version of the key generation.  */
+/**
+ * _gcry_ecc_eddsa_genkey - EdDSA version of the key generation.
+ *
+ * @sk:  A struct to receive the secret key.
+ * @E:   Parameters of the curve.
+ * @ctx: Elliptic curve computation context.
+ * @flags: Flags controlling aspects of the creation.
+ *
+ * Return: An error code.
+ *
+ * The only @flags bit used by this function is %PUBKEY_FLAG_TRANSIENT
+ * to use a faster RNG.
+ */
 gpg_err_code_t
 _gcry_ecc_eddsa_genkey (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx,
-                        gcry_random_level_t random_level)
+                        int flags)
 {
   gpg_err_code_t rc;
   int b = 256/8;             /* The only size we currently support.  */
   gcry_mpi_t a, x, y;
   mpi_point_struct Q;
+  gcry_random_level_t random_level;
   char *dbuf;
   size_t dlen;
   gcry_buffer_t hvec[1];
@@ -482,6 +495,11 @@ _gcry_ecc_eddsa_genkey (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx,
   point_init (&Q);
   memset (hvec, 0, sizeof hvec);
 
+  if ((flags & PUBKEY_FLAG_TRANSIENT_KEY))
+    random_level = GCRY_STRONG_RANDOM;
+  else
+    random_level = GCRY_VERY_STRONG_RANDOM;
+
   a = mpi_snew (0);
   x = mpi_new (0);
   y = mpi_new (0);
@@ -490,7 +508,7 @@ _gcry_ecc_eddsa_genkey (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx,
   hash_d = xtrymalloc_secure (2*b);
   if (!hash_d)
     {
-      rc = gpg_error_from_syserror ();
+      rc = gpg_err_code_from_syserror ();
       goto leave;
     }
   dlen = b;
@@ -525,6 +543,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);
 
@@ -561,7 +580,7 @@ _gcry_ecc_eddsa_sign (gcry_mpi_t input, ECC_secret_key *skey,
   mpi_ec_t ctx = NULL;
   int b;
   unsigned int tmp;
-  unsigned char *digest;
+  unsigned char *digest = NULL;
   gcry_buffer_t hvec[3];
   const void *mbuf;
   size_t mlen;
@@ -588,8 +607,10 @@ _gcry_ecc_eddsa_sign (gcry_mpi_t input, ECC_secret_key *skey,
   ctx = _gcry_mpi_ec_p_internal_new (skey->E.model, skey->E.dialect, 0,
                                      skey->E.p, skey->E.a, skey->E.b);
   b = (ctx->nbits+7)/8;
-  if (b != 256/8)
-    return GPG_ERR_INTERNAL; /* We only support 256 bit. */
+  if (b != 256/8) {
+    rc = GPG_ERR_INTERNAL; /* We only support 256 bit. */
+    goto leave;
+  }
 
   rc = _gcry_ecc_eddsa_compute_h_d (&digest, skey->d, ctx);
   if (rc)
@@ -814,7 +835,7 @@ _gcry_ecc_eddsa_verify (gcry_mpi_t input, ECC_public_key *pkey,
 
   _gcry_mpi_ec_mul_point (&Ia, s, &pkey->E.G, ctx);
   _gcry_mpi_ec_mul_point (&Ib, h, &Q, ctx);
-  _gcry_mpi_neg (Ib.x, Ib.x);
+  _gcry_mpi_sub (Ib.x, ctx->p, Ib.x);
   _gcry_mpi_ec_add_points (&Ia, &Ia, &Ib, ctx);
   rc = _gcry_ecc_eddsa_encodepoint (&Ia, ctx, s, h, 0, &tbuf, &tlen);
   if (rc)
index 7b750c0..8f7b8c4 100644 (file)
@@ -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;
 }
@@ -79,7 +81,7 @@ _gcry_ecc_model2str (enum gcry_mpi_ec_models model)
     {
     case MPI_EC_WEIERSTRASS:    str = "Weierstrass"; break;
     case MPI_EC_MONTGOMERY:     str = "Montgomery";  break;
-    case MPI_EC_TWISTEDEDWARDS: str = "Twisted Edwards"; break;
+    case MPI_EC_EDWARDS:        str = "Edwards"; break;
     }
   return str;
 }
@@ -252,7 +254,7 @@ _gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec,
 
   if (!d || !G || !ec->p || !ec->a)
     return NULL;
-  if (ec->model == MPI_EC_TWISTEDEDWARDS && !ec->b)
+  if (ec->model == MPI_EC_EDWARDS && !ec->b)
     return NULL;
 
   if (ec->dialect == ECC_DIALECT_ED25519
@@ -285,3 +287,83 @@ _gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec,
 
   return Q;
 }
+
+
+gpg_err_code_t
+_gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, mpi_point_t result)
+{
+  unsigned char *rawmpi;
+  unsigned int rawmpilen;
+
+  if (mpi_is_opaque (pk))
+    {
+      const unsigned char *buf;
+      unsigned char *p;
+
+      buf = mpi_get_opaque (pk, &rawmpilen);
+      if (!buf)
+        return GPG_ERR_INV_OBJ;
+      rawmpilen = (rawmpilen + 7)/8;
+
+      if (rawmpilen > 1 && (rawmpilen%2) && buf[0] == 0x40)
+        {
+          rawmpilen--;
+          buf++;
+        }
+
+      rawmpi = xtrymalloc (rawmpilen? rawmpilen:1);
+      if (!rawmpi)
+        return gpg_err_code_from_syserror ();
+
+      p = rawmpi + rawmpilen;
+      while (p > rawmpi)
+        *--p = *buf++;
+    }
+  else
+    {
+      unsigned int nbytes = (ctx->nbits+7)/8;
+
+      rawmpi = _gcry_mpi_get_buffer (pk, nbytes, &rawmpilen, NULL);
+      if (!rawmpi)
+        return gpg_err_code_from_syserror ();
+      /*
+       * It is not reliable to assume that 0x40 means the prefix.
+       *
+       * For newer implementation, it is reliable since we always put
+       * 0x40 for x-only coordinate.
+       *
+       * For data with older implementation (non-released development
+       * version), it is possibe to have the 0x40 as a part of data.
+       * Besides, when data was parsed as MPI, we might have 0x00
+       * prefix.
+       *
+       * So, we need to check if it's really the prefix or not.
+       * Only when it's the prefix, we remove it.
+       */
+      if (pk->nlimbs * BYTES_PER_MPI_LIMB < nbytes)
+        {/*
+          * It is possible for data created by older implementation
+          * to have shorter length when it was parsed as MPI.
+          */
+          unsigned int len = pk->nlimbs * BYTES_PER_MPI_LIMB;
+
+          memmove (rawmpi + nbytes - len, rawmpi, len);
+          memset (rawmpi, 0, nbytes - len);
+        }
+
+      /*
+       * When we have the prefix (0x40 or 0x00), it comes at the end,
+       * since it is taken by _gcry_mpi_get_buffer with little endian.
+       * Just setting RAWMPILEN to NBYTES is enough in this case.
+       * Othewise, RAWMPILEN is NBYTES already.
+       */
+      rawmpilen = nbytes;
+    }
+
+  rawmpi[0] &= (1 << (ctx->nbits % 8)) - 1;
+  _gcry_mpi_set_buffer (result->x, rawmpi, rawmpilen, 0);
+  xfree (rawmpi);
+  mpi_set_ui (result->z, 1);
+
+  return 0;
+}
index 885ff09..b09902e 100644 (file)
@@ -1,6 +1,6 @@
 /* ecc.c  -  Elliptic Curve Cryptography
  * Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc.
- * Copyright (C) 2013 g10 Code GmbH
+ * Copyright (C) 2013, 2015 g10 Code GmbH
  *
  * This file is part of Libgcrypt.
  *
@@ -30,7 +30,7 @@
       Ramiro Moreno Chiral
       Mikael Mylnikov (mmr)
   For use in Libgcrypt the code has been heavily modified and cleaned
-  up. In fact there is not much left of the orginally code except for
+  up. In fact there is not much left of the originally code except for
   some variable names and the text book implementaion of the sign and
   verification algorithms.  The arithmetic functions have entirely
   been rewritten and moved to mpi/ec.c.
@@ -73,6 +73,25 @@ static const char *ecc_names[] =
   };
 
 
+/* Sample NIST P-256 key from RFC 6979 A.2.5 */
+static const char sample_public_key_secp256[] =
+  "(public-key"
+  " (ecc"
+  "  (curve secp256r1)"
+  "  (q #04"
+  /**/  "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6"
+  /**/  "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299#)))";
+
+static const char sample_secret_key_secp256[] =
+  "(private-key"
+  " (ecc"
+  "  (curve secp256r1)"
+  "  (d #C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721#)"
+  "  (q #04"
+  /**/  "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6"
+  /**/  "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299#)))";
+
+
 /* Registered progress function and its callback value. */
 static void (*progress_cb) (void *, const char*, int, int, int);
 static void *progress_cb_data;
@@ -81,6 +100,7 @@ static void *progress_cb_data;
 \f
 /* 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, int flags);
 static unsigned int ecc_get_nbits (gcry_sexp_t parms);
 
 
@@ -104,17 +124,44 @@ _gcry_register_pk_ecc_progress (void (*cb) (void *, const char *,
 
 
 \f
-/* Standard version of the key generation.  */
+/**
+ * nist_generate_key - Standard version of the ECC key generation.
+ * @sk:  A struct to receive the secret key.
+ * @E:   Parameters of the curve.
+ * @ctx: Elliptic curve computation context.
+ * @flags: Flags controlling aspects of the creation.
+ * @nbits: Only for testing
+ * @r_x: On success this receives an allocated MPI with the affine
+ *       x-coordinate of the poblic key.  On error NULL is stored.
+ * @r_y: Ditto for the y-coordinate.
+ *
+ * Return: An error code.
+ *
+ * The @flags bits used by this function are %PUBKEY_FLAG_TRANSIENT to
+ * use a faster RNG, and %PUBKEY_FLAG_NO_KEYTEST to skip the assertion
+ * that the key works as expected.
+ *
+ * FIXME: Check whether N is needed.
+ */
 static gpg_err_code_t
 nist_generate_key (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx,
-                   gcry_random_level_t random_level, unsigned int nbits)
+                   int flags, unsigned int nbits,
+                   gcry_mpi_t *r_x, gcry_mpi_t *r_y)
 {
   mpi_point_struct Q;
+  gcry_random_level_t random_level;
+  gcry_mpi_t x, y;
+  const unsigned int pbits = mpi_get_nbits (E->p);
 
   point_init (&Q);
 
+  if ((flags & PUBKEY_FLAG_TRANSIENT_KEY))
+    random_level = GCRY_STRONG_RANDOM;
+  else
+    random_level = GCRY_VERY_STRONG_RANDOM;
+
   /* Generate a secret.  */
-  if (ctx->dialect == ECC_DIALECT_ED25519)
+  if (ctx->dialect == ECC_DIALECT_ED25519 || (flags & PUBKEY_FLAG_DJB_TWEAK))
     {
       char *rndbuf;
 
@@ -142,8 +189,17 @@ 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);
 
+  x = mpi_new (pbits);
+  if (r_y == NULL)
+    y = NULL;
+  else
+    y = mpi_new (pbits);
+  if (_gcry_mpi_ec_get_affine (x, y, &Q, ctx))
+    log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "Q");
+
   /* We want the Q=(x,y) be a "compliant key" in terms of the
    * http://tools.ietf.org/html/draft-jivsov-ecc-compact, which simply
    * means that we choose either Q=(x,y) or -Q=(x,p-y) such that we
@@ -153,20 +209,14 @@ nist_generate_key (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx,
    * possibilities without any loss of security.  Note that we don't
    * do that for Ed25519 so that we do not violate the special
    * construction of the secret key.  */
-  if (E->dialect == ECC_DIALECT_ED25519)
+  if (r_y == NULL || E->dialect == ECC_DIALECT_ED25519)
     point_set (&sk->Q, &Q);
   else
     {
-      gcry_mpi_t x, y, negative;
-      const unsigned int pbits = mpi_get_nbits (E->p);
+      gcry_mpi_t negative;
 
-      x = mpi_new (pbits);
-      y = mpi_new (pbits);
       negative = mpi_new (pbits);
 
-      if (_gcry_mpi_ec_get_affine (x, y, &Q, ctx))
-        log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "Q");
-
       if (E->model == MPI_EC_WEIERSTRASS)
         mpi_sub (negative, E->p, y);      /* negative = p - y */
       else
@@ -176,12 +226,18 @@ nist_generate_key (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx,
         {
           /* We need to end up with -Q; this assures that new Q's y is
              the smallest one */
-          mpi_sub (sk->d, E->n, sk->d);   /* d = order - d */
           if (E->model == MPI_EC_WEIERSTRASS)
-            mpi_point_snatch_set (&sk->Q, x, negative,
-                                       mpi_alloc_set_ui (1));
+            {
+              mpi_free (y);
+              y = negative;
+            }
           else
-            mpi_point_snatch_set (&sk->Q, negative, y, mpi_alloc_set_ui (1));
+            {
+              mpi_free (x);
+              x = negative;
+            }
+          mpi_sub (sk->d, E->n, sk->d);   /* d = order - d */
+          mpi_point_set (&sk->Q, x, y, mpi_const (MPI_C_ONE));
 
           if (DBG_CIPHER)
             log_debug ("ecgen converted Q to a compliant point\n");
@@ -189,26 +245,25 @@ nist_generate_key (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx,
       else /* p - y >= p */
         {
           /* No change is needed exactly 50% of the time: just copy. */
+          mpi_free (negative);
           point_set (&sk->Q, &Q);
           if (DBG_CIPHER)
             log_debug ("ecgen didn't need to convert Q to a compliant point\n");
-
-          mpi_free (negative);
-          if (E->model == MPI_EC_WEIERSTRASS)
-            mpi_free (x);
-          else
-            mpi_free (y);
         }
-
-      if (E->model == MPI_EC_WEIERSTRASS)
-        mpi_free (y);
-      else
-        mpi_free (x);
     }
 
+  *r_x = x;
+  if (r_y)
+    *r_y = y;
+
   point_free (&Q);
   /* Now we can test our keys (this should never fail!).  */
-  test_keys (sk, nbits - 64);
+  if ((flags & PUBKEY_FLAG_NO_KEYTEST))
+    ; /* User requested to skip the test.  */
+  else if (sk->E.model != MPI_EC_MONTGOMERY)
+    test_keys (sk, nbits - 64);
+  else
+    test_ecdh_only_keys (sk, nbits - 64, flags);
 
   return 0;
 }
@@ -265,6 +320,80 @@ test_keys (ECC_secret_key *sk, unsigned int nbits)
 }
 
 
+static void
+test_ecdh_only_keys (ECC_secret_key *sk, unsigned int nbits, int flags)
+{
+  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 ECDH only key.\n");
+
+  point_init (&R_);
+
+  pk.E = _gcry_ecc_curve_copy (sk->E);
+  point_init (&pk.Q);
+  point_set (&pk.Q, &sk->Q);
+
+  if ((flags & PUBKEY_FLAG_DJB_TWEAK))
+    {
+      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, flags,
+                                    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 (!(flags & PUBKEY_FLAG_DJB_TWEAK))
+    _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 (!(flags & PUBKEY_FLAG_DJB_TWEAK))
+    _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.
@@ -280,7 +409,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))
@@ -299,7 +431,7 @@ check_secret_key (ECC_secret_key *sk, mpi_ec_t ec, int flags)
     }
 
   /* Check order of curve.  */
-  if (sk->E.dialect != ECC_DIALECT_ED25519)
+  if (sk->E.dialect != ECC_DIALECT_ED25519 && !(flags & PUBKEY_FLAG_DJB_TWEAK))
     {
       _gcry_mpi_ec_mul_point (&Q, sk->E.n, &sk->E.G, ec);
       if (mpi_cmp_ui (Q.z, 0))
@@ -337,7 +469,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
@@ -388,11 +520,12 @@ ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
   unsigned int nbits;
   elliptic_curve_t E;
   ECC_secret_key sk;
-  gcry_mpi_t x = NULL;
-  gcry_mpi_t y = NULL;
+  gcry_mpi_t Gx = NULL;
+  gcry_mpi_t Gy = NULL;
+  gcry_mpi_t Qx = NULL;
+  gcry_mpi_t Qy = NULL;
   char *curve_name = NULL;
   gcry_sexp_t l1;
-  gcry_random_level_t random_level;
   mpi_ec_t ctx = NULL;
   gcry_sexp_t curve_info = NULL;
   gcry_sexp_t curve_flags = NULL;
@@ -441,7 +574,6 @@ ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
     return GPG_ERR_NO_OBJ; /* No NBITS parameter. */
 
   rc = _gcry_ecc_fill_in_curve (nbits, curve_name, &E, &nbits);
-  xfree (curve_name); curve_name = NULL;
   if (rc)
     goto leave;
 
@@ -456,48 +588,70 @@ 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);
     }
 
-  if ((flags & PUBKEY_FLAG_TRANSIENT_KEY))
-    random_level = GCRY_STRONG_RANDOM;
-  else
-    random_level = GCRY_VERY_STRONG_RANDOM;
+  ctx = _gcry_mpi_ec_p_internal_new (E.model, E.dialect, flags, E.p, E.a, E.b);
 
-  ctx = _gcry_mpi_ec_p_internal_new (E.model, E.dialect, 0, E.p, E.a, E.b);
-  x = mpi_new (0);
-  y = mpi_new (0);
-
-  if ((flags & PUBKEY_FLAG_EDDSA))
-    rc = _gcry_ecc_eddsa_genkey (&sk, &E, ctx, random_level);
+  if (E.model == MPI_EC_MONTGOMERY)
+    rc = nist_generate_key (&sk, &E, ctx, flags, nbits, &Qx, NULL);
+  else if ((flags & PUBKEY_FLAG_EDDSA))
+    rc = _gcry_ecc_eddsa_genkey (&sk, &E, ctx, flags);
   else
-    rc = nist_generate_key (&sk, &E, ctx, random_level, nbits);
+    rc = nist_generate_key (&sk, &E, ctx, flags, nbits, &Qx, &Qy);
   if (rc)
     goto leave;
 
   /* Copy data to the result.  */
-  if (_gcry_mpi_ec_get_affine (x, y, &sk.E.G, ctx))
-    log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "G");
-  base = _gcry_ecc_ec2os (x, y, sk.E.p);
-  if (sk.E.dialect == ECC_DIALECT_ED25519 && !(flags & PUBKEY_FLAG_NOCOMP))
+  Gx = mpi_new (0);
+  Gy = mpi_new (0);
+  if (E.model != MPI_EC_MONTGOMERY)
+    {
+      if (_gcry_mpi_ec_get_affine (Gx, Gy, &sk.E.G, ctx))
+        log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "G");
+      base = _gcry_ecc_ec2os (Gx, Gy, sk.E.p);
+    }
+  if ((sk.E.dialect == ECC_DIALECT_ED25519 || E.model == MPI_EC_MONTGOMERY)
+      && !(flags & PUBKEY_FLAG_NOCOMP))
     {
       unsigned char *encpk;
       unsigned int encpklen;
 
-      rc = _gcry_ecc_eddsa_encodepoint (&sk.Q, ctx, x, y,
-                                        !!(flags & PUBKEY_FLAG_COMP),
-                                        &encpk, &encpklen);
+      if (E.model != MPI_EC_MONTGOMERY)
+        /* (Gx and Gy are used as scratch variables)  */
+        rc = _gcry_ecc_eddsa_encodepoint (&sk.Q, ctx, Gx, Gy,
+                                          !!(flags & PUBKEY_FLAG_COMP),
+                                          &encpk, &encpklen);
+      else
+        {
+          encpk = _gcry_mpi_get_buffer_extra (Qx, nbits/8,
+                                              -1, &encpklen, NULL);
+          if (encpk == NULL)
+            rc = gpg_err_code_from_syserror ();
+          else
+            {
+              encpk[0] = 0x40;
+              encpklen++;
+            }
+        }
       if (rc)
-        return rc;
+        goto leave;
       public = mpi_new (0);
       mpi_set_opaque (public, encpk, encpklen*8);
-      encpk = NULL;
     }
   else
     {
-      if (_gcry_mpi_ec_get_affine (x, y, &sk.Q, ctx))
-        log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "Q");
-      public = _gcry_ecc_ec2os (x, y, sk.E.p);
+      if (!Qx)
+        {
+          /* This is the case for a key from _gcry_ecc_eddsa_generate
+             with no compression.  */
+          Qx = mpi_new (0);
+          Qy = mpi_new (0);
+          if (_gcry_mpi_ec_get_affine (Qx, Qy, &sk.Q, ctx))
+            log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "Q");
+        }
+      public = _gcry_ecc_ec2os (Qx, Qy, sk.E.p);
     }
   secret = sk.d; sk.d = NULL;
   if (E.name)
@@ -507,15 +661,18 @@ ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
         goto leave;
     }
 
-  if ((flags & PUBKEY_FLAG_PARAM) || (flags & PUBKEY_FLAG_EDDSA))
+  if ((flags & PUBKEY_FLAG_PARAM) || (flags & PUBKEY_FLAG_EDDSA)
+      || (flags & PUBKEY_FLAG_DJB_TWEAK))
     {
       rc = sexp_build
         (&curve_flags, NULL,
          ((flags & PUBKEY_FLAG_PARAM) && (flags & PUBKEY_FLAG_EDDSA))?
          "(flags param eddsa)" :
+         ((flags & PUBKEY_FLAG_PARAM) && (flags & PUBKEY_FLAG_EDDSA))?
+         "(flags param djb-tweak)" :
          ((flags & PUBKEY_FLAG_PARAM))?
-         "(flags param)" :
-         "(flags eddsa)");
+         "(flags param)" : ((flags & PUBKEY_FLAG_EDDSA))?
+         "(flags eddsa)" : "(flags djb-tweak)" );
       if (rc)
         goto leave;
     }
@@ -524,14 +681,15 @@ 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 +712,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))
@@ -570,9 +729,12 @@ ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
     mpi_free (sk.d);
   }
   _gcry_ecc_curve_free (&E);
-  mpi_free (x);
-  mpi_free (y);
+  mpi_free (Gx);
+  mpi_free (Gy);
+  mpi_free (Qx);
+  mpi_free (Qy);
   _gcry_mpi_ec_free (ctx);
+  xfree (curve_name);
   sexp_release (curve_flags);
   sexp_release (curve_info);
   return rc;
@@ -604,9 +766,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);
@@ -621,12 +783,9 @@ ecc_check_secret_key (gcry_sexp_t keyparms)
       curvename = sexp_nth_string (l1, 1);
       if (curvename)
         {
-          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);
+          rc = _gcry_ecc_fill_in_curve (0, curvename, &sk.E, NULL);
           if (rc)
-            return rc;
+            goto leave;
         }
     }
   if (mpi_g)
@@ -642,7 +801,7 @@ ecc_check_secret_key (gcry_sexp_t keyparms)
   if (!curvename)
     {
       sk.E.model = ((flags & PUBKEY_FLAG_EDDSA)
-               ? MPI_EC_TWISTEDEDWARDS
+               ? MPI_EC_EDWARDS
                : MPI_EC_WEIERSTRASS);
       sk.E.dialect = ((flags & PUBKEY_FLAG_EDDSA)
                       ? ECC_DIALECT_ED25519
@@ -660,17 +819,18 @@ 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;
     }
 
-  ec = _gcry_mpi_ec_p_internal_new (sk.E.model, sk.E.dialect, 0,
+  ec = _gcry_mpi_ec_p_internal_new (sk.E.model, sk.E.dialect, flags,
                                     sk.E.p, sk.E.a, sk.E.b);
 
   if (mpi_q)
@@ -678,6 +838,8 @@ ecc_check_secret_key (gcry_sexp_t keyparms)
       point_init (&sk.Q);
       if (ec->dialect == ECC_DIALECT_ED25519)
         rc = _gcry_ecc_eddsa_decodepoint (mpi_q, ec, &sk.Q, NULL, NULL);
+      else if (ec->model == MPI_EC_MONTGOMERY)
+        rc = _gcry_ecc_mont_decodepoint (mpi_q, ec, &sk.Q);
       else
         rc = _gcry_ecc_os2ec (&sk.Q, mpi_q);
       if (rc)
@@ -701,6 +863,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 +904,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);
@@ -757,7 +920,6 @@ ecc_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
         goto leave;
     }
   /* Add missing parameters using the optional curve parameter.  */
-  sexp_release (l1);
   l1 = sexp_find_token (keyparms, "curve", 5);
   if (l1)
     {
@@ -766,7 +928,7 @@ ecc_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
         {
           rc = _gcry_ecc_fill_in_curve (0, curvename, &sk.E, NULL);
           if (rc)
-            return rc;
+            goto leave;
         }
     }
   /* Guess required fields if a curve parameter has not been given.
@@ -774,7 +936,7 @@ ecc_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
   if (!curvename)
     {
       sk.E.model = ((ctx.flags & PUBKEY_FLAG_EDDSA)
-                    ? MPI_EC_TWISTEDEDWARDS
+                    ? MPI_EC_EDWARDS
                     : MPI_EC_WEIERSTRASS);
       sk.E.dialect = ((ctx.flags & PUBKEY_FLAG_EDDSA)
                       ? ECC_DIALECT_ED25519
@@ -793,11 +955,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 +1001,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 +1069,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.h, &mpi_q, NULL);
   else
     rc = sexp_extract_param (s_keyparms, NULL, "/q",
                              &mpi_q, NULL);
@@ -930,7 +1094,7 @@ ecc_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms)
         {
           rc = _gcry_ecc_fill_in_curve (0, curvename, &pk.E, NULL);
           if (rc)
-            return rc;
+            goto leave;
         }
     }
   /* Guess required fields if a curve parameter has not been given.
@@ -938,7 +1102,7 @@ ecc_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms)
   if (!curvename)
     {
       pk.E.model = ((sigflags & PUBKEY_FLAG_EDDSA)
-                    ? MPI_EC_TWISTEDEDWARDS
+                    ? MPI_EC_EDWARDS
                     : MPI_EC_WEIERSTRASS);
       pk.E.dialect = ((sigflags & PUBKEY_FLAG_EDDSA)
                       ? ECC_DIALECT_ED25519
@@ -958,9 +1122,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 +1201,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);
@@ -1081,6 +1247,7 @@ ecc_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms)
 static gcry_err_code_t
 ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
 {
+  unsigned int nbits;
   gcry_err_code_t rc;
   struct pk_encoding_ctx ctx;
   gcry_sexp_t l1 = NULL;
@@ -1092,10 +1259,22 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
   gcry_mpi_t data = NULL;
   ECC_public_key pk;
   mpi_ec_t ec = NULL;
+  int flags = 0;
 
   memset (&pk, 0, sizeof pk);
   _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT,
-                                   ecc_get_nbits (keyparms));
+                                   (nbits = ecc_get_nbits (keyparms)));
+
+  /* Look for flags. */
+  l1 = sexp_find_token (keyparms, "flags", 0);
+  if (l1)
+    {
+      rc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
+      if (rc)
+        goto leave;
+    }
+  sexp_release (l1);
+  l1 = NULL;
 
   /*
    * Extract the data.
@@ -1103,20 +1282,19 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
   rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
   if (rc)
     goto leave;
-  if (DBG_CIPHER)
-    log_mpidump ("ecc_encrypt data", data);
   if (mpi_is_opaque (data))
     {
       rc = GPG_ERR_INV_DATA;
       goto leave;
     }
 
-
   /*
    * 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,
+                           (flags & PUBKEY_FLAG_DJB_TWEAK)?
+                           "-p?a?b?g?n?h?/q" : "-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;
@@ -1128,7 +1306,6 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
         goto leave;
     }
   /* Add missing parameters using the optional curve parameter.  */
-  sexp_release (l1);
   l1 = sexp_find_token (keyparms, "curve", 5);
   if (l1)
     {
@@ -1137,7 +1314,7 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
         {
           rc = _gcry_ecc_fill_in_curve (0, curvename, &pk.E, NULL);
           if (rc)
-            return rc;
+            goto leave;
         }
     }
   /* Guess required fields if a curve parameter has not been given.  */
@@ -1147,6 +1324,21 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
       pk.E.dialect = ECC_DIALECT_STANDARD;
     }
 
+  /*
+   * Tweak the scalar bits by cofactor and number of bits of the field.
+   * It assumes the cofactor is a power of 2.
+   */
+  if ((flags & PUBKEY_FLAG_DJB_TWEAK))
+    {
+      int i;
+
+      for (i = 0; i < mpi_get_nbits (pk.E.h) - 1; i++)
+        mpi_clear_bit (data, i);
+      mpi_set_highbit (data, mpi_get_nbits (pk.E.p) - 1);
+    }
+  if (DBG_CIPHER)
+    log_mpidump ("ecc_encrypt data", data);
+
   if (DBG_CIPHER)
     {
       log_debug ("ecc_encrypt info: %s/%s\n",
@@ -1159,34 +1351,43 @@ 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;
     }
 
+  /* Compute the encrypted value.  */
+  ec = _gcry_mpi_ec_p_internal_new (pk.E.model, pk.E.dialect, flags,
+                                    pk.E.p, pk.E.a, pk.E.b);
+
   /* Convert the public key.  */
   if (mpi_q)
     {
       point_init (&pk.Q);
-      rc = _gcry_ecc_os2ec (&pk.Q, mpi_q);
+      if (ec->model == MPI_EC_MONTGOMERY)
+        rc = _gcry_ecc_mont_decodepoint (mpi_q, ec, &pk.Q);
+      else
+        rc = _gcry_ecc_os2ec (&pk.Q, mpi_q);
       if (rc)
         goto leave;
     }
 
-  /* Compute the encrypted value.  */
-  ec = _gcry_mpi_ec_p_internal_new (pk.E.model, pk.E.dialect, 0,
-                                    pk.E.p, pk.E.a, pk.E.b);
-
   /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so */
   {
     mpi_point_struct R;  /* Result that we return.  */
     gcry_mpi_t x, y;
+    unsigned char *rawmpi;
+    unsigned int rawmpilen;
 
     x = mpi_new (0);
-    y = mpi_new (0);
+    if (ec->model == MPI_EC_MONTGOMERY)
+      y = NULL;
+    else
+      y = mpi_new (0);
 
     point_init (&R);
 
@@ -1194,15 +1395,63 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
     _gcry_mpi_ec_mul_point (&R, data, &pk.Q, ec);
 
     if (_gcry_mpi_ec_get_affine (x, y, &R, ec))
-      log_fatal ("ecdh: Failed to get affine coordinates for kdG\n");
-    mpi_s = _gcry_ecc_ec2os (x, y, pk.E.p);
+      {
+        /*
+         * Here, X is 0.  In the X25519 computation on Curve25519, X0
+         * function maps infinity to zero.  So, when PUBKEY_FLAG_DJB_TWEAK
+         * is enabled, return the result of 0 not raising an error.
+         *
+         * This is a corner case.  It never occurs with properly
+         * generated public keys, but it might happen with blindly
+         * imported public key which might not follow the key
+         * generation procedure.
+         */
+        if (!(flags & PUBKEY_FLAG_DJB_TWEAK))
+          { /* It's not for X25519, then, the input data was simply wrong.  */
+            rc = GPG_ERR_INV_DATA;
+            goto leave;
+          }
+      }
+    if (y)
+      mpi_s = _gcry_ecc_ec2os (x, y, pk.E.p);
+    else
+      {
+        rawmpi = _gcry_mpi_get_buffer_extra (x, nbits/8, -1, &rawmpilen, NULL);
+        if (!rawmpi)
+          rc = gpg_err_code_from_syserror ();
+        else
+          {
+            rawmpi[0] = 0x40;
+            rawmpilen++;
+            mpi_s = mpi_new (0);
+            mpi_set_opaque (mpi_s, rawmpi, rawmpilen*8);
+          }
+      }
 
     /* R = kG */
     _gcry_mpi_ec_mul_point (&R, data, &pk.E.G, ec);
 
     if (_gcry_mpi_ec_get_affine (x, y, &R, ec))
-      log_fatal ("ecdh: Failed to get affine coordinates for kG\n");
-    mpi_e = _gcry_ecc_ec2os (x, y, pk.E.p);
+      {
+        rc = GPG_ERR_INV_DATA;
+        goto leave;
+      }
+    if (y)
+      mpi_e = _gcry_ecc_ec2os (x, y, pk.E.p);
+    else
+      {
+        rawmpi = _gcry_mpi_get_buffer_extra (x, nbits/8, -1, &rawmpilen, NULL);
+        if (!rawmpi)
+          rc = gpg_err_code_from_syserror ();
+        else
+          {
+            rawmpi[0] = 0x40;
+            rawmpilen++;
+            mpi_e = mpi_new (0);
+            mpi_set_opaque (mpi_e, rawmpi, rawmpilen*8);
+          }
+      }
+
 
     mpi_free (x);
     mpi_free (y);
@@ -1210,7 +1459,8 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
     point_free (&R);
   }
 
-  rc = sexp_build (r_ciph, NULL, "(enc-val(ecdh(s%m)(e%m)))", mpi_s, mpi_e);
+  if (!rc)
+    rc = sexp_build (r_ciph, NULL, "(enc-val(ecdh(s%m)(e%m)))", mpi_s, mpi_e);
 
  leave:
   _gcry_mpi_release (pk.E.p);
@@ -1219,12 +1469,14 @@ 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);
   _gcry_mpi_release (mpi_s);
   _gcry_mpi_release (mpi_e);
   xfree (curvename);
+  sexp_release (l1);
   _gcry_mpi_ec_free (ec);
   _gcry_pk_util_free_encoding_ctx (&ctx);
   if (DBG_CIPHER)
@@ -1243,6 +1495,7 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
 static gcry_err_code_t
 ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
 {
+  unsigned int nbits;
   gpg_err_code_t rc;
   struct pk_encoding_ctx ctx;
   gcry_sexp_t l1 = NULL;
@@ -1254,13 +1507,25 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
   mpi_point_struct kG;
   mpi_point_struct R;
   gcry_mpi_t r = NULL;
+  int flags = 0;
 
   memset (&sk, 0, sizeof sk);
   point_init (&kG);
   point_init (&R);
 
   _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_DECRYPT,
-                                   ecc_get_nbits (keyparms));
+                                   (nbits = ecc_get_nbits (keyparms)));
+
+  /* Look for flags. */
+  l1 = sexp_find_token (keyparms, "flags", 0);
+  if (l1)
+    {
+      rc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
+      if (rc)
+        goto leave;
+    }
+  sexp_release (l1);
+  l1 = NULL;
 
   /*
    * Extract the data.
@@ -1282,9 +1547,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)
@@ -1304,7 +1569,7 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
         {
           rc = _gcry_ecc_fill_in_curve (0, curvename, &sk.E, NULL);
           if (rc)
-            return rc;
+            goto leave;
         }
     }
   /* Guess required fields if a curve parameter has not been given.  */
@@ -1325,29 +1590,41 @@ 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;
     }
 
 
+  ec = _gcry_mpi_ec_p_internal_new (sk.E.model, sk.E.dialect, flags,
+                                    sk.E.p, sk.E.a, sk.E.b);
+
   /*
    * Compute the plaintext.
    */
-  rc = _gcry_ecc_os2ec (&kG, data_e);
+  if (ec->model == MPI_EC_MONTGOMERY)
+    rc = _gcry_ecc_mont_decodepoint (data_e, ec, &kG);
+  else
+    rc = _gcry_ecc_os2ec (&kG, data_e);
   if (rc)
+    goto leave;
+
+  if (DBG_CIPHER)
+    log_printpnt ("ecc_decrypt    kG", &kG, NULL);
+
+  if (!(flags & PUBKEY_FLAG_DJB_TWEAK)
+      /* For X25519, by its definition, validation should not be done.  */
+      && !_gcry_mpi_ec_curve_point (&kG, ec))
     {
-      point_free (&kG);
-      return rc;
+      rc = GPG_ERR_INV_DATA;
+      goto leave;
     }
 
-  ec = _gcry_mpi_ec_p_internal_new (sk.E.model, sk.E.dialect, 0,
-                                    sk.E.p, sk.E.a, sk.E.b);
-
   /* R = dkG */
   _gcry_mpi_ec_mul_point (&R, sk.d, &kG, ec);
 
@@ -1356,12 +1633,60 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
     gcry_mpi_t x, y;
 
     x = mpi_new (0);
-    y = mpi_new (0);
+    if (ec->model == MPI_EC_MONTGOMERY)
+      y = NULL;
+    else
+      y = mpi_new (0);
 
     if (_gcry_mpi_ec_get_affine (x, y, &R, ec))
-      log_fatal ("ecdh: Failed to get affine coordinates\n");
+      {
+        rc = GPG_ERR_INV_DATA;
+        goto leave;
+        /*
+         * Note for X25519.
+         *
+         * By the definition of X25519, this is the case where X25519
+         * returns 0, mapping infinity to zero.  However, we
+         * deliberately let it return an error.
+         *
+         * For X25519 ECDH, comming here means that it might be
+         * decrypted by anyone with the shared secret of 0 (the result
+         * of this function could be always 0 by other scalar values,
+         * other than the private key of SK.D).
+         *
+         * So, it looks like an encrypted message but it can be
+         * decrypted by anyone, or at least something wrong
+         * happens.  Recipient should not proceed as if it were
+         * properly encrypted message.
+         *
+         * This handling is needed for our major usage of GnuPG,
+         * where it does the One-Pass Diffie-Hellman method,
+         * C(1, 1, ECC CDH), with an ephemeral key.
+         */
+      }
 
-    r = _gcry_ecc_ec2os (x, y, sk.E.p);
+    if (y)
+      r = _gcry_ecc_ec2os (x, y, sk.E.p);
+    else
+      {
+        unsigned char *rawmpi;
+        unsigned int rawmpilen;
+
+        rawmpi = _gcry_mpi_get_buffer_extra (x, nbits/8, -1,
+                                             &rawmpilen, NULL);
+        if (!rawmpi)
+          {
+            rc = gpg_err_code_from_syserror ();
+            goto leave;
+          }
+        else
+          {
+            rawmpi[0] = 0x40;
+            rawmpilen++;
+            r = mpi_new (0);
+            mpi_set_opaque (r, rawmpi, rawmpilen*8);
+          }
+      }
     if (!r)
       rc = gpg_err_code_from_syserror ();
     else
@@ -1385,6 +1710,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);
@@ -1402,6 +1728,7 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
  * for example:
  *
  *   (ecc
+ *     (curve <name>)
  *     (p <mpi>)
  *     (a <mpi>)
  *     (b <mpi>)
@@ -1409,8 +1736,7 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
  *     (n <mpi>)
  *     (q <mpi>))
  *
- * More parameters may be given currently P is needed.  FIXME: We
- * need allow for a "curve" parameter.
+ * More parameters may be given. Either P or CURVE is needed.
  */
 static unsigned int
 ecc_get_nbits (gcry_sexp_t parms)
@@ -1454,8 +1780,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];
@@ -1482,25 +1808,25 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparms)
   /* Extract the parameters.  */
   if ((flags & PUBKEY_FLAG_PARAM))
     {
-      if ((flags & PUBKEY_FLAG_EDDSA))
-        rc = sexp_extract_param (keyparms, NULL, "p?a?b?g?n?/q",
+      if ((flags & PUBKEY_FLAG_DJB_TWEAK))
+        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))
+      if ((flags & PUBKEY_FLAG_DJB_TWEAK))
         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 +1843,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;
         }
@@ -1528,7 +1854,7 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparms)
   if (!curvename)
     {
       model = ((flags & PUBKEY_FLAG_EDDSA)
-               ? MPI_EC_TWISTEDEDWARDS
+               ? MPI_EC_EDWARDS
                : MPI_EC_WEIERSTRASS);
       dialect = ((flags & PUBKEY_FLAG_EDDSA)
                  ? ECC_DIALECT_ED25519
@@ -1552,12 +1878,9 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparms)
      the compressed version.  Because we don't support any non-eddsa
      compression, the only thing we need to do is to compress
      EdDSA.  */
-  if ((flags & PUBKEY_FLAG_EDDSA))
+  if ((flags & PUBKEY_FLAG_DJB_TWEAK))
     {
-      if (dialect == ECC_DIALECT_ED25519)
-        rc = _gcry_ecc_eddsa_ensure_compact (values[5], 256);
-      else
-        rc = GPG_ERR_NOT_IMPLEMENTED;
+      rc = _gcry_ecc_eddsa_ensure_compact (values[6], 256);
       if (rc)
         goto leave;
     }
@@ -1567,6 +1890,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 +1950,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 +2002,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;
@@ -1701,23 +2027,166 @@ _gcry_pk_ecc_get_sexp (gcry_sexp_t *r_sexp, int mode, mpi_ec_t ec)
      Self-test section.
  */
 
+static const char *
+selftest_sign (gcry_sexp_t pkey, gcry_sexp_t skey)
+{
+  /* Sample data from RFC 6979 section A.2.5, hash is of message "sample" */
+  static const char sample_data[] =
+    "(data (flags rfc6979)"
+    " (hash sha256 #af2bdbe1aa9b6ec1e2ade1d694f41fc71a831d0268e98915"
+    /**/           "62113d8a62add1bf#))";
+  static const char sample_data_bad[] =
+    "(data (flags rfc6979)"
+    " (hash sha256 #bf2bdbe1aa9b6ec1e2ade1d694f41fc71a831d0268e98915"
+    /**/           "62113d8a62add1bf#))";
+  static const char signature_r[] =
+    "efd48b2aacb6a8fd1140dd9cd45e81d69d2c877b56aaf991c34d0ea84eaf3716";
+  static const char signature_s[] =
+    "f7cb1c942d657c41d436c7a1b6e29f65f3e900dbb9aff4064dc4ab2f843acda8";
+
+  const char *errtxt = NULL;
+  gcry_error_t err;
+  gcry_sexp_t data = NULL;
+  gcry_sexp_t data_bad = NULL;
+  gcry_sexp_t sig = NULL;
+  gcry_sexp_t l1 = NULL;
+  gcry_sexp_t l2 = NULL;
+  gcry_mpi_t r = NULL;
+  gcry_mpi_t s = NULL;
+  gcry_mpi_t calculated_r = NULL;
+  gcry_mpi_t calculated_s = NULL;
+  int cmp;
+
+  err = sexp_sscan (&data, NULL, sample_data, strlen (sample_data));
+  if (!err)
+    err = sexp_sscan (&data_bad, NULL,
+                      sample_data_bad, strlen (sample_data_bad));
+  if (!err)
+    err = _gcry_mpi_scan (&r, GCRYMPI_FMT_HEX, signature_r, 0, NULL);
+  if (!err)
+    err = _gcry_mpi_scan (&s, GCRYMPI_FMT_HEX, signature_s, 0, NULL);
+
+  if (err)
+    {
+      errtxt = "converting data failed";
+      goto leave;
+    }
+
+  err = _gcry_pk_sign (&sig, data, skey);
+  if (err)
+    {
+      errtxt = "signing failed";
+      goto leave;
+    }
+
+  /* check against known signature */
+  errtxt = "signature validity failed";
+  l1 = _gcry_sexp_find_token (sig, "sig-val", 0);
+  if (!l1)
+    goto leave;
+  l2 = _gcry_sexp_find_token (l1, "ecdsa", 0);
+  if (!l2)
+    goto leave;
+
+  sexp_release (l1);
+  l1 = l2;
+
+  l2 = _gcry_sexp_find_token (l1, "r", 0);
+  if (!l2)
+    goto leave;
+  calculated_r = _gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
+  if (!calculated_r)
+    goto leave;
+
+  sexp_release (l2);
+  l2 = _gcry_sexp_find_token (l1, "s", 0);
+  if (!l2)
+    goto leave;
+  calculated_s = _gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
+  if (!calculated_s)
+    goto leave;
+
+  errtxt = "known sig check failed";
+
+  cmp = _gcry_mpi_cmp (r, calculated_r);
+  if (cmp)
+    goto leave;
+  cmp = _gcry_mpi_cmp (s, calculated_s);
+  if (cmp)
+    goto leave;
+
+  errtxt = NULL;
+
+  /* verify generated signature */
+  err = _gcry_pk_verify (sig, data, pkey);
+  if (err)
+    {
+      errtxt = "verify failed";
+      goto leave;
+    }
+  err = _gcry_pk_verify (sig, data_bad, pkey);
+  if (gcry_err_code (err) != GPG_ERR_BAD_SIGNATURE)
+    {
+      errtxt = "bad signature not detected";
+      goto leave;
+    }
+
+
+ leave:
+  sexp_release (sig);
+  sexp_release (data_bad);
+  sexp_release (data);
+  sexp_release (l1);
+  sexp_release (l2);
+  mpi_release (r);
+  mpi_release (s);
+  mpi_release (calculated_r);
+  mpi_release (calculated_s);
+  return errtxt;
+}
+
 
 static gpg_err_code_t
 selftests_ecdsa (selftest_report_func_t report)
 {
   const char *what;
   const char *errtxt;
+  gcry_error_t err;
+  gcry_sexp_t skey = NULL;
+  gcry_sexp_t pkey = NULL;
 
-  what = "low-level";
-  errtxt = NULL; /*selftest ();*/
+  what = "convert";
+  err = sexp_sscan (&skey, NULL, sample_secret_key_secp256,
+                    strlen (sample_secret_key_secp256));
+  if (!err)
+    err = sexp_sscan (&pkey, NULL, sample_public_key_secp256,
+                      strlen (sample_public_key_secp256));
+  if (err)
+    {
+      errtxt = _gcry_strerror (err);
+      goto failed;
+    }
+
+  what = "key consistency";
+  err = ecc_check_secret_key(skey);
+  if (err)
+    {
+      errtxt = _gcry_strerror (err);
+      goto failed;
+    }
+
+  what = "sign";
+  errtxt = selftest_sign (pkey, skey);
   if (errtxt)
     goto failed;
 
-  /* FIXME:  need more tests.  */
-
+  sexp_release(pkey);
+  sexp_release(skey);
   return 0; /* Succeeded. */
 
  failed:
+  sexp_release(pkey);
+  sexp_release(skey);
   if (report)
     report ("pubkey", GCRY_PK_ECC, what, errtxt);
   return GPG_ERR_SELFTEST_FAILED;
@@ -1741,10 +2210,10 @@ run_selftests (int algo, int extended, selftest_report_func_t report)
 \f
 gcry_pk_spec_t _gcry_pubkey_spec_ecc =
   {
-    GCRY_PK_ECC, { 0, 0 },
+    GCRY_PK_ECC, { 0, 1 },
     (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,
index cb3ca43..4eb52d6 100644 (file)
 #include "pubkey-internal.h"
 
 
+/* Blinding is used to mitigate side-channel attacks.  You may undef
+   this to speed up the operation in case the system is secured
+   against physical and network mounted side-channel attacks.  */
+#define USE_BLINDING 1
+
+
 typedef struct
 {
   gcry_mpi_t p;            /* prime */
@@ -516,15 +522,45 @@ do_encrypt(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey )
 static void
 decrypt (gcry_mpi_t output, gcry_mpi_t a, gcry_mpi_t b, ELG_secret_key *skey )
 {
-  gcry_mpi_t t1 = mpi_alloc_secure( mpi_get_nlimbs( skey->p ) );
+  gcry_mpi_t t1, t2, r;
+  unsigned int nbits = mpi_get_nbits (skey->p);
 
   mpi_normalize (a);
   mpi_normalize (b);
 
+  t1 = mpi_snew (nbits);
+
+#ifdef USE_BLINDING
+
+  t2 = mpi_snew (nbits);
+  r  = mpi_new (nbits);
+
+  /* We need a random number of about the prime size.  The random
+     number merely needs to be unpredictable; thus we use level 0.  */
+  _gcry_mpi_randomize (r, nbits, GCRY_WEAK_RANDOM);
+
+  /* t1 = r^x mod p */
+  mpi_powm (t1, r, skey->x, skey->p);
+  /* t2 = (a * r)^-x mod p */
+  mpi_mulm (t2, a, r, skey->p);
+  mpi_powm (t2, t2, skey->x, skey->p);
+  mpi_invm (t2, t2, skey->p);
+  /* t1 = (t1 * t2) mod p*/
+  mpi_mulm (t1, t1, t2, skey->p);
+
+  mpi_free (r);
+  mpi_free (t2);
+
+#else /*!USE_BLINDING*/
+
   /* output = b/(a^x) mod p */
-  mpi_powm( t1, a, skey->x, skey->p );
-  mpi_invm( t1, t1, skey->p );
-  mpi_mulm( output, b, t1, skey->p );
+  mpi_powm (t1, a, skey->x, skey->p);
+  mpi_invm (t1, t1, skey->p);
+
+#endif /*!USE_BLINDING*/
+
+  mpi_mulm (output, b, t1, skey->p);
+
 #if 0
   if( DBG_CIPHER )
     {
@@ -535,7 +571,7 @@ decrypt (gcry_mpi_t output, gcry_mpi_t a, gcry_mpi_t b, ELG_secret_key *skey )
       log_mpidump ("elg decrypted M", output);
     }
 #endif
-  mpi_free(t1);
+  mpi_free (t1);
 }
 
 
diff --git a/cipher/gost-s-box.c b/cipher/gost-s-box.c
new file mode 100644 (file)
index 0000000..0094f65
--- /dev/null
@@ -0,0 +1,256 @@
+/* gost-s-box.c - GOST 28147-89 S-Box expander
+ * Copyright (C) 2013 Dmitry Eremin-Solenikov
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define DIM(v) (sizeof(v)/sizeof((v)[0]))
+
+struct gost_sbox
+{
+  const char *name;
+  const char *oid;
+  unsigned char sbox[16*8];
+} gost_sboxes[] = {
+  { "test_3411", "1.2.643.2.2.30.0", {
+      0x4, 0xE, 0x5, 0x7, 0x6, 0x4, 0xD, 0x1,
+      0xA, 0xB, 0x8, 0xD, 0xC, 0xB, 0xB, 0xF,
+      0x9, 0x4, 0x1, 0xA, 0x7, 0xA, 0x4, 0xD,
+      0x2, 0xC, 0xD, 0x1, 0x1, 0x0, 0x1, 0x0,
+
+      0xD, 0x6, 0xA, 0x0, 0x5, 0x7, 0x3, 0x5,
+      0x8, 0xD, 0x3, 0x8, 0xF, 0x2, 0xF, 0x7,
+      0x0, 0xF, 0x4, 0x9, 0xD, 0x1, 0x5, 0xA,
+      0xE, 0xA, 0x2, 0xF, 0x8, 0xD, 0x9, 0x4,
+
+      0x6, 0x2, 0xE, 0xE, 0x4, 0x3, 0x0, 0x9,
+      0xB, 0x3, 0xF, 0x4, 0xA, 0x6, 0xA, 0x2,
+      0x1, 0x8, 0xC, 0x6, 0x9, 0x8, 0xE, 0x3,
+      0xC, 0x1, 0x7, 0xC, 0xE, 0x5, 0x7, 0xE,
+
+      0x7, 0x0, 0x6, 0xB, 0x0, 0x9, 0x6, 0x6,
+      0xF, 0x7, 0x0, 0x2, 0x3, 0xC, 0x8, 0xB,
+      0x5, 0x5, 0x9, 0x5, 0xB, 0xF, 0x2, 0x8,
+      0x3, 0x9, 0xB, 0x3, 0x2, 0xE, 0xC, 0xC,
+    }
+  },
+  { "CryptoPro_3411", "1.2.643.2.2.30.1", {
+      0xA, 0x5, 0x7, 0x4, 0x7, 0x7, 0xD, 0x1,
+      0x4, 0xF, 0xF, 0xA, 0x6, 0x6, 0xE, 0x3,
+      0x5, 0x4, 0xC, 0x7, 0x4, 0x2, 0x4, 0xA,
+      0x6, 0x0, 0xE, 0xC, 0xB, 0x4, 0x1, 0x9,
+
+      0x8, 0x2, 0x9, 0x0, 0x9, 0xD, 0x7, 0x5,
+      0x1, 0xD, 0x4, 0xF, 0xC, 0x9, 0x0, 0xB,
+      0x3, 0xB, 0x1, 0x2, 0x2, 0xF, 0x5, 0x4,
+      0x7, 0x9, 0x0, 0x8, 0xA, 0x0, 0xA, 0xF,
+
+      0xD, 0x1, 0x3, 0xE, 0x1, 0xA, 0x3, 0x8,
+      0xC, 0x7, 0xB, 0x1, 0x8, 0x1, 0xC, 0x6,
+      0xE, 0x6, 0x5, 0x6, 0x0, 0x5, 0x8, 0x7,
+      0x0, 0x3, 0x2, 0x5, 0xE, 0xB, 0xF, 0xE,
+
+      0x9, 0xC, 0x6, 0xD, 0xF, 0x8, 0x6, 0xD,
+      0x2, 0xE, 0xA, 0xB, 0xD, 0xE, 0x2, 0x0,
+      0xB, 0xA, 0x8, 0x9, 0x3, 0xC, 0x9, 0x2,
+      0xF, 0x8, 0xD, 0x3, 0x5, 0x3, 0xB, 0xC,
+    }
+  },
+  { "Test_89", "1.2.643.2.2.31.0", {
+      0x4, 0xC, 0xD, 0xE, 0x3, 0x8, 0x9, 0xC,
+      0x2, 0x9, 0x8, 0x9, 0xE, 0xF, 0xB, 0x6,
+      0xF, 0xF, 0xE, 0xB, 0x5, 0x6, 0xC, 0x5,
+      0x5, 0xE, 0xC, 0x2, 0x9, 0xB, 0x0, 0x2,
+
+      0x9, 0x8, 0x7, 0x5, 0x6, 0x1, 0x3, 0xB,
+      0x1, 0x1, 0x3, 0xF, 0x8, 0x9, 0x6, 0x0,
+      0x0, 0x3, 0x9, 0x7, 0x0, 0xC, 0x7, 0x9,
+      0x8, 0xA, 0xA, 0x1, 0xD, 0x5, 0x5, 0xD,
+
+      0xE, 0x2, 0x1, 0x0, 0xA, 0xD, 0x4, 0x3,
+      0x3, 0x7, 0x5, 0xD, 0xB, 0x3, 0x8, 0xE,
+      0xB, 0x4, 0x2, 0xC, 0x7, 0x7, 0xE, 0x7,
+      0xC, 0xD, 0x4, 0x6, 0xC, 0xA, 0xF, 0xA,
+
+      0xD, 0x6, 0x6, 0xA, 0x2, 0x0, 0x1, 0xF,
+      0x7, 0x0, 0xF, 0x4, 0x1, 0xE, 0xA, 0x4,
+      0xA, 0xB, 0x0, 0x3, 0xF, 0x2, 0x2, 0x1,
+      0x6, 0x5, 0xB, 0x8, 0x4, 0x4, 0xD, 0x8,
+    }
+  },
+  { "CryptoPro_A", "1.2.643.2.2.31.1", {
+      0x9, 0x3, 0xE, 0xE, 0xB, 0x3, 0x1, 0xB,
+      0x6, 0x7, 0x4, 0x7, 0x5, 0xA, 0xD, 0xA,
+      0x3, 0xE, 0x6, 0xA, 0x1, 0xD, 0x2, 0xF,
+      0x2, 0x9, 0x2, 0xC, 0x9, 0xC, 0x9, 0x5,
+
+      0x8, 0x8, 0xB, 0xD, 0x8, 0x1, 0x7, 0x0,
+      0xB, 0xA, 0x3, 0x1, 0xD, 0x2, 0xA, 0xC,
+      0x1, 0xF, 0xD, 0x3, 0xF, 0x0, 0x6, 0xE,
+      0x7, 0x0, 0x8, 0x9, 0x0, 0xB, 0x0, 0x8,
+
+      0xA, 0x5, 0xC, 0x0, 0xE, 0x7, 0x8, 0x6,
+      0x4, 0x2, 0xF, 0x2, 0x4, 0x5, 0xC, 0x2,
+      0xE, 0x6, 0x5, 0xB, 0x2, 0x9, 0x4, 0x3,
+      0xF, 0xC, 0xA, 0x4, 0x3, 0x4, 0x5, 0x9,
+
+      0xC, 0xB, 0x0, 0xF, 0xC, 0x8, 0xF, 0x1,
+      0x0, 0x4, 0x7, 0x8, 0x7, 0xF, 0x3, 0x7,
+      0xD, 0xD, 0x1, 0x5, 0xA, 0xE, 0xB, 0xD,
+      0x5, 0x1, 0x9, 0x6, 0x6, 0x6, 0xE, 0x4,
+    }
+  },
+  { "CryptoPro_B", "1.2.643.2.2.31.2", {
+      0x8, 0x0, 0xE, 0x7, 0x2, 0x8, 0x5, 0x0,
+      0x4, 0x1, 0xC, 0x5, 0x7, 0x3, 0x2, 0x4,
+      0xB, 0x2, 0x0, 0x0, 0xC, 0x2, 0xA, 0xB,
+      0x1, 0xA, 0xA, 0xD, 0xF, 0x6, 0xB, 0xE,
+
+      0x3, 0x4, 0x9, 0xB, 0x9, 0x4, 0x9, 0x8,
+      0x5, 0xD, 0x2, 0x6, 0x5, 0xD, 0x1, 0x3,
+      0x0, 0x5, 0xD, 0x1, 0xA, 0xE, 0xC, 0x7,
+      0x9, 0xC, 0xB, 0x2, 0xB, 0xB, 0x3, 0x1,
+
+      0x2, 0x9, 0x7, 0x3, 0x1, 0xC, 0x7, 0xA,
+      0xE, 0x7, 0x5, 0xA, 0x4, 0x1, 0x4, 0x2,
+      0xA, 0x3, 0x8, 0xC, 0x0, 0x7, 0xD, 0x9,
+      0xC, 0xF, 0xF, 0xF, 0xD, 0xF, 0x0, 0x6,
+
+      0x6, 0x8, 0x6, 0xE, 0x8, 0x0, 0xF, 0xD,
+      0x7, 0x6, 0x1, 0x9, 0xE, 0x9, 0x8, 0x5,
+      0xF, 0xE, 0x4, 0x8, 0x3, 0x5, 0xE, 0xC,
+    }
+  },
+  { "CryptoPro_C", "1.2.643.2.2.31.3", {
+      0x1, 0x0, 0x8, 0x3, 0x8, 0xC, 0xA, 0x7,
+      0xB, 0x1, 0x2, 0x6, 0xD, 0x9, 0x9, 0x4,
+      0xC, 0x7, 0x5, 0x0, 0xB, 0xB, 0x6, 0x0,
+      0x2, 0xD, 0x0, 0x1, 0x0, 0x1, 0x8, 0x5,
+
+      0x9, 0xB, 0x4, 0x5, 0x4, 0x8, 0xD, 0xA,
+      0xD, 0x4, 0x9, 0xD, 0x5, 0xE, 0xE, 0x2,
+      0x0, 0x5, 0xF, 0xA, 0x1, 0x2, 0x2, 0xF,
+      0xF, 0x2, 0xA, 0x8, 0x2, 0x4, 0x0, 0xE,
+
+      0x4, 0x8, 0x3, 0xB, 0x9, 0x7, 0xF, 0xC,
+      0x5, 0xE, 0x7, 0x2, 0x3, 0x3, 0x3, 0x6,
+      0x8, 0xF, 0xC, 0x9, 0xC, 0x6, 0x5, 0x1,
+      0xE, 0xC, 0xD, 0x7, 0xE, 0x5, 0xB, 0xB,
+
+      0xA, 0x9, 0x6, 0xE, 0x6, 0xA, 0x4, 0xD,
+      0x7, 0xA, 0xE, 0xF, 0xF, 0x0, 0x1, 0x9,
+      0x6, 0x6, 0x1, 0xC, 0xA, 0xF, 0xC, 0x3,
+      0x3, 0x3, 0xB, 0x4, 0x7, 0xD, 0x7, 0x8,
+    }
+  },
+  { "CryptoPro_D", "1.2.643.2.2.31.4", {
+      0xF, 0xB, 0x1, 0x1, 0x0, 0x8, 0x3, 0x1,
+      0xC, 0x6, 0xC, 0x5, 0xC, 0x0, 0x0, 0xA,
+      0x2, 0x3, 0xB, 0xE, 0x8, 0xF, 0x6, 0x6,
+      0xA, 0x4, 0x0, 0xC, 0x9, 0x3, 0xF, 0x8,
+
+      0x6, 0xC, 0xF, 0xA, 0xD, 0x2, 0x1, 0xF,
+      0x4, 0xF, 0xE, 0x7, 0x2, 0x5, 0xE, 0xB,
+      0x5, 0xE, 0x6, 0x0, 0xA, 0xE, 0x9, 0x0,
+      0x0, 0x2, 0x5, 0xD, 0xB, 0xB, 0x2, 0x4,
+
+      0x7, 0x7, 0xA, 0x6, 0x7, 0x1, 0xD, 0xC,
+      0x9, 0xD, 0xD, 0x2, 0x3, 0xA, 0x8, 0x3,
+      0xE, 0x8, 0x4, 0xB, 0x6, 0x4, 0xC, 0x5,
+      0xD, 0x0, 0x8, 0x4, 0x5, 0x7, 0x4, 0x9,
+
+      0x1, 0x5, 0x9, 0x9, 0x4, 0xC, 0xB, 0x7,
+      0xB, 0xA, 0x3, 0x3, 0xE, 0x9, 0xA, 0xD,
+      0x8, 0x9, 0x7, 0xF, 0xF, 0xD, 0x5, 0x2,
+      0x3, 0x1, 0x2, 0x8, 0x1, 0x6, 0x7, 0xE,
+    }
+  },
+  { "TC26_A", "1.2.643.7.1.2.5.1.1", {
+      0xc, 0x6, 0xb, 0xc, 0x7, 0x5, 0x8, 0x1,
+      0x4, 0x8, 0x3, 0x8, 0xf, 0xd, 0xe, 0x7,
+      0x6, 0x2, 0x5, 0x2, 0x5, 0xf, 0x2, 0xe,
+      0x2, 0x3, 0x8, 0x1, 0xa, 0x6, 0x5, 0xd,
+
+      0xa, 0x9, 0x2, 0xd, 0x8, 0x9, 0x6, 0x0,
+      0x5, 0xa, 0xf, 0x4, 0x1, 0x2, 0x9, 0x5,
+      0xb, 0x5, 0xa, 0xf, 0x6, 0xc, 0x1, 0x8,
+      0x9, 0xc, 0xd, 0x6, 0xd, 0xa, 0xc, 0x3,
+
+      0xe, 0x1, 0xe, 0x7, 0x0, 0xb, 0xf, 0x4,
+      0x8, 0xe, 0x1, 0x0, 0x9, 0x7, 0x4, 0xf,
+      0xd, 0x4, 0x7, 0xa, 0x3, 0x8, 0xb, 0xa,
+      0x7, 0x7, 0x4, 0x5, 0xe, 0x1, 0x0, 0x6,
+
+      0x0, 0xb, 0xc, 0x3, 0xb, 0x4, 0xd, 0x9,
+      0x3, 0xd, 0x9, 0xe, 0x4, 0x3, 0xa, 0xc,
+      0xf, 0x0, 0x6, 0x9, 0x2, 0xe, 0x3, 0xb,
+      0x1, 0xf, 0x0, 0xb, 0xc, 0x0, 0x7, 0x2,
+    }
+  },
+};
+
+int main(int argc, char **argv)
+{
+  unsigned int i, j, s;
+  FILE *f;
+
+  if (argc == 1)
+    f = stdin;
+  else
+    f = fopen(argv[1], "w");
+
+  if (!f)
+    {
+      perror("fopen");
+      exit(1);
+    }
+
+  for (s = 0; s < DIM(gost_sboxes); s++)
+    {
+      unsigned char *sbox = gost_sboxes[s].sbox;
+      fprintf (f, "static const u32 sbox_%s[4*256] =\n  {", gost_sboxes[s].name);
+      for (i = 0; i < 4; i++) {
+        fprintf (f,    "\n    /* %d */\n   ", i);
+        for (j = 0; j < 256; j++) {
+          unsigned int val;
+          if (j % 4 == 0 && j != 0)
+            fprintf (f, "\n   ");
+          val = sbox[ (j & 0xf) * 8 + 2 * i + 0] |
+               (sbox[ (j >> 4)  * 8 + 2 * i + 1] << 4);
+          val <<= (8*i);
+          val = (val << 11) | (val >> 21);
+          fprintf (f, " 0x%08x,", val);
+        }
+      }
+      fprintf (f, "\n  };\n\n");
+    }
+
+  fprintf (f, "static struct\n{\n  const char *oid;\n  const u32 *sbox;\n} gost_oid_map[] = {\n");
+
+  for (s = 0; s < DIM(gost_sboxes); s++)
+    {
+      fprintf (f, "  { \"%s\", sbox_%s },\n", gost_sboxes[s].oid, gost_sboxes[s].name );
+    }
+
+  fprintf(f, "  { NULL, NULL }\n};\n");
+
+  fclose (f);
+
+  return 0;
+}
index d058eb2..025119c 100644 (file)
 
 typedef struct {
   u32 key[8];
+  const u32 *sbox;
 } GOST28147_context;
 
 /* This is a simple interface that will be used by GOST R 34.11-94 */
-extern unsigned int _gcry_gost_enc_one (GOST28147_context *c, const byte *key,
-    byte *out, byte *in);
+unsigned int _gcry_gost_enc_data (GOST28147_context *c, const u32 *key,
+    u32 *o1, u32 *o2, u32 n1, u32 n2, int cryptopro);
 
 #endif
index c094209..4ff80b4 100644 (file)
 #include "types.h"
 #include "g10lib.h"
 #include "cipher.h"
-
-
-/* This is an s-box from RFC4357, named GostR3411-94-TestParamSet
- * For now it is the only s-box supported, as libgcrypt lacks mechanism
- * for passing parameters to cipher in a usefull way.
- * S-boxes was modified from 4->4 to 8->8 bits unit with precalculated
- * shift and rotation by optimisation reasons.
- */
-static const u32 test_sbox[4][256] = {
-  /* 0 */
-  { 0x00072000, 0x00075000, 0x00074800, 0x00071000,
-    0x00076800, 0x00074000, 0x00070000, 0x00077000,
-    0x00073000, 0x00075800, 0x00070800, 0x00076000,
-    0x00073800, 0x00077800, 0x00072800, 0x00071800,
-    0x0005a000, 0x0005d000, 0x0005c800, 0x00059000,
-    0x0005e800, 0x0005c000, 0x00058000, 0x0005f000,
-    0x0005b000, 0x0005d800, 0x00058800, 0x0005e000,
-    0x0005b800, 0X0005F800, 0x0005a800, 0x00059800,
-    0x00022000, 0x00025000, 0x00024800, 0x00021000,
-    0x00026800, 0x00024000, 0x00020000, 0x00027000,
-    0X00023000, 0x00025800, 0x00020800, 0x00026000,
-    0x00023800, 0x00027800, 0x00022800, 0x00021800,
-    0x00062000, 0x00065000, 0x00064800, 0x00061000,
-    0x00066800, 0x00064000, 0x00060000, 0x00067000,
-    0x00063000, 0x00065800, 0x00060800, 0x00066000,
-    0x00063800, 0x00067800, 0x00062800, 0x00061800,
-    0x00032000, 0x00035000, 0x00034800, 0x00031000,
-    0x00036800, 0x00034000, 0x00030000, 0x00037000,
-    0x00033000, 0x00035800, 0x00030800, 0x00036000,
-    0x00033800, 0x00037800, 0x00032800, 0x00031800,
-    0x0006a000, 0x0006d000, 0x0006c800, 0x00069000,
-    0x0006e800, 0x0006c000, 0x00068000, 0x0006f000,
-    0x0006b000, 0x0006d800, 0x00068800, 0x0006e000,
-    0x0006b800, 0x0006f800, 0x0006a800, 0x00069800,
-    0x0007a000, 0x0007d000, 0x0007c800, 0x00079000,
-    0x0007e800, 0x0007c000, 0x00078000, 0x0007f000,
-    0x0007b000, 0x0007d800, 0x00078800, 0x0007e000,
-    0x0007b800, 0x0007f800, 0x0007a800, 0x00079800,
-    0x00052000, 0x00055000, 0x00054800, 0x00051000,
-    0x00056800, 0x00054000, 0x00050000, 0x00057000,
-    0x00053000, 0x00055800, 0x00050800, 0x00056000,
-    0x00053800, 0x00057800, 0x00052800, 0x00051800,
-    0x00012000, 0x00015000, 0x00014800, 0x00011000,
-    0x00016800, 0x00014000, 0x00010000, 0x00017000,
-    0x00013000, 0x00015800, 0x00010800, 0x00016000,
-    0x00013800, 0x00017800, 0x00012800, 0x00011800,
-    0x0001a000, 0x0001d000, 0x0001c800, 0x00019000,
-    0x0001e800, 0x0001c000, 0x00018000, 0x0001f000,
-    0x0001b000, 0x0001d800, 0x00018800, 0x0001e000,
-    0x0001b800, 0x0001f800, 0x0001a800, 0x00019800,
-    0x00042000, 0x00045000, 0x00044800, 0x00041000,
-    0x00046800, 0x00044000, 0x00040000, 0x00047000,
-    0x00043000, 0x00045800, 0x00040800, 0x00046000,
-    0x00043800, 0x00047800, 0x00042800, 0x00041800,
-    0x0000a000, 0x0000d000, 0x0000c800, 0x00009000,
-    0x0000e800, 0x0000c000, 0x00008000, 0x0000f000,
-    0x0000b000, 0x0000d800, 0x00008800, 0x0000e000,
-    0x0000b800, 0x0000f800, 0x0000a800, 0x00009800,
-    0x00002000, 0x00005000, 0x00004800, 0x00001000,
-    0x00006800, 0x00004000, 0x00000000, 0x00007000,
-    0x00003000, 0x00005800, 0x00000800, 0x00006000,
-    0x00003800, 0x00007800, 0x00002800, 0x00001800,
-    0x0003a000, 0x0003d000, 0x0003c800, 0x00039000,
-    0x0003e800, 0x0003c000, 0x00038000, 0x0003f000,
-    0x0003b000, 0x0003d800, 0x00038800, 0x0003e000,
-    0x0003b800, 0x0003f800, 0x0003a800, 0x00039800,
-    0x0002a000, 0x0002d000, 0x0002c800, 0x00029000,
-    0x0002e800, 0x0002c000, 0x00028000, 0x0002f000,
-    0x0002b000, 0x0002d800, 0x00028800, 0x0002e000,
-    0x0002b800, 0x0002f800, 0x0002a800, 0x00029800,
-    0x0004a000, 0x0004d000, 0x0004c800, 0x00049000,
-    0x0004e800, 0x0004c000, 0x00048000, 0x0004f000,
-    0x0004b000, 0x0004d800, 0x00048800, 0x0004e000,
-    0x0004b800, 0x0004f800, 0x0004a800, 0x00049800 },
-  /* 1 */
-  { 0x03a80000, 0x03c00000, 0x03880000, 0x03e80000,
-    0x03d00000, 0x03980000, 0x03a00000, 0x03900000,
-    0x03f00000, 0x03f80000, 0x03e00000, 0x03b80000,
-    0x03b00000, 0x03800000, 0x03c80000, 0x03d80000,
-    0x06a80000, 0x06c00000, 0x06880000, 0x06e80000,
-    0x06d00000, 0x06980000, 0x06a00000, 0x06900000,
-    0x06f00000, 0x06f80000, 0x06e00000, 0x06b80000,
-    0x06b00000, 0x06800000, 0x06c80000, 0x06d80000,
-    0x05280000, 0x05400000, 0x05080000, 0x05680000,
-    0x05500000, 0x05180000, 0x05200000, 0x05100000,
-    0x05700000, 0x05780000, 0x05600000, 0x05380000,
-    0x05300000, 0x05000000, 0x05480000, 0x05580000,
-    0x00a80000, 0x00c00000, 0x00880000, 0x00e80000,
-    0x00d00000, 0x00980000, 0x00a00000, 0x00900000,
-    0x00f00000, 0x00f80000, 0x00e00000, 0x00b80000,
-    0x00b00000, 0x00800000, 0x00c80000, 0x00d80000,
-    0x00280000, 0x00400000, 0x00080000, 0x00680000,
-    0x00500000, 0x00180000, 0x00200000, 0x00100000,
-    0x00700000, 0x00780000, 0x00600000, 0x00380000,
-    0x00300000, 0x00000000, 0x00480000, 0x00580000,
-    0x04280000, 0x04400000, 0x04080000, 0x04680000,
-    0x04500000, 0x04180000, 0x04200000, 0x04100000,
-    0x04700000, 0x04780000, 0x04600000, 0x04380000,
-    0x04300000, 0x04000000, 0x04480000, 0x04580000,
-    0x04a80000, 0x04c00000, 0x04880000, 0x04e80000,
-    0x04d00000, 0x04980000, 0x04a00000, 0x04900000,
-    0x04f00000, 0x04f80000, 0x04e00000, 0x04b80000,
-    0x04b00000, 0x04800000, 0x04c80000, 0x04d80000,
-    0x07a80000, 0x07c00000, 0x07880000, 0x07e80000,
-    0x07d00000, 0x07980000, 0x07a00000, 0x07900000,
-    0x07f00000, 0x07f80000, 0x07e00000, 0x07b80000,
-    0x07b00000, 0x07800000, 0x07c80000, 0x07d80000,
-    0x07280000, 0x07400000, 0x07080000, 0x07680000,
-    0x07500000, 0x07180000, 0x07200000, 0x07100000,
-    0x07700000, 0x07780000, 0x07600000, 0x07380000,
-    0x07300000, 0x07000000, 0x07480000, 0x07580000,
-    0x02280000, 0x02400000, 0x02080000, 0x02680000,
-    0x02500000, 0x02180000, 0x02200000, 0x02100000,
-    0x02700000, 0x02780000, 0x02600000, 0x02380000,
-    0x02300000, 0x02000000, 0x02480000, 0x02580000,
-    0x03280000, 0x03400000, 0x03080000, 0x03680000,
-    0x03500000, 0x03180000, 0x03200000, 0x03100000,
-    0x03700000, 0x03780000, 0x03600000, 0x03380000,
-    0x03300000, 0x03000000, 0x03480000, 0x03580000,
-    0x06280000, 0x06400000, 0x06080000, 0x06680000,
-    0x06500000, 0x06180000, 0x06200000, 0x06100000,
-    0x06700000, 0x06780000, 0x06600000, 0x06380000,
-    0x06300000, 0x06000000, 0x06480000, 0x06580000,
-    0x05a80000, 0x05c00000, 0x05880000, 0x05e80000,
-    0x05d00000, 0x05980000, 0x05a00000, 0x05900000,
-    0x05f00000, 0x05f80000, 0x05e00000, 0x05b80000,
-    0x05b00000, 0x05800000, 0x05c80000, 0x05d80000,
-    0x01280000, 0x01400000, 0x01080000, 0x01680000,
-    0x01500000, 0x01180000, 0x01200000, 0x01100000,
-    0x01700000, 0x01780000, 0x01600000, 0x01380000,
-    0x01300000, 0x01000000, 0x01480000, 0x01580000,
-    0x02a80000, 0x02c00000, 0x02880000, 0x02e80000,
-    0x02d00000, 0x02980000, 0x02a00000, 0x02900000,
-    0x02f00000, 0x02f80000, 0x02e00000, 0x02b80000,
-    0x02b00000, 0x02800000, 0x02c80000, 0x02d80000,
-    0x01a80000, 0x01c00000, 0x01880000, 0x01e80000,
-    0x01d00000, 0x01980000, 0x01a00000, 0x01900000,
-    0x01f00000, 0x01f80000, 0x01e00000, 0x01b80000,
-    0x01b00000, 0x01800000, 0x01c80000, 0x01d80000 },
-  /* 2 */
-  { 0x30000002, 0x60000002, 0x38000002, 0x08000002,
-    0x28000002, 0x78000002, 0x68000002, 0x40000002,
-    0x20000002, 0x50000002, 0x48000002, 0x70000002,
-    0x00000002, 0x18000002, 0x58000002, 0x10000002,
-    0xb0000005, 0xe0000005, 0xb8000005, 0x88000005,
-    0xa8000005, 0xf8000005, 0xe8000005, 0xc0000005,
-    0xa0000005, 0xd0000005, 0xc8000005, 0xf0000005,
-    0x80000005, 0x98000005, 0xd8000005, 0x90000005,
-    0x30000005, 0x60000005, 0x38000005, 0x08000005,
-    0x28000005, 0x78000005, 0x68000005, 0x40000005,
-    0x20000005, 0x50000005, 0x48000005, 0x70000005,
-    0x00000005, 0x18000005, 0x58000005, 0x10000005,
-    0x30000000, 0x60000000, 0x38000000, 0x08000000,
-    0x28000000, 0x78000000, 0x68000000, 0x40000000,
-    0x20000000, 0x50000000, 0x48000000, 0x70000000,
-    0x00000000, 0x18000000, 0x58000000, 0x10000000,
-    0xb0000003, 0xe0000003, 0xb8000003, 0x88000003,
-    0xa8000003, 0xf8000003, 0xe8000003, 0xc0000003,
-    0xa0000003, 0xd0000003, 0xc8000003, 0xf0000003,
-    0x80000003, 0x98000003, 0xd8000003, 0x90000003,
-    0x30000001, 0x60000001, 0x38000001, 0x08000001,
-    0x28000001, 0x78000001, 0x68000001, 0x40000001,
-    0x20000001, 0x50000001, 0x48000001, 0x70000001,
-    0x00000001, 0x18000001, 0x58000001, 0x10000001,
-    0xb0000000, 0xe0000000, 0xb8000000, 0x88000000,
-    0xa8000000, 0xf8000000, 0xe8000000, 0xc0000000,
-    0xa0000000, 0xd0000000, 0xc8000000, 0xf0000000,
-    0x80000000, 0x98000000, 0xd8000000, 0x90000000,
-    0xb0000006, 0xe0000006, 0xb8000006, 0x88000006,
-    0xa8000006, 0xf8000006, 0xe8000006, 0xc0000006,
-    0xa0000006, 0xd0000006, 0xc8000006, 0xf0000006,
-    0x80000006, 0x98000006, 0xd8000006, 0x90000006,
-    0xb0000001, 0xe0000001, 0xb8000001, 0x88000001,
-    0xa8000001, 0xf8000001, 0xe8000001, 0xc0000001,
-    0xa0000001, 0xd0000001, 0xc8000001, 0xf0000001,
-    0x80000001, 0x98000001, 0xd8000001, 0x90000001,
-    0x30000003, 0x60000003, 0x38000003, 0x08000003,
-    0x28000003, 0x78000003, 0x68000003, 0x40000003,
-    0x20000003, 0x50000003, 0x48000003, 0x70000003,
-    0x00000003, 0x18000003, 0x58000003, 0x10000003,
-    0x30000004, 0x60000004, 0x38000004, 0x08000004,
-    0x28000004, 0x78000004, 0x68000004, 0x40000004,
-    0x20000004, 0x50000004, 0x48000004, 0x70000004,
-    0x00000004, 0x18000004, 0x58000004, 0x10000004,
-    0xb0000002, 0xe0000002, 0xb8000002, 0x88000002,
-    0xa8000002, 0xf8000002, 0xe8000002, 0xc0000002,
-    0xa0000002, 0xd0000002, 0xc8000002, 0xf0000002,
-    0x80000002, 0x98000002, 0xd8000002, 0x90000002,
-    0xb0000004, 0xe0000004, 0xb8000004, 0x88000004,
-    0xa8000004, 0xf8000004, 0xe8000004, 0xc0000004,
-    0xa0000004, 0xd0000004, 0xc8000004, 0xf0000004,
-    0x80000004, 0x98000004, 0xd8000004, 0x90000004,
-    0x30000006, 0x60000006, 0x38000006, 0x08000006,
-    0x28000006, 0x78000006, 0x68000006, 0x40000006,
-    0x20000006, 0x50000006, 0x48000006, 0x70000006,
-    0x00000006, 0x18000006, 0x58000006, 0x10000006,
-    0xb0000007, 0xe0000007, 0xb8000007, 0x88000007,
-    0xa8000007, 0xf8000007, 0xe8000007, 0xc0000007,
-    0xa0000007, 0xd0000007, 0xc8000007, 0xf0000007,
-    0x80000007, 0x98000007, 0xd8000007, 0x90000007,
-    0x30000007, 0x60000007, 0x38000007, 0x08000007,
-    0x28000007, 0x78000007, 0x68000007, 0x40000007,
-    0x20000007, 0x50000007, 0x48000007, 0x70000007,
-    0x00000007, 0x18000007, 0x58000007, 0x10000007 },
-  /* 3 */
-  { 0x000000e8, 0x000000d8, 0x000000a0, 0x00000088,
-    0x00000098, 0x000000f8, 0x000000a8, 0x000000c8,
-    0x00000080, 0x000000d0, 0x000000f0, 0x000000b8,
-    0x000000b0, 0x000000c0, 0x00000090, 0x000000e0,
-    0x000007e8, 0x000007d8, 0x000007a0, 0x00000788,
-    0x00000798, 0x000007f8, 0x000007a8, 0x000007c8,
-    0x00000780, 0x000007d0, 0x000007f0, 0x000007b8,
-    0x000007b0, 0x000007c0, 0x00000790, 0x000007e0,
-    0x000006e8, 0x000006d8, 0x000006a0, 0x00000688,
-    0x00000698, 0x000006f8, 0x000006a8, 0x000006c8,
-    0x00000680, 0x000006d0, 0x000006f0, 0x000006b8,
-    0x000006b0, 0x000006c0, 0x00000690, 0x000006e0,
-    0x00000068, 0x00000058, 0x00000020, 0x00000008,
-    0x00000018, 0x00000078, 0x00000028, 0x00000048,
-    0x00000000, 0x00000050, 0x00000070, 0x00000038,
-    0x00000030, 0x00000040, 0x00000010, 0x00000060,
-    0x000002e8, 0x000002d8, 0x000002a0, 0x00000288,
-    0x00000298, 0x000002f8, 0x000002a8, 0x000002c8,
-    0x00000280, 0x000002d0, 0x000002f0, 0x000002b8,
-    0x000002b0, 0x000002c0, 0x00000290, 0x000002e0,
-    0x000003e8, 0x000003d8, 0x000003a0, 0x00000388,
-    0x00000398, 0x000003f8, 0x000003a8, 0x000003c8,
-    0x00000380, 0x000003d0, 0x000003f0, 0x000003b8,
-    0x000003b0, 0x000003c0, 0x00000390, 0x000003e0,
-    0x00000568, 0x00000558, 0x00000520, 0x00000508,
-    0x00000518, 0x00000578, 0x00000528, 0x00000548,
-    0x00000500, 0x00000550, 0x00000570, 0x00000538,
-    0x00000530, 0x00000540, 0x00000510, 0x00000560,
-    0x00000268, 0x00000258, 0x00000220, 0x00000208,
-    0x00000218, 0x00000278, 0x00000228, 0x00000248,
-    0x00000200, 0x00000250, 0x00000270, 0x00000238,
-    0x00000230, 0x00000240, 0x00000210, 0x00000260,
-    0x000004e8, 0x000004d8, 0x000004a0, 0x00000488,
-    0x00000498, 0x000004f8, 0x000004a8, 0x000004c8,
-    0x00000480, 0x000004d0, 0x000004f0, 0x000004b8,
-    0x000004b0, 0x000004c0, 0x00000490, 0x000004e0,
-    0x00000168, 0x00000158, 0x00000120, 0x00000108,
-    0x00000118, 0x00000178, 0x00000128, 0x00000148,
-    0x00000100, 0x00000150, 0x00000170, 0x00000138,
-    0x00000130, 0x00000140, 0x00000110, 0x00000160,
-    0x000001e8, 0x000001d8, 0x000001a0, 0x00000188,
-    0x00000198, 0x000001f8, 0x000001a8, 0x000001c8,
-    0x00000180, 0x000001d0, 0x000001f0, 0x000001b8,
-    0x000001b0, 0x000001c0, 0x00000190, 0x000001e0,
-    0x00000768, 0x00000758, 0x00000720, 0x00000708,
-    0x00000718, 0x00000778, 0x00000728, 0x00000748,
-    0x00000700, 0x00000750, 0x00000770, 0x00000738,
-    0x00000730, 0x00000740, 0x00000710, 0x00000760,
-    0x00000368, 0x00000358, 0x00000320, 0x00000308,
-    0x00000318, 0x00000378, 0x00000328, 0x00000348,
-    0x00000300, 0x00000350, 0x00000370, 0x00000338,
-    0x00000330, 0x00000340, 0x00000310, 0x00000360,
-    0x000005e8, 0x000005d8, 0x000005a0, 0x00000588,
-    0x00000598, 0x000005f8, 0x000005a8, 0x000005c8,
-    0x00000580, 0x000005d0, 0x000005f0, 0x000005b8,
-    0x000005b0, 0x000005c0, 0x00000590, 0x000005e0,
-    0x00000468, 0x00000458, 0x00000420, 0x00000408,
-    0x00000418, 0x00000478, 0x00000428, 0x00000448,
-    0x00000400, 0x00000450, 0x00000470, 0x00000438,
-    0x00000430, 0x00000440, 0x00000410, 0x00000460,
-    0x00000668, 0x00000658, 0x00000620, 0x00000608,
-    0x00000618, 0x00000678, 0x00000628, 0x00000648,
-    0x00000600, 0x00000650, 0x00000670, 0x00000638,
-    0x00000630, 0x00000640, 0x00000610, 0x00000660 }
-};
+#include "bufhelp.h"
 
 #include "gost.h"
+#include "gost-sb.h"
 
 static gcry_err_code_t
 gost_setkey (void *c, const byte *key, unsigned keylen)
@@ -315,12 +47,12 @@ gost_setkey (void *c, const byte *key, unsigned keylen)
   if (keylen != 256 / 8)
     return GPG_ERR_INV_KEYLEN;
 
+  if (!ctx->sbox)
+    ctx->sbox = sbox_test_3411;
+
   for (i = 0; i < 8; i++)
     {
-      ctx->key[i] = (key[4 * i + 3] << 24) |
-                    (key[4 * i + 2] << 16) |
-                    (key[4 * i + 1] <<  8) |
-                    (key[4 * i + 0] <<  0);
+      ctx->key[i] = buf_get_le32(&key[4*i]);
     }
   return GPG_ERR_NO_ERROR;
 }
@@ -329,27 +61,17 @@ static u32
 gost_val (GOST28147_context *ctx, u32 cm1, int subkey)
 {
   cm1 += ctx->key[subkey];
-  cm1 = test_sbox[0][ (cm1 >>  0) & 0xff] |
-        test_sbox[1][ (cm1 >>  8) & 0xff] |
-        test_sbox[2][ (cm1 >> 16) & 0xff] |
-        test_sbox[3][ (cm1 >> 24) & 0xff];
+  cm1 = ctx->sbox[0*256 + ((cm1 >>  0) & 0xff)] |
+        ctx->sbox[1*256 + ((cm1 >>  8) & 0xff)] |
+        ctx->sbox[2*256 + ((cm1 >> 16) & 0xff)] |
+        ctx->sbox[3*256 + ((cm1 >> 24) & 0xff)];
   return cm1;
 }
 
 static unsigned int
-gost_encrypt_block (void *c, byte *outbuf, const byte *inbuf)
+_gost_encrypt_data (void *c, u32 *o1, u32 *o2, u32 n1, u32 n2)
 {
   GOST28147_context *ctx = c;
-  u32 n1, n2;
-
-  n1 =  (inbuf[0] << 0) |
-        (inbuf[1] << 8) |
-        (inbuf[2] << 16) |
-        (inbuf[3] << 24);
-  n2 =  (inbuf[4] << 0) |
-        (inbuf[5] << 8) |
-        (inbuf[6] << 16) |
-        (inbuf[7] << 24);
 
   n2 ^= gost_val (ctx, n1, 0); n1 ^= gost_val (ctx, n2, 1);
   n2 ^= gost_val (ctx, n1, 2); n1 ^= gost_val (ctx, n2, 3);
@@ -371,25 +93,41 @@ gost_encrypt_block (void *c, byte *outbuf, const byte *inbuf)
   n2 ^= gost_val (ctx, n1, 3); n1 ^= gost_val (ctx, n2, 2);
   n2 ^= gost_val (ctx, n1, 1); n1 ^= gost_val (ctx, n2, 0);
 
-  outbuf[0 + 0] = (n2 >> (0 * 8)) & 0xff;
-  outbuf[1 + 0] = (n2 >> (1 * 8)) & 0xff;
-  outbuf[2 + 0] = (n2 >> (2 * 8)) & 0xff;
-  outbuf[3 + 0] = (n2 >> (3 * 8)) & 0xff;
-  outbuf[0 + 4] = (n1 >> (0 * 8)) & 0xff;
-  outbuf[1 + 4] = (n1 >> (1 * 8)) & 0xff;
-  outbuf[2 + 4] = (n1 >> (2 * 8)) & 0xff;
-  outbuf[3 + 4] = (n1 >> (3 * 8)) & 0xff;
+  *o1 = n2;
+  *o2 = n1;
 
   return /* burn_stack */ 4*sizeof(void*) /* func call */ +
                           3*sizeof(void*) /* stack */ +
                           4*sizeof(void*) /* gost_val call */;
 }
 
-unsigned int _gcry_gost_enc_one (GOST28147_context *c, const byte *key,
-    byte *out, byte *in)
+static unsigned int
+gost_encrypt_block (void *c, byte *outbuf, const byte *inbuf)
 {
-  gost_setkey (c, key, 32);
-  return gost_encrypt_block (c, out, in) + 5 * sizeof(void *);
+  GOST28147_context *ctx = c;
+  u32 n1, n2;
+  unsigned int burn;
+
+  n1 = buf_get_le32 (inbuf);
+  n2 = buf_get_le32 (inbuf+4);
+
+  burn = _gost_encrypt_data(ctx, &n1, &n2, n1, n2);
+
+  buf_put_le32 (outbuf+0, n1);
+  buf_put_le32 (outbuf+4, n2);
+
+  return /* burn_stack */ burn + 6*sizeof(void*) /* func call */;
+}
+
+unsigned int _gcry_gost_enc_data (GOST28147_context *c, const u32 *key,
+    u32 *o1, u32 *o2, u32 n1, u32 n2, int cryptopro)
+{
+  if (cryptopro)
+    c->sbox = sbox_CryptoPro_3411;
+  else
+    c->sbox = sbox_test_3411;
+  memcpy (c->key, key, 8*4);
+  return _gost_encrypt_data (c, o1, o2, n1, n2) + 7 * sizeof(void *);
 }
 
 static unsigned int
@@ -398,14 +136,8 @@ gost_decrypt_block (void *c, byte *outbuf, const byte *inbuf)
   GOST28147_context *ctx = c;
   u32 n1, n2;
 
-  n1 =  (inbuf[0] << 0) |
-        (inbuf[1] << 8) |
-        (inbuf[2] << 16) |
-        (inbuf[3] << 24);
-  n2 =  (inbuf[4] << 0) |
-        (inbuf[5] << 8) |
-        (inbuf[6] << 16) |
-        (inbuf[7] << 24);
+  n1 = buf_get_le32 (inbuf);
+  n2 = buf_get_le32 (inbuf+4);
 
   n2 ^= gost_val (ctx, n1, 0); n1 ^= gost_val (ctx, n2, 1);
   n2 ^= gost_val (ctx, n1, 2); n1 ^= gost_val (ctx, n2, 3);
@@ -427,26 +159,69 @@ gost_decrypt_block (void *c, byte *outbuf, const byte *inbuf)
   n2 ^= gost_val (ctx, n1, 3); n1 ^= gost_val (ctx, n2, 2);
   n2 ^= gost_val (ctx, n1, 1); n1 ^= gost_val (ctx, n2, 0);
 
-  outbuf[0 + 0] = (n2 >> (0 * 8)) & 0xff;
-  outbuf[1 + 0] = (n2 >> (1 * 8)) & 0xff;
-  outbuf[2 + 0] = (n2 >> (2 * 8)) & 0xff;
-  outbuf[3 + 0] = (n2 >> (3 * 8)) & 0xff;
-  outbuf[0 + 4] = (n1 >> (0 * 8)) & 0xff;
-  outbuf[1 + 4] = (n1 >> (1 * 8)) & 0xff;
-  outbuf[2 + 4] = (n1 >> (2 * 8)) & 0xff;
-  outbuf[3 + 4] = (n1 >> (3 * 8)) & 0xff;
+  buf_put_le32 (outbuf+0, n2);
+  buf_put_le32 (outbuf+4, n1);
 
   return /* burn_stack */ 4*sizeof(void*) /* func call */ +
                           3*sizeof(void*) /* stack */ +
                           4*sizeof(void*) /* gost_val call */;
 }
 
+static gpg_err_code_t
+gost_set_sbox (GOST28147_context *ctx, const char *oid)
+{
+  int i;
+
+  for (i = 0; gost_oid_map[i].oid; i++)
+    {
+      if (!strcmp(gost_oid_map[i].oid, oid))
+        {
+          ctx->sbox = gost_oid_map[i].sbox;
+          return 0;
+        }
+    }
+  return GPG_ERR_VALUE_NOT_FOUND;
+}
+
+static gpg_err_code_t
+gost_set_extra_info (void *c, int what, const void *buffer, size_t buflen)
+{
+  GOST28147_context *ctx = c;
+  gpg_err_code_t ec = 0;
+
+  (void)buffer;
+  (void)buflen;
+
+  switch (what)
+    {
+    case GCRYCTL_SET_SBOX:
+      ec = gost_set_sbox (ctx, buffer);
+      break;
+
+    default:
+      ec = GPG_ERR_INV_OP;
+      break;
+    }
+  return ec;
+}
+
+static gcry_cipher_oid_spec_t oids_gost28147[] =
+  {
+    /* { "1.2.643.2.2.31.0", GCRY_CIPHER_MODE_CNTGOST }, */
+    { "1.2.643.2.2.31.1", GCRY_CIPHER_MODE_CFB },
+    { "1.2.643.2.2.31.2", GCRY_CIPHER_MODE_CFB },
+    { "1.2.643.2.2.31.3", GCRY_CIPHER_MODE_CFB },
+    { "1.2.643.2.2.31.4", GCRY_CIPHER_MODE_CFB },
+    { NULL }
+  };
+
 gcry_cipher_spec_t _gcry_cipher_spec_gost28147 =
   {
     GCRY_CIPHER_GOST28147, {0, 0},
-    "GOST28147", NULL, NULL, 8, 256,
+    "GOST28147", NULL, oids_gost28147, 8, 256,
     sizeof (GOST28147_context),
     gost_setkey,
     gost_encrypt_block,
     gost_decrypt_block,
+    NULL, NULL, NULL, gost_set_extra_info,
   };
index 5486964..a782427 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "g10lib.h"
 #include "bithelp.h"
+#include "bufhelp.h"
 #include "cipher.h"
 #include "hash-common.h"
 
 typedef struct {
   gcry_md_block_ctx_t bctx;
   GOST28147_context hd;
-  byte h[32];
-  byte sigma[32];
+  union {
+    u32 h[8];
+    byte result[32];
+  };
+  u32 sigma[8];
   u32 len;
+  int cryptopro;
 } GOSTR3411_CONTEXT;
 
 static unsigned int
-transform (void *c, const unsigned char *data);
+transform (void *c, const unsigned char *data, size_t nblks);
 
 static void
 gost3411_init (void *context, unsigned int flags)
@@ -58,105 +63,134 @@ gost3411_init (void *context, unsigned int flags)
   hd->bctx.count = 0;
   hd->bctx.blocksize = 32;
   hd->bctx.bwrite = transform;
+  hd->cryptopro = 0;
+}
+
+static void
+gost3411_cp_init (void *context, unsigned int flags)
+{
+  GOSTR3411_CONTEXT *hd = context;
+  gost3411_init (context, flags);
+  hd->cryptopro = 1;
 }
 
 static void
-do_p (unsigned char *p, unsigned char *u, unsigned char *v)
+do_p (u32 *p, u32 *u, u32 *v)
 {
-  int i, k;
+  int k;
+  u32 t[8];
+
   for (k = 0; k < 8; k++)
+    t[k] = u[k] ^ v[k];
+
+  for (k = 0; k < 4; k++)
     {
-      for (i = 0; i < 4; i++)
-        {
-          p[i + 4 * k] = u[8 * i + k] ^ v[8 * i + k];
-        }
+          p[k+0] = ((t[0] >> (8*k)) & 0xff) << 0 |
+                   ((t[2] >> (8*k)) & 0xff) << 8 |
+                   ((t[4] >> (8*k)) & 0xff) << 16 |
+                   ((t[6] >> (8*k)) & 0xff) << 24;
+          p[k+4] = ((t[1] >> (8*k)) & 0xff) << 0 |
+                   ((t[3] >> (8*k)) & 0xff) << 8 |
+                   ((t[5] >> (8*k)) & 0xff) << 16 |
+                   ((t[7] >> (8*k)) & 0xff) << 24;
     }
 }
 
 static void
-do_a (unsigned char *u)
+do_a (u32 *u)
 {
-  unsigned char temp[8];
+  u32 t[2];
   int i;
-  memcpy (temp, u, 8);
-  memmove (u, u+8, 24);
-  for (i = 0; i < 8; i++)
-    {
-      u[24 + i] = u[i] ^ temp[i];
-    }
+  memcpy(t, u, 2*4);
+  for (i = 0; i < 6; i++)
+    u[i] = u[i+2];
+  u[6] = u[0] ^ t[0];
+  u[7] = u[1] ^ t[1];
 }
 /* apply do_a twice: 1 2 3 4 -> 3 4 1^2 2^3 */
 static void
-do_a2 (unsigned char *u)
+do_a2 (u32 *u)
 {
-  unsigned char temp[16];
+  u32 t[4];
   int i;
-  memcpy (temp, u, 16);
-  memcpy (u, u + 16, 16);
-  for (i = 0; i < 8; i++)
+  memcpy (t, u, 16);
+  memcpy (u, u + 4, 16);
+  for (i = 0; i < 2; i++)
     {
-      u[16 + i] = temp[i] ^ temp[8 + i];
-      u[24 + i] =    u[i] ^ temp[8 + i];
+      u[4+i] = t[i] ^ t[i + 2];
+      u[6+i] = u[i] ^ t[i + 2];
     }
 }
 
 static void
-do_apply_c2 (unsigned char *u)
+do_apply_c2 (u32 *u)
 {
-  u[ 1] ^= 0xff;
-  u[ 3] ^= 0xff;
-  u[ 5] ^= 0xff;
-  u[ 7] ^= 0xff;
-
-  u[ 8] ^= 0xff;
-  u[10] ^= 0xff;
-  u[12] ^= 0xff;
-  u[14] ^= 0xff;
-
-  u[17] ^= 0xff;
-  u[18] ^= 0xff;
-  u[20] ^= 0xff;
-  u[23] ^= 0xff;
-
-  u[24] ^= 0xff;
-  u[28] ^= 0xff;
-  u[29] ^= 0xff;
-  u[31] ^= 0xff;
+  u[ 0] ^= 0xff00ff00;
+  u[ 1] ^= 0xff00ff00;
+  u[ 2] ^= 0x00ff00ff;
+  u[ 3] ^= 0x00ff00ff;
+  u[ 4] ^= 0x00ffff00;
+  u[ 5] ^= 0xff0000ff;
+  u[ 6] ^= 0x000000ff;
+  u[ 7] ^= 0xff00ffff;
 }
 
-#define do_phi_step(e, i) \
-  e[(0 + 2*i) % 32] ^= e[(2 + 2*i) % 32] ^ e[(4 + 2*i) % 32] ^ e[(6 + 2*i) % 32] ^ e[(24 + 2*i) % 32] ^ e[(30 + 2*i) % 32]; \
-  e[(1 + 2*i) % 32] ^= e[(3 + 2*i) % 32] ^ e[(5 + 2*i) % 32] ^ e[(7 + 2*i) % 32] ^ e[(25 + 2*i) % 32] ^ e[(31 + 2*i) % 32];
+#define do_chi_step12(e) \
+  e[6] ^= ((e[6] >> 16) ^ e[7] ^ (e[7] >> 16) ^ e[4] ^ (e[5] >>16)) & 0xffff;
+
+#define do_chi_step13(e) \
+  e[6] ^= ((e[7] ^ (e[7] >> 16) ^ e[0] ^ (e[4] >> 16) ^ e[6]) & 0xffff) << 16;
+
+#define do_chi_doublestep(e, i) \
+  e[i] ^= (e[i] >> 16) ^ (e[(i+1)%8] << 16) ^ e[(i+1)%8] ^ (e[(i+1)%8] >> 16) ^ (e[(i+2)%8] << 16) ^ e[(i+6)%8] ^ (e[(i+7)%8] >> 16); \
+  e[i] ^= (e[i] << 16);
 
 static void
-do_phi_submix (unsigned char *e, unsigned char *x, int round)
+do_chi_submix12 (u32 *e, u32 *x)
 {
-  int i;
-  round *= 2;
-  for (i = 0; i < 32; i++)
-    {
-      e[(i + round) % 32] ^= x[i];
-    }
+  e[6] ^= x[0];
+  e[7] ^= x[1];
+  e[0] ^= x[2];
+  e[1] ^= x[3];
+  e[2] ^= x[4];
+  e[3] ^= x[5];
+  e[4] ^= x[6];
+  e[5] ^= x[7];
 }
 
 static void
-do_add (unsigned char *s, unsigned char *a)
+do_chi_submix13 (u32 *e, u32 *x)
 {
-  unsigned temp = 0;
+  e[6] ^= (x[0] << 16) | (x[7] >> 16);
+  e[7] ^= (x[1] << 16) | (x[0] >> 16);
+  e[0] ^= (x[2] << 16) | (x[1] >> 16);
+  e[1] ^= (x[3] << 16) | (x[2] >> 16);
+  e[2] ^= (x[4] << 16) | (x[3] >> 16);
+  e[3] ^= (x[5] << 16) | (x[4] >> 16);
+  e[4] ^= (x[6] << 16) | (x[5] >> 16);
+  e[5] ^= (x[7] << 16) | (x[6] >> 16);
+}
+
+static void
+do_add (u32 *s, u32 *a)
+{
+  u32 carry = 0;
   int i;
 
-  for (i = 0; i < 32; i++)
+  for (i = 0; i < 8; i++)
     {
-      temp = s[i] + a[i] + (temp >> 8);
-      s[i] = temp & 0xff;
+      u32 op = carry + a[i];
+      s[i] += op;
+      carry = (a[i] > op) || (op > s[i]);
     }
 }
 
 static unsigned int
-do_hash_step (GOST28147_context *hd, unsigned char *h, unsigned char *m)
+do_hash_step (GOSTR3411_CONTEXT *hd, u32 *h, u32 *m)
 {
-  unsigned char u[32], v[32], s[32];
-  unsigned char k[32];
+  u32 u[8], v[8];
+  u32 s[8];
+  u32 k[8];
   unsigned int burn;
   int i;
 
@@ -166,7 +200,7 @@ do_hash_step (GOST28147_context *hd, unsigned char *h, unsigned char *m)
   for (i = 0; i < 4; i++) {
     do_p (k, u, v);
 
-    burn = _gcry_gost_enc_one (hd, k, s + i*8, h + i*8);
+    burn = _gcry_gost_enc_data (&hd->hd, k, &s[2*i], &s[2*i+1], h[2*i], h[2*i+1], hd->cryptopro);
 
     do_a (u);
     if (i == 1)
@@ -176,33 +210,26 @@ do_hash_step (GOST28147_context *hd, unsigned char *h, unsigned char *m)
 
   for (i = 0; i < 5; i++)
     {
-      do_phi_step (s, 0);
-      do_phi_step (s, 1);
-      do_phi_step (s, 2);
-      do_phi_step (s, 3);
-      do_phi_step (s, 4);
-      do_phi_step (s, 5);
-      do_phi_step (s, 6);
-      do_phi_step (s, 7);
-      do_phi_step (s, 8);
-      do_phi_step (s, 9);
+      do_chi_doublestep (s, 0);
+      do_chi_doublestep (s, 1);
+      do_chi_doublestep (s, 2);
+      do_chi_doublestep (s, 3);
+      do_chi_doublestep (s, 4);
       /* That is in total 12 + 1 + 61 = 74 = 16 * 4 + 10 rounds */
       if (i == 4)
         break;
-      do_phi_step (s, 10);
-      do_phi_step (s, 11);
+      do_chi_doublestep (s, 5);
       if (i == 0)
-        do_phi_submix(s, m, 12);
-      do_phi_step (s, 12);
+        do_chi_submix12(s, m);
+      do_chi_step12 (s);
       if (i == 0)
-        do_phi_submix(s, h, 13);
-      do_phi_step (s, 13);
-      do_phi_step (s, 14);
-      do_phi_step (s, 15);
+        do_chi_submix13(s, h);
+      do_chi_step13 (s);
+      do_chi_doublestep (s, 7);
     }
 
-  memcpy (h, s+20, 12);
-  memcpy (h+12, s, 20);
+  memcpy (h, s+5, 12);
+  memcpy (h+3, s, 20);
 
   return /* burn_stack */ 4 * sizeof(void*) /* func call (ret addr + args) */ +
                           4 * 32 + 2 * sizeof(int) /* stack */ +
@@ -211,21 +238,39 @@ do_hash_step (GOST28147_context *hd, unsigned char *h, unsigned char *m)
                               16 + sizeof(int) /* do_a2 stack */ );
 }
 
-
 static unsigned int
-transform (void *ctx, const unsigned char *data)
+transform_blk (void *ctx, const unsigned char *data)
 {
   GOSTR3411_CONTEXT *hd = ctx;
-  byte m[32];
+  u32 m[8];
   unsigned int burn;
+  int i;
 
-  memcpy (m, data, 32);
-  burn = do_hash_step (&hd->hd, hd->h, m);
+  for (i = 0; i < 8; i++)
+    m[i] = buf_get_le32(data + i*4);
+  burn = do_hash_step (hd, hd->h, m);
   do_add (hd->sigma, m);
 
   return /* burn_stack */ burn + 3 * sizeof(void*) + 32 + 2 * sizeof(void*);
 }
 
+
+static unsigned int
+transform ( void *c, const unsigned char *data, size_t nblks )
+{
+  unsigned int burn;
+
+  do
+    {
+      burn = transform_blk (c, data);
+      data += 32;
+    }
+  while (--nblks);
+
+  return burn;
+}
+
+
 /*
    The routine finally terminates the computation and returns the
    digest.  The handle is prepared for a new cycle, but adding bytes
@@ -236,9 +281,9 @@ gost3411_final (void *context)
 {
   GOSTR3411_CONTEXT *hd = context;
   size_t padlen = 0;
-  byte l[32];
+  u32 l[8];
   int i;
-  u32 nblocks;
+  MD_NBLOCKS_TYPE nblocks;
 
   if (hd->bctx.count > 0)
     {
@@ -259,15 +304,19 @@ gost3411_final (void *context)
       nblocks --;
       l[0] = 256 - padlen * 8;
     }
+  l[0] |= nblocks << 8;
+  nblocks >>= 24;
 
-  for (i = 1; i < 32 && nblocks != 0; i++)
+  for (i = 1; i < 8 && nblocks != 0; i++)
     {
-      l[i] = nblocks % 256;
-      nblocks /= 256;
+      l[i] = nblocks;
+      nblocks >>= 24;
     }
 
-  do_hash_step (&hd->hd, hd->h, l);
-  do_hash_step (&hd->hd, hd->h, hd->sigma);
+  do_hash_step (hd, hd->h, l);
+  do_hash_step (hd, hd->h, hd->sigma);
+  for (i = 0; i < 8; i++)
+    hd->h[i] = le_bswap32(hd->h[i]);
 }
 
 static byte *
@@ -275,12 +324,32 @@ gost3411_read (void *context)
 {
   GOSTR3411_CONTEXT *hd = context;
 
-  return hd->h;
+  return hd->result;
 }
+
+static unsigned char asn[6] = /* Object ID is 1.2.643.2.2.3 */
+  { 0x2a, 0x85, 0x03, 0x02, 0x02, 0x03 };
+
+static gcry_md_oid_spec_t oid_spec_gostr3411[] =
+  {
+    /* iso.member-body.ru.rans.cryptopro.3 (gostR3411-94-with-gostR3410-2001) */
+    { "1.2.643.2.2.3" },
+    /* iso.member-body.ru.rans.cryptopro.9 (gostR3411-94) */
+    { "1.2.643.2.2.9" },
+    {NULL},
+  };
+
 gcry_md_spec_t _gcry_digest_spec_gost3411_94 =
   {
     GCRY_MD_GOSTR3411_94, {0, 0},
     "GOSTR3411_94", NULL, 0, NULL, 32,
-    gost3411_init, _gcry_md_block_write, gost3411_final, gost3411_read,
+    gost3411_init, _gcry_md_block_write, gost3411_final, gost3411_read, NULL,
+    sizeof (GOSTR3411_CONTEXT)
+  };
+gcry_md_spec_t _gcry_digest_spec_gost3411_cp =
+  {
+    GCRY_MD_GOSTR3411_CP, {0, 0},
+    "GOSTR3411_CP", asn, DIM (asn), oid_spec_gostr3411, 32,
+    gost3411_cp_init, _gcry_md_block_write, gost3411_final, gost3411_read, NULL,
     sizeof (GOSTR3411_CONTEXT)
   };
index ffbc39e..a750d64 100644 (file)
@@ -49,8 +49,12 @@ _gcry_hash_selftest_check_one (int algo,
   gcry_error_t err = 0;
   gcry_md_hd_t hd;
   unsigned char *digest;
+  char aaa[1000];
+  int xof = 0;
 
-  if (_gcry_md_get_algo_dlen (algo) != expectlen)
+  if (_gcry_md_get_algo_dlen (algo) == 0)
+    xof = 1;
+  else if (_gcry_md_get_algo_dlen (algo) != expectlen)
     return "digest size does not match expected size";
 
   err = _gcry_md_open (&hd, algo, 0);
@@ -65,7 +69,6 @@ _gcry_hash_selftest_check_one (int algo,
 
     case 1: /* Hash one million times an "a". */
       {
-        char aaa[1000];
         int i;
 
         /* Write in odd size chunks so that we test the buffering.  */
@@ -81,10 +84,23 @@ _gcry_hash_selftest_check_one (int algo,
 
   if (!result)
     {
-      digest = _gcry_md_read (hd, algo);
-
-      if ( memcmp (digest, expect, expectlen) )
-        result = "digest mismatch";
+      if (!xof)
+       {
+         digest = _gcry_md_read (hd, algo);
+
+         if ( memcmp (digest, expect, expectlen) )
+           result = "digest mismatch";
+       }
+      else
+       {
+         gcry_assert(expectlen <= sizeof(aaa));
+
+         err = _gcry_md_extract (hd, algo, aaa, expectlen);
+         if (err)
+           result = "error extracting output from XOF";
+         else if ( memcmp (aaa, expect, expectlen) )
+           result = "digest mismatch";
+       }
     }
 
   _gcry_md_close (hd);
@@ -95,23 +111,28 @@ _gcry_hash_selftest_check_one (int algo,
 
 /* Common function to write a chunk of data to the transform function
    of a hash algorithm.  Note that the use of the term "block" does
-   not imply a fixed size block.  */
+   not imply a fixed size block.  Note that we explicitly allow to use
+   this function after the context has been finalized; the result does
+   not have any meaning but writing after finalize is sometimes
+   helpful to mitigate timing attacks. */
 void
 _gcry_md_block_write (void *context, const void *inbuf_arg, size_t inlen)
 {
   const unsigned char *inbuf = inbuf_arg;
   gcry_md_block_ctx_t *hd = context;
   unsigned int stack_burn = 0;
+  const unsigned int blocksize = hd->blocksize;
+  size_t inblocks;
 
-  if (sizeof(hd->buf) < hd->blocksize)
+  if (sizeof(hd->buf) < blocksize)
     BUG();
 
-  if (hd->buf == NULL || hd->bwrite == NULL)
+  if (!hd->bwrite)
     return;
 
-  if (hd->count == hd->blocksize)  /* Flush the buffer. */
+  if (hd->count == blocksize)  /* Flush the buffer. */
     {
-      stack_burn = hd->bwrite (hd, hd->buf);
+      stack_burn = hd->bwrite (hd, hd->buf, 1);
       _gcry_burn_stack (stack_burn);
       stack_burn = 0;
       hd->count = 0;
@@ -123,23 +144,24 @@ _gcry_md_block_write (void *context, const void *inbuf_arg, size_t inlen)
 
   if (hd->count)
     {
-      for (; inlen && hd->count < hd->blocksize; inlen--)
+      for (; inlen && hd->count < blocksize; inlen--)
         hd->buf[hd->count++] = *inbuf++;
       _gcry_md_block_write (hd, NULL, 0);
       if (!inlen)
         return;
     }
 
-  while (inlen >= hd->blocksize)
+  if (inlen >= blocksize)
     {
-      stack_burn = hd->bwrite (hd, inbuf);
+      inblocks = inlen / blocksize;
+      stack_burn = hd->bwrite (hd, inbuf, inblocks);
       hd->count = 0;
-      if (!++hd->nblocks)
-        hd->nblocks_high++;
-      inlen -= hd->blocksize;
-      inbuf += hd->blocksize;
+      hd->nblocks_high += (hd->nblocks + inblocks < inblocks);
+      hd->nblocks += inblocks;
+      inlen -= inblocks * blocksize;
+      inbuf += inblocks * blocksize;
     }
   _gcry_burn_stack (stack_burn);
-  for (; inlen && hd->count < hd->blocksize; inlen--)
+  for (; inlen && hd->count < blocksize; inlen--)
     hd->buf[hd->count++] = *inbuf++;
 }
index aa95365..23f81ed 100644 (file)
@@ -30,10 +30,11 @@ const char * _gcry_hash_selftest_check_one
 
 /* Type for the md_write helper function.  */
 typedef unsigned int (*_gcry_md_block_write_t) (void *c,
-                                               const unsigned char *buf);
+                                               const unsigned char *blks,
+                                               size_t nblks);
 
-#if defined(HAVE_U64_TYPEDEF) && (defined(USE_SHA512) || defined(USE_WHIRLPOOL))
-/* SHA-512 needs u64 and larger buffer. Whirlpool needs u64. */
+#if (defined(USE_SHA512) || defined(USE_WHIRLPOOL))
+/* SHA-512 and Whirlpool needs u64. SHA-512 needs larger buffer. */
 # define MD_BLOCK_MAX_BLOCKSIZE 128
 # define MD_NBLOCKS_TYPE u64
 #else
index 7c27342..8c04708 100644 (file)
@@ -701,6 +701,17 @@ run_selftests (int algo, int extended, selftest_report_func_t report)
     case GCRY_MD_SHA512:
       ec = selftests_sha512 (extended, report);
       break;
+
+    case GCRY_MD_SHA3_224:
+    case GCRY_MD_SHA3_256:
+    case GCRY_MD_SHA3_384:
+    case GCRY_MD_SHA3_512:
+      ec = 0;  /* FIXME: Add selftests.  */
+#if defined(__GNUC__) && defined(IS_DEVELOPMENT_VERSION)
+# warning Please add self test functions for HMAC-SHA3
+#endif
+      break;
+
     default:
       ec = GPG_ERR_DIGEST_ALGO;
       break;
index af0dc48..27f5789 100644 (file)
@@ -26,7 +26,6 @@
 
 #include "g10lib.h"
 #include "cipher.h"
-#include "ath.h"
 #include "kdf-internal.h"
 
 
@@ -126,7 +125,7 @@ _gcry_kdf_pkdf2 (const void *passphrase, size_t passphraselen,
   gpg_err_code_t ec;
   gcry_md_hd_t md;
   int secmode;
-  unsigned int dklen = keysize;
+  unsigned long dklen = keysize;
   char *dk = keybuffer;
   unsigned int hlen;   /* Output length of the digest function.  */
   unsigned int l;      /* Rounded up number of blocks.  */
@@ -139,7 +138,7 @@ _gcry_kdf_pkdf2 (const void *passphrase, size_t passphraselen,
   unsigned long iter;  /* Current iteration number.  */
   unsigned int i;
 
-  /* NWe allow for a saltlen of 0 here to support scrypt.  It is not
+  /* We allow for a saltlen of 0 here to support scrypt.  It is not
      clear whether rfc2898 allows for this this, thus we do a test on
      saltlen > 0 only in gcry_kdf_derive.  */
   if (!salt || !iterations || !dklen)
@@ -151,8 +150,16 @@ _gcry_kdf_pkdf2 (const void *passphrase, size_t passphraselen,
 
   secmode = _gcry_is_secure (passphrase) || _gcry_is_secure (keybuffer);
 
-  /* We ignore step 1 from pksc5v2.1 which demands a check that dklen
-     is not larger that 0xffffffff * hlen.  */
+  /* Step 1 */
+  /* If dkLen > (2^32 - 1) * hLen, output "derived key too long" and
+   * stop.  We use a stronger inequality but only if our type can hold
+   * a larger value.  */
+
+#if SIZEOF_UNSIGNED_LONG > 4
+  if (dklen > 0xffffffffU)
+    return GPG_ERR_INV_VALUE;
+#endif
+
 
   /* Step 2 */
   l = ((dklen - 1)/ hlen) + 1;
diff --git a/cipher/keccak-armv7-neon.S b/cipher/keccak-armv7-neon.S
new file mode 100644 (file)
index 0000000..0bec8d5
--- /dev/null
@@ -0,0 +1,945 @@
+/* keccak-armv7-neon.S  -  ARMv7/NEON implementation of Keccak
+ *
+ * Copyright (C) 2015 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) && \
+    defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \
+    defined(HAVE_GCC_INLINE_ASM_NEON)
+
+/* Based on public-domain/CC0 implementation from SUPERCOP package
+ * (keccakc1024/inplace-armv7a-neon/keccak2.s)
+ *
+ * Original copyright header follows:
+ */
+
+@ The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
+@ Michaël Peeters and Gilles Van Assche. For more information, feedback or
+@ questions, please refer to our website: http://keccak.noekeon.org/
+@
+@ Implementation by Ronny Van Keer, hereby denoted as "the implementer".
+@
+@ To the extent possible under law, the implementer has waived all copyright
+@ and related or neighboring rights to the source code in this file.
+@ http://creativecommons.org/publicdomain/zero/1.0/
+
+.text
+
+.syntax unified
+.fpu neon
+.arm
+
+
+.extern _gcry_keccak_round_consts_64bit;
+
+#ifdef __PIC__
+#  define GET_DATA_POINTER(reg, name, rtmp) \
+               ldr reg, 1f; \
+               ldr rtmp, 2f; \
+               b 3f; \
+       1:      .word _GLOBAL_OFFSET_TABLE_-(3f+8); \
+       2:      .word name(GOT); \
+       3:      add reg, pc, reg; \
+               ldr reg, [reg, rtmp];
+#else
+#  define GET_DATA_POINTER(reg, name, rtmp) ldr reg, =name
+#endif
+
+
+@//  --- offsets in state
+.equ Aba, 0*8
+.equ Aga, 1*8
+.equ Aka, 2*8
+.equ Ama, 3*8
+.equ Asa, 4*8
+
+@// --- macros
+
+.macro    KeccakThetaRhoPiChiIota argA1, argA2, argA3, argA4, argA5
+
+    @Prepare Theta
+    @Ca = Aba^Aga^Aka^Ama^Asa@
+    @Ce = Abe^Age^Ake^Ame^Ase@
+    @Ci = Abi^Agi^Aki^Ami^Asi@
+    @Co = Abo^Ago^Ako^Amo^Aso@
+    @Cu = Abu^Agu^Aku^Amu^Asu@
+    @De = Ca^ROL64(Ci, 1)@
+    @Di = Ce^ROL64(Co, 1)@
+    @Do = Ci^ROL64(Cu, 1)@
+    @Du = Co^ROL64(Ca, 1)@
+    @Da = Cu^ROL64(Ce, 1)@
+
+    veor.64 q4, q6, q7
+    veor.64 q5, q9, q10
+    veor.64 d8,  d8,   d9
+    veor.64 d10,  d10,   d11
+    veor.64 d1,  d8,   d16
+    veor.64 d2,  d10,   d17
+
+    veor.64 q4, q11, q12
+    veor.64 q5, q14, q15
+    veor.64 d8,  d8,   d9
+    veor.64 d10,  d10,   d11
+    veor.64 d3,  d8,   d26
+
+    vadd.u64 q4, q1, q1
+    veor.64 d4,  d10,   d27
+    vmov.64  d0, d5
+    vsri.64 q4, q1, #63
+
+    vadd.u64 q5, q2, q2
+    veor.64 q4, q4, q0
+    vsri.64 q5, q2, #63
+    vadd.u64 d7, d1, d1
+    veor.64 \argA2, \argA2, d8
+    veor.64 q5, q5, q1
+
+    vsri.64 d7, d1, #63
+    vshl.u64 d1, \argA2, #44
+    veor.64 \argA3, \argA3, d9
+    veor.64 d7, d7, d4
+
+    @Ba = argA1^Da@
+    @Be = ROL64((argA2^De), 44)@
+    @Bi = ROL64((argA3^Di), 43)@
+    @Bo = ROL64((argA4^Do), 21)@
+    @Bu = ROL64((argA5^Du), 14)@
+    @argA2 =   Be ^((~Bi)& Bo )@
+    @argA3 =   Bi ^((~Bo)& Bu )@
+    @argA4 =   Bo ^((~Bu)& Ba )@
+    @argA5 =   Bu ^((~Ba)& Be )@
+    @argA1 =   Ba ^((~Be)& Bi )@ argA1 ^= KeccakF1600RoundConstants[i+round]@
+    vsri.64 d1, \argA2, #64-44
+    vshl.u64 d2, \argA3, #43
+    vldr.64 d0, [sp, #\argA1]
+    veor.64 \argA4, \argA4, d10
+    vsri.64 d2, \argA3, #64-43
+    vshl.u64 d3, \argA4, #21
+    veor.64 \argA5, \argA5, d11
+    veor.64 d0, d0, d7
+    vsri.64 d3, \argA4, #64-21
+    vbic.64   d5, d2, d1
+    vshl.u64 d4, \argA5, #14
+    vbic.64   \argA2, d3, d2
+    vld1.64   d6, [ip]!
+    veor.64   d5, d0
+    vsri.64 d4, \argA5, #64-14
+    veor.64   d5, d6
+    vbic.64   \argA5, d1, d0
+    vbic.64   \argA3, d4, d3
+    vbic.64   \argA4, d0, d4
+    veor.64   \argA2, d1
+    vstr.64   d5, [sp, #\argA1]
+    veor.64   \argA3, d2
+    veor.64   \argA4, d3
+    veor.64   \argA5, d4
+
+    .endm
+
+.macro    KeccakThetaRhoPiChi1   argA1, argA2, argA3, argA4, argA5
+
+    @d2 = ROL64((argA1^Da), 3)@
+    @d3 = ROL64((argA2^De), 45)@
+    @d4 = ROL64((argA3^Di), 61)@
+    @d0 = ROL64((argA4^Do), 28)@
+    @d1 = ROL64((argA5^Du), 20)@
+    @argA1 =   Ba ^((~Be)&  Bi )@ Ca ^= argA1@
+    @argA2 =   Be ^((~Bi)&  Bo )@
+    @argA3 =   Bi ^((~Bo)&  Bu )@
+    @argA4 =   Bo ^((~Bu)&  Ba )@
+    @argA5 =   Bu ^((~Ba)&  Be )@
+
+    veor.64 \argA2, \argA2, d8
+    veor.64 \argA3, \argA3, d9
+    vshl.u64  d3, \argA2, #45
+    vldr.64 d6, [sp, #\argA1]
+    vshl.u64  d4, \argA3, #61
+    veor.64 \argA4, \argA4, d10
+    vsri.64  d3, \argA2, #64-45
+    veor.64 \argA5, \argA5, d11
+    vsri.64  d4, \argA3, #64-61
+    vshl.u64  d0, \argA4, #28
+    veor.64 d6, d6, d7
+    vshl.u64  d1, \argA5, #20
+    vbic.64   \argA3, d4, d3
+    vsri.64  d0, \argA4, #64-28
+    vbic.64   \argA4, d0, d4
+    vshl.u64  d2, d6, #3
+    vsri.64  d1, \argA5, #64-20
+    veor.64   \argA4, d3
+    vsri.64  d2, d6, #64-3
+    vbic.64   \argA5, d1, d0
+    vbic.64   d6, d2, d1
+    vbic.64   \argA2, d3, d2
+    veor.64   d6, d0
+    veor.64   \argA2, d1
+    vstr.64   d6, [sp, #\argA1]
+    veor.64   \argA3, d2
+    veor.64  d5, d6
+    veor.64   \argA5, d4
+
+    .endm
+
+.macro    KeccakThetaRhoPiChi2 argA1, argA2, argA3, argA4, argA5
+
+    @d4 = ROL64((argA1^Da), 18)@
+    @d0 = ROL64((argA2^De), 1)@
+    @d1 = ROL64((argA3^Di), 6)@
+    @d2 = ROL64((argA4^Do), 25)@
+    @d3 = ROL64((argA5^Du), 8)@
+    @argA1 =   Ba ^((~Be)&  Bi )@ Ca ^= argA1@
+    @argA2 =   Be ^((~Bi)&  Bo )@
+    @argA3 =   Bi ^((~Bo)&  Bu )@
+    @argA4 =   Bo ^((~Bu)&  Ba )@
+    @argA5 =   Bu ^((~Ba)&  Be )@
+
+    veor.64 \argA3, \argA3, d9
+    veor.64 \argA4, \argA4, d10
+    vshl.u64  d1, \argA3, #6
+    vldr.64 d6, [sp, #\argA1]
+    vshl.u64  d2, \argA4, #25
+    veor.64 \argA5, \argA5, d11
+    vsri.64  d1, \argA3, #64-6
+    veor.64 \argA2, \argA2, d8
+    vsri.64  d2, \argA4, #64-25
+    vext.8  d3, \argA5, \argA5, #7
+    veor.64 d6, d6, d7
+    vbic.64  \argA3, d2, d1
+    vadd.u64  d0, \argA2, \argA2
+    vbic.64   \argA4, d3, d2
+    vsri.64  d0, \argA2, #64-1
+    vshl.u64  d4, d6, #18
+    veor.64  \argA2, d1, \argA4
+    veor.64  \argA3, d0
+    vsri.64  d4, d6, #64-18
+    vstr.64   \argA3, [sp, #\argA1]
+    veor.64  d5, \argA3
+    vbic.64   \argA5, d1, d0
+    vbic.64   \argA3, d4, d3
+    vbic.64   \argA4, d0, d4
+    veor.64   \argA3, d2
+    veor.64   \argA4, d3
+    veor.64   \argA5, d4
+
+    .endm
+
+.macro    KeccakThetaRhoPiChi3 argA1, argA2, argA3, argA4, argA5
+
+    @d1 = ROL64((argA1^Da), 36)@
+    @d2 = ROL64((argA2^De), 10)@
+    @d3 = ROL64((argA3^Di), 15)@
+    @d4 = ROL64((argA4^Do), 56)@
+    @d0 = ROL64((argA5^Du), 27)@
+    @argA1 =   Ba ^((~Be)&  Bi )@ Ca ^= argA1@
+    @argA2 =   Be ^((~Bi)&  Bo )@
+    @argA3 =   Bi ^((~Bo)&  Bu )@
+    @argA4 =   Bo ^((~Bu)&  Ba )@
+    @argA5 =   Bu ^((~Ba)&  Be )@
+
+    veor.64 \argA2, \argA2, d8
+    veor.64 \argA3, \argA3, d9
+    vshl.u64  d2, \argA2, #10
+    vldr.64 d6, [sp, #\argA1]
+    vshl.u64  d3, \argA3, #15
+    veor.64 \argA4, \argA4, d10
+    vsri.64  d2, \argA2, #64-10
+    vsri.64  d3, \argA3, #64-15
+    veor.64 \argA5, \argA5, d11
+    vext.8  d4, \argA4, \argA4, #1
+    vbic.64   \argA2, d3, d2
+    vshl.u64  d0, \argA5, #27
+    veor.64 d6, d6, d7
+    vbic.64   \argA3, d4, d3
+    vsri.64  d0, \argA5, #64-27
+    vshl.u64  d1, d6, #36
+    veor.64   \argA3, d2
+    vbic.64   \argA4, d0, d4
+    vsri.64  d1, d6, #64-36
+
+    veor.64   \argA4, d3
+    vbic.64   d6, d2, d1
+    vbic.64   \argA5, d1, d0
+    veor.64   d6, d0
+    veor.64   \argA2, d1
+    vstr.64   d6, [sp, #\argA1]
+    veor.64  d5, d6
+    veor.64   \argA5, d4
+
+    .endm
+
+.macro    KeccakThetaRhoPiChi4 argA1, argA2, argA3, argA4, argA5
+
+    @d3 = ROL64((argA1^Da), 41)@
+    @d4 = ROL64((argA2^De), 2)@
+    @d0 = ROL64((argA3^Di), 62)@
+    @d1 = ROL64((argA4^Do), 55)@
+    @d2 = ROL64((argA5^Du), 39)@
+    @argA1 =   Ba ^((~Be)&  Bi )@ Ca ^= argA1@
+    @argA2 =   Be ^((~Bi)&  Bo )@
+    @argA3 =   Bi ^((~Bo)&  Bu )@
+    @argA4 =   Bo ^((~Bu)&  Ba )@
+    @argA5 =   Bu ^((~Ba)&  Be )@
+
+    veor.64 \argA2, \argA2, d8
+    veor.64 \argA3, \argA3, d9
+    vshl.u64  d4, \argA2, #2
+    veor.64 \argA5, \argA5, d11
+    vshl.u64  d0, \argA3, #62
+    vldr.64 d6, [sp, #\argA1]
+    vsri.64  d4, \argA2, #64-2
+    veor.64 \argA4, \argA4, d10
+    vsri.64  d0, \argA3, #64-62
+
+    vshl.u64  d1, \argA4, #55
+    veor.64 d6, d6, d7
+    vshl.u64  d2, \argA5, #39
+    vsri.64  d1, \argA4, #64-55
+    vbic.64  \argA4, d0, d4
+    vsri.64  d2, \argA5, #64-39
+    vbic.64  \argA2, d1, d0
+    vshl.u64  d3, d6, #41
+    veor.64  \argA5, d4, \argA2
+    vbic.64  \argA2, d2, d1
+    vsri.64  d3, d6, #64-41
+    veor.64  d6, d0, \argA2
+
+    vbic.64 \argA2, d3, d2
+    vbic.64 \argA3, d4, d3
+    veor.64 \argA2, d1
+    vstr.64 d6, [sp, #\argA1]
+    veor.64 d5, d6
+    veor.64 \argA3, d2
+    veor.64 \argA4, d3
+
+    .endm
+
+
+@// --- code
+
+@not callable from C!
+.p2align 3
+.type  KeccakF_armv7a_neon_asm,%function;
+KeccakF_armv7a_neon_asm:  @
+
+.LroundLoop:
+
+    KeccakThetaRhoPiChiIota  Aba, d13, d19, d25, d31
+    KeccakThetaRhoPiChi1    Aka, d15, d21, d22, d28
+    KeccakThetaRhoPiChi2    Asa, d12, d18, d24, d30
+    KeccakThetaRhoPiChi3    Aga, d14, d20, d26, d27
+    KeccakThetaRhoPiChi4    Ama, d16, d17, d23, d29
+
+    KeccakThetaRhoPiChiIota  Aba, d15, d18, d26, d29
+    KeccakThetaRhoPiChi1    Asa, d14, d17, d25, d28
+    KeccakThetaRhoPiChi2    Ama, d13, d21, d24, d27
+    KeccakThetaRhoPiChi3    Aka, d12, d20, d23, d31
+    KeccakThetaRhoPiChi4    Aga, d16, d19, d22, d30
+
+    KeccakThetaRhoPiChiIota Aba, d14, d21, d23, d30
+    KeccakThetaRhoPiChi1    Ama, d12, d19, d26, d28
+    KeccakThetaRhoPiChi2    Aga, d15, d17, d24, d31
+    KeccakThetaRhoPiChi3    Asa, d13, d20, d22, d29
+    KeccakThetaRhoPiChi4    Aka, d16, d18, d25, d27
+
+    KeccakThetaRhoPiChiIota Aba, d12, d17, d22, d27
+    KeccakThetaRhoPiChi1    Aga, d13, d18, d23, d28
+    KeccakThetaRhoPiChi2    Aka, d14, d19, d24, d29
+    ldr    r0, [ip]
+    KeccakThetaRhoPiChi3    Ama, d15, d20, d25, d30
+    cmp    r0, #0xFFFFFFFF
+    KeccakThetaRhoPiChi4    Asa, d16, d21, d26, d31
+
+    bne    .LroundLoop
+    sub    ip, #(8*24)
+    bx    lr
+.p2align 2
+.ltorg
+.size KeccakF_armv7a_neon_asm,.-KeccakF_armv7a_neon_asm;
+
+
+@//unsigned _gcry_keccak_permute_armv7_neon(u64 *state)  callable from C
+.p2align 3
+.global   _gcry_keccak_permute_armv7_neon
+.type  _gcry_keccak_permute_armv7_neon,%function;
+_gcry_keccak_permute_armv7_neon:
+
+    push   {ip, lr}
+    vpush  {q4-q7}
+    sub    sp,sp, #5*8
+
+    vldr.64  d0,  [r0, #0*8]
+    vldr.64  d12, [r0, #1*8]
+    vldr.64  d17, [r0, #2*8]
+    vldr.64  d22, [r0, #3*8]
+    vldr.64  d27, [r0, #4*8]
+
+    GET_DATA_POINTER(ip, _gcry_keccak_round_consts_64bit, lr);
+
+    vldr.64  d1,  [r0, #5*8]
+    vldr.64  d13, [r0, #6*8]
+    vldr.64  d18, [r0, #7*8]
+    vldr.64  d23, [r0, #8*8]
+    vldr.64  d28, [r0, #9*8]
+
+    vldr.64  d2,  [r0, #10*8]
+    vldr.64  d14, [r0, #11*8]
+    vldr.64  d19, [r0, #12*8]
+    vldr.64  d24, [r0, #13*8]
+    vldr.64  d29, [r0, #14*8]
+
+    vldr.64  d3,  [r0, #15*8]
+    vldr.64  d15, [r0, #16*8]
+    vldr.64  d20, [r0, #17*8]
+    vldr.64  d25, [r0, #18*8]
+    vldr.64  d30, [r0, #19*8]
+
+    vldr.64  d4,  [r0, #20*8]
+    vldr.64  d16, [r0, #21*8]
+    vldr.64  d21, [r0, #22*8]
+    vldr.64  d26, [r0, #23*8]
+    vldr.64  d31, [r0, #24*8]
+
+    vstr.64  d0, [sp, #Aba]
+    vstr.64  d1, [sp, #Aga]
+    veor.64 q0, q0, q1
+    vstr.64  d2, [sp, #Aka]
+    veor.64 d5, d0,  d1
+    vstr.64  d3, [sp, #Ama]
+    mov      r1, r0
+    vstr.64  d4, [sp, #Asa]
+    veor.64 d5, d5,  d4
+
+    bl KeccakF_armv7a_neon_asm
+
+    vpop.64  { d0- d4 }
+
+    vstr.64  d0,  [r1, #0*8]
+    vstr.64  d12, [r1, #1*8]
+    vstr.64  d17, [r1, #2*8]
+    vstr.64  d22, [r1, #3*8]
+    vstr.64  d27, [r1, #4*8]
+
+    vstr.64  d1,  [r1, #5*8]
+    vstr.64  d13, [r1, #6*8]
+    vstr.64  d18, [r1, #7*8]
+    vstr.64  d23, [r1, #8*8]
+    vstr.64  d28, [r1, #9*8]
+
+    vstr.64  d2,  [r1, #10*8]
+    vstr.64  d14, [r1, #11*8]
+    vstr.64  d19, [r1, #12*8]
+    vstr.64  d24, [r1, #13*8]
+    vstr.64  d29, [r1, #14*8]
+
+    vstr.64  d3,  [r1, #15*8]
+    vstr.64  d15, [r1, #16*8]
+    vstr.64  d20, [r1, #17*8]
+    vstr.64  d25, [r1, #18*8]
+    vstr.64  d30, [r1, #19*8]
+
+    vstr.64  d4,  [r1, #20*8]
+    vstr.64  d16, [r1, #21*8]
+    vstr.64  d21, [r1, #22*8]
+    vstr.64  d26, [r1, #23*8]
+    vstr.64  d31, [r1, #24*8]
+
+    mov   r0, #112
+    vpop  {q4-q7}
+    pop   {ip, pc}
+.p2align 2
+.ltorg
+.size _gcry_keccak_permute_armv7_neon,.-_gcry_keccak_permute_armv7_neon;
+
+@//unsigned _gcry_keccak_permute_armv7_neon(u64 *state, @r4
+@                                          int pos,    @r1
+@                                          const byte *lanes,   @r2
+@                                          unsigned int nlanes, @r3
+@                                          int blocklanes) @ r5 callable from C
+.p2align 3
+.global   _gcry_keccak_absorb_lanes64_armv7_neon
+.type  _gcry_keccak_absorb_lanes64_armv7_neon,%function;
+_gcry_keccak_absorb_lanes64_armv7_neon:
+
+    cmp    r3, #0      @ nlanes == 0
+    itt eq
+    moveq  r0, #0
+    bxeq   lr
+
+    push   {r4-r5, ip, lr}
+    beq    .Lout
+    mov    r4, r0
+    ldr    r5, [sp, #(4*4)]
+    vpush  {q4-q7}
+
+    @ load state
+    vldr.64  d0,  [r4, #0*8]
+    vldr.64  d12, [r4, #1*8]
+    vldr.64  d17, [r4, #2*8]
+    vldr.64  d22, [r4, #3*8]
+    vldr.64  d27, [r4, #4*8]
+
+    GET_DATA_POINTER(ip, _gcry_keccak_round_consts_64bit, lr);
+
+    vldr.64  d1,  [r4, #5*8]
+    vldr.64  d13, [r4, #6*8]
+    vldr.64  d18, [r4, #7*8]
+    vldr.64  d23, [r4, #8*8]
+    vldr.64  d28, [r4, #9*8]
+
+    vldr.64  d2,  [r4, #10*8]
+    vldr.64  d14, [r4, #11*8]
+    vldr.64  d19, [r4, #12*8]
+    vldr.64  d24, [r4, #13*8]
+    vldr.64  d29, [r4, #14*8]
+
+    vldr.64  d3,  [r4, #15*8]
+    vldr.64  d15, [r4, #16*8]
+    vldr.64  d20, [r4, #17*8]
+    vldr.64  d25, [r4, #18*8]
+    vldr.64  d30, [r4, #19*8]
+
+    vldr.64  d4,  [r4, #20*8]
+    vldr.64  d16, [r4, #21*8]
+    vldr.64  d21, [r4, #22*8]
+    vldr.64  d26, [r4, #23*8]
+    vldr.64  d31, [r4, #24*8]
+
+.Lmain_loop:
+
+    @ detect absorb mode (full blocks vs lanes)
+
+    cmp r1, #0         @ pos != 0
+    bne .Llanes_loop
+
+.Lmain_loop_pos0:
+
+    @ full blocks mode
+
+    @ switch (blocksize)
+    cmp r5, #21
+    beq .Lfull_block_21
+    cmp r5, #18
+    beq .Lfull_block_18
+    cmp r5, #17
+    beq .Lfull_block_17
+    cmp r5, #13
+    beq .Lfull_block_13
+    cmp r5, #9
+    beq .Lfull_block_9
+
+    @ unknown blocksize
+    b .Llanes_loop
+
+.Lfull_block_21:
+
+    @ SHAKE128
+
+    cmp r3, #21                @ nlanes < blocklanes
+    blo .Llanes_loop
+
+    sub    sp,sp, #5*8
+
+    vld1.64 {d5-d8}, [r2]!
+    veor d0,  d5
+    vld1.64 {d9-d11}, [r2]!
+    veor d12, d6
+    veor d17, d7
+    veor d22, d8
+    vld1.64 {d5-d8}, [r2]!
+    veor d27, d9
+
+    veor d1,  d10
+    veor d13, d11
+    vld1.64 {d9-d11}, [r2]!
+    veor d18, d5
+    veor d23, d6
+    veor d28, d7
+
+    veor d2,  d8
+    vld1.64 {d5-d8}, [r2]!
+    veor d14, d9
+    veor d19, d10
+    veor d24, d11
+    vld1.64 {d9-d11}, [r2]!
+    veor d29, d5
+
+    veor d3,  d6
+    veor d15, d7
+    veor d20, d8
+    veor d25, d9
+    veor d30, d10
+
+    veor d4,  d11
+
+    vstr.64  d0, [sp, #Aba]
+    vstr.64  d1, [sp, #Aga]
+    veor.64 q0, q0, q1
+    vstr.64  d2, [sp, #Aka]
+    veor.64 d5, d0,  d1
+    vstr.64  d3, [sp, #Ama]
+    vstr.64  d4, [sp, #Asa]
+    veor.64 d5, d5,  d4
+
+    bl KeccakF_armv7a_neon_asm
+
+    subs r3, #21       @ nlanes -= 21
+    vpop.64  { d0-d4 }
+
+    beq .Ldone
+
+    b .Lfull_block_21
+
+.Lfull_block_18:
+
+    @ SHA3-224
+
+    cmp r3, #18                @ nlanes < blocklanes
+    blo .Llanes_loop
+
+    sub    sp,sp, #5*8
+
+    vld1.64 {d5-d8}, [r2]!
+    veor d0,  d5
+    vld1.64 {d9-d11}, [r2]!
+    veor d12, d6
+    veor d17, d7
+    veor d22, d8
+    vld1.64 {d5-d8}, [r2]!
+    veor d27, d9
+
+    veor d1,  d10
+    veor d13, d11
+    vld1.64 {d9-d11}, [r2]!
+    veor d18, d5
+    veor d23, d6
+    veor d28, d7
+
+    veor d2,  d8
+    vld1.64 {d5-d8}, [r2]!
+    veor d14, d9
+    veor d19, d10
+    veor d24, d11
+    veor d29, d5
+
+    veor d3,  d6
+    veor d15, d7
+    veor d20, d8
+
+    vstr.64  d0, [sp, #Aba]
+    vstr.64  d1, [sp, #Aga]
+    veor.64 q0, q0, q1
+    vstr.64  d2, [sp, #Aka]
+    veor.64 d5, d0,  d1
+    vstr.64  d3, [sp, #Ama]
+    vstr.64  d4, [sp, #Asa]
+    veor.64 d5, d5,  d4
+
+    bl KeccakF_armv7a_neon_asm
+
+    subs r3, #18       @ nlanes -= 18
+    vpop.64  { d0-d4 }
+
+    beq .Ldone
+
+    b .Lfull_block_18
+
+.Lfull_block_17:
+
+    @ SHA3-256 & SHAKE256
+
+    cmp r3, #17                @ nlanes < blocklanes
+    blo .Llanes_loop
+
+    sub    sp,sp, #5*8
+
+    vld1.64 {d5-d8}, [r2]!
+    veor d0,  d5
+    vld1.64 {d9-d11}, [r2]!
+    veor d12, d6
+    veor d17, d7
+    veor d22, d8
+    vld1.64 {d5-d8}, [r2]!
+    veor d27, d9
+
+    veor d1,  d10
+    veor d13, d11
+    vld1.64 {d9-d11}, [r2]!
+    veor d18, d5
+    veor d23, d6
+    veor d28, d7
+
+    veor d2,  d8
+    vld1.64 {d5-d7}, [r2]!
+    veor d14, d9
+    veor d19, d10
+    veor d24, d11
+    veor d29, d5
+
+    veor d3,  d6
+    veor d15, d7
+
+    vstr.64  d0, [sp, #Aba]
+    vstr.64  d1, [sp, #Aga]
+    veor.64 q0, q0, q1
+    vstr.64  d2, [sp, #Aka]
+    veor.64 d5, d0,  d1
+    vstr.64  d3, [sp, #Ama]
+    vstr.64  d4, [sp, #Asa]
+    veor.64 d5, d5,  d4
+
+    bl KeccakF_armv7a_neon_asm
+
+    subs r3, #17       @ nlanes -= 17
+    vpop.64  { d0-d4 }
+
+    beq .Ldone
+
+    b .Lfull_block_17
+
+.Lfull_block_13:
+
+    @ SHA3-384
+
+    cmp r3, #13                @ nlanes < blocklanes
+    blo .Llanes_loop
+
+    sub    sp,sp, #5*8
+
+    vld1.64 {d5-d8}, [r2]!
+    veor d0,  d5
+    vld1.64 {d9-d11}, [r2]!
+    veor d12, d6
+    veor d17, d7
+    veor d22, d8
+    vld1.64 {d5-d8}, [r2]!
+    veor d27, d9
+
+    veor d1,  d10
+    veor d13, d11
+    vld1.64 {d9-d10}, [r2]!
+    veor d18, d5
+    veor d23, d6
+    veor d28, d7
+
+    veor d2,  d8
+    veor d14, d9
+    veor d19, d10
+
+    vstr.64  d0, [sp, #Aba]
+    vstr.64  d1, [sp, #Aga]
+    veor.64 q0, q0, q1
+    vstr.64  d2, [sp, #Aka]
+    veor.64 d5, d0,  d1
+    vstr.64  d3, [sp, #Ama]
+    vstr.64  d4, [sp, #Asa]
+    veor.64 d5, d5,  d4
+
+    bl KeccakF_armv7a_neon_asm
+
+    subs r3, #13       @ nlanes -= 13
+    vpop.64  { d0-d4 }
+
+    beq .Ldone
+
+    b .Lfull_block_13
+
+.Lfull_block_9:
+
+    @ SHA3-512
+
+    cmp r3, #9         @ nlanes < blocklanes
+    blo .Llanes_loop
+
+    sub    sp,sp, #5*8
+
+    vld1.64 {d5-d8}, [r2]!
+    veor d0,  d5
+    vld1.64 {d9-d11}, [r2]!
+    veor d12, d6
+    veor d17, d7
+    veor d22, d8
+    vld1.64 {d5-d6}, [r2]!
+    veor d27, d9
+
+    veor d1,  d10
+    veor d13, d11
+    veor d18, d5
+    veor d23, d6
+
+    vstr.64  d0, [sp, #Aba]
+    vstr.64  d1, [sp, #Aga]
+    veor.64 q0, q0, q1
+    vstr.64  d2, [sp, #Aka]
+    veor.64 d5, d0,  d1
+    vstr.64  d3, [sp, #Ama]
+    vstr.64  d4, [sp, #Asa]
+    veor.64 d5, d5,  d4
+
+    bl KeccakF_armv7a_neon_asm
+
+    subs r3, #9                @ nlanes -= 9
+    vpop.64  { d0-d4 }
+
+    beq .Ldone
+
+    b .Lfull_block_9
+
+.Llanes_loop:
+
+    @ per-lane mode
+
+    @ switch (pos)
+    ldrb r0, [pc, r1]
+    add pc, pc, r0, lsl #2
+.Lswitch_table:
+    .byte (.Llane0-.Lswitch_table-4)/4
+    .byte (.Llane1-.Lswitch_table-4)/4
+    .byte (.Llane2-.Lswitch_table-4)/4
+    .byte (.Llane3-.Lswitch_table-4)/4
+    .byte (.Llane4-.Lswitch_table-4)/4
+    .byte (.Llane5-.Lswitch_table-4)/4
+    .byte (.Llane6-.Lswitch_table-4)/4
+    .byte (.Llane7-.Lswitch_table-4)/4
+    .byte (.Llane8-.Lswitch_table-4)/4
+    .byte (.Llane9-.Lswitch_table-4)/4
+    .byte (.Llane10-.Lswitch_table-4)/4
+    .byte (.Llane11-.Lswitch_table-4)/4
+    .byte (.Llane12-.Lswitch_table-4)/4
+    .byte (.Llane13-.Lswitch_table-4)/4
+    .byte (.Llane14-.Lswitch_table-4)/4
+    .byte (.Llane15-.Lswitch_table-4)/4
+    .byte (.Llane16-.Lswitch_table-4)/4
+    .byte (.Llane17-.Lswitch_table-4)/4
+    .byte (.Llane18-.Lswitch_table-4)/4
+    .byte (.Llane19-.Lswitch_table-4)/4
+    .byte (.Llane20-.Lswitch_table-4)/4
+    .byte (.Llane21-.Lswitch_table-4)/4
+    .byte (.Llane22-.Lswitch_table-4)/4
+    .byte (.Llane23-.Lswitch_table-4)/4
+    .byte (.Llane24-.Lswitch_table-4)/4
+.p2align 2
+
+#define ABSORB_LANE(label, vreg) \
+    label: \
+      add     r1, #1; \
+      vld1.64 d5, [r2]!; \
+      cmp     r1, r5; /* pos == blocklanes */ \
+      veor    vreg, vreg, d5; \
+      beq     .Llanes_permute; \
+      subs    r3, #1; \
+      beq     .Ldone;
+
+    ABSORB_LANE(.Llane0, d0)
+    ABSORB_LANE(.Llane1, d12)
+    ABSORB_LANE(.Llane2, d17)
+    ABSORB_LANE(.Llane3, d22)
+    ABSORB_LANE(.Llane4, d27)
+
+    ABSORB_LANE(.Llane5, d1)
+    ABSORB_LANE(.Llane6, d13)
+    ABSORB_LANE(.Llane7, d18)
+    ABSORB_LANE(.Llane8, d23)
+    ABSORB_LANE(.Llane9, d28)
+
+    ABSORB_LANE(.Llane10, d2)
+    ABSORB_LANE(.Llane11, d14)
+    ABSORB_LANE(.Llane12, d19)
+    ABSORB_LANE(.Llane13, d24)
+    ABSORB_LANE(.Llane14, d29)
+
+    ABSORB_LANE(.Llane15, d3)
+    ABSORB_LANE(.Llane16, d15)
+    ABSORB_LANE(.Llane17, d20)
+    ABSORB_LANE(.Llane18, d25)
+    ABSORB_LANE(.Llane19, d30)
+
+    ABSORB_LANE(.Llane20, d4)
+    ABSORB_LANE(.Llane21, d16)
+    ABSORB_LANE(.Llane22, d21)
+    ABSORB_LANE(.Llane23, d26)
+    ABSORB_LANE(.Llane24, d31)
+
+    b .Llanes_loop
+
+.Llanes_permute:
+
+    sub    sp,sp, #5*8
+    vstr.64  d0, [sp, #Aba]
+    vstr.64  d1, [sp, #Aga]
+    veor.64 q0, q0, q1
+    vstr.64  d2, [sp, #Aka]
+    veor.64 d5, d0,  d1
+    vstr.64  d3, [sp, #Ama]
+    vstr.64  d4, [sp, #Asa]
+    veor.64 d5, d5,  d4
+
+    bl KeccakF_armv7a_neon_asm
+
+    mov  r1, #0   @ pos <= 0
+    subs r3, #1
+
+    vpop.64  { d0-d4 }
+
+    beq  .Ldone
+
+    b .Lmain_loop_pos0
+
+.Ldone:
+
+    @ save state
+    vstr.64  d0,  [r4, #0*8]
+    vstr.64  d12, [r4, #1*8]
+    vstr.64  d17, [r4, #2*8]
+    vstr.64  d22, [r4, #3*8]
+    vstr.64  d27, [r4, #4*8]
+
+    vstr.64  d1,  [r4, #5*8]
+    vstr.64  d13, [r4, #6*8]
+    vstr.64  d18, [r4, #7*8]
+    vstr.64  d23, [r4, #8*8]
+    vstr.64  d28, [r4, #9*8]
+
+    vstr.64  d2,  [r4, #10*8]
+    vstr.64  d14, [r4, #11*8]
+    vstr.64  d19, [r4, #12*8]
+    vstr.64  d24, [r4, #13*8]
+    vstr.64  d29, [r4, #14*8]
+
+    vstr.64  d3,  [r4, #15*8]
+    vstr.64  d15, [r4, #16*8]
+    vstr.64  d20, [r4, #17*8]
+    vstr.64  d25, [r4, #18*8]
+    vstr.64  d30, [r4, #19*8]
+
+    vstr.64  d4,  [r4, #20*8]
+    vstr.64  d16, [r4, #21*8]
+    vstr.64  d21, [r4, #22*8]
+    vstr.64  d26, [r4, #23*8]
+    vstr.64  d31, [r4, #24*8]
+
+    mov   r0, #120
+    vpop  {q4-q7}
+.Lout:
+    pop   {r4-r5, ip, pc}
+.p2align 2
+.ltorg
+.size _gcry_keccak_absorb_lanes64_armv7_neon,.-_gcry_keccak_absorb_lanes64_armv7_neon;
+
+#endif
diff --git a/cipher/keccak.c b/cipher/keccak.c
new file mode 100644 (file)
index 0000000..0bb3155
--- /dev/null
@@ -0,0 +1,1266 @@
+/* keccak.c - SHA3 hash functions
+ * Copyright (C) 2015  g10 Code GmbH
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <config.h>
+#include <string.h>
+#include "g10lib.h"
+#include "bithelp.h"
+#include "bufhelp.h"
+#include "cipher.h"
+#include "hash-common.h"
+
+
+
+/* USE_64BIT indicates whether to use 64-bit generic implementation.
+ * USE_32BIT indicates whether to use 32-bit generic implementation. */
+#undef USE_64BIT
+#if defined(__x86_64__) || SIZEOF_UNSIGNED_LONG == 8
+# define USE_64BIT 1
+#else
+# define USE_32BIT 1
+#endif
+
+
+/* USE_64BIT_BMI2 indicates whether to compile with 64-bit Intel BMI2 code. */
+#undef USE_64BIT_BMI2
+#if defined(USE_64BIT) && defined(HAVE_GCC_INLINE_ASM_BMI2)
+# define USE_64BIT_BMI2 1
+#endif
+
+
+/* USE_64BIT_SHLD indicates whether to compile with 64-bit Intel SHLD code. */
+#undef USE_64BIT_SHLD
+#if defined(USE_64BIT) && defined (__GNUC__) && defined(__x86_64__)
+# define USE_64BIT_SHLD 1
+#endif
+
+
+/* USE_32BIT_BMI2 indicates whether to compile with 32-bit Intel BMI2 code. */
+#undef USE_32BIT_BMI2
+#if defined(USE_32BIT) && defined(HAVE_GCC_INLINE_ASM_BMI2)
+# define USE_32BIT_BMI2 1
+#endif
+
+
+/* USE_64BIT_ARM_NEON indicates whether to enable 64-bit ARM/NEON assembly
+ * code. */
+#undef USE_64BIT_ARM_NEON
+#ifdef ENABLE_NEON_SUPPORT
+# if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) \
+     && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) \
+     && defined(HAVE_GCC_INLINE_ASM_NEON)
+#  define USE_64BIT_ARM_NEON 1
+# endif
+#endif /*ENABLE_NEON_SUPPORT*/
+
+
+#if defined(USE_64BIT) || defined(USE_64BIT_ARM_NEON)
+# define NEED_COMMON64 1
+#endif
+
+#ifdef USE_32BIT
+# define NEED_COMMON32BI 1
+#endif
+
+
+#define SHA3_DELIMITED_SUFFIX 0x06
+#define SHAKE_DELIMITED_SUFFIX 0x1F
+
+
+typedef struct
+{
+  union {
+#ifdef NEED_COMMON64
+    u64 state64[25];
+#endif
+#ifdef NEED_COMMON32BI
+    u32 state32bi[50];
+#endif
+  } u;
+} KECCAK_STATE;
+
+
+typedef struct
+{
+  unsigned int (*permute)(KECCAK_STATE *hd);
+  unsigned int (*absorb)(KECCAK_STATE *hd, int pos, const byte *lanes,
+                        unsigned int nlanes, int blocklanes);
+  unsigned int (*extract) (KECCAK_STATE *hd, unsigned int pos, byte *outbuf,
+                          unsigned int outlen);
+} keccak_ops_t;
+
+
+typedef struct KECCAK_CONTEXT_S
+{
+  KECCAK_STATE state;
+  unsigned int outlen;
+  unsigned int blocksize;
+  unsigned int count;
+  unsigned int suffix;
+  const keccak_ops_t *ops;
+} KECCAK_CONTEXT;
+
+
+
+#ifdef NEED_COMMON64
+
+const u64 _gcry_keccak_round_consts_64bit[24 + 1] =
+{
+  U64_C(0x0000000000000001), U64_C(0x0000000000008082),
+  U64_C(0x800000000000808A), U64_C(0x8000000080008000),
+  U64_C(0x000000000000808B), U64_C(0x0000000080000001),
+  U64_C(0x8000000080008081), U64_C(0x8000000000008009),
+  U64_C(0x000000000000008A), U64_C(0x0000000000000088),
+  U64_C(0x0000000080008009), U64_C(0x000000008000000A),
+  U64_C(0x000000008000808B), U64_C(0x800000000000008B),
+  U64_C(0x8000000000008089), U64_C(0x8000000000008003),
+  U64_C(0x8000000000008002), U64_C(0x8000000000000080),
+  U64_C(0x000000000000800A), U64_C(0x800000008000000A),
+  U64_C(0x8000000080008081), U64_C(0x8000000000008080),
+  U64_C(0x0000000080000001), U64_C(0x8000000080008008),
+  U64_C(0xFFFFFFFFFFFFFFFF)
+};
+
+static unsigned int
+keccak_extract64(KECCAK_STATE *hd, unsigned int pos, byte *outbuf,
+                unsigned int outlen)
+{
+  unsigned int i;
+
+  /* NOTE: when pos == 0, hd and outbuf may point to same memory (SHA-3). */
+
+  for (i = pos; i < pos + outlen / 8 + !!(outlen % 8); i++)
+    {
+      u64 tmp = hd->u.state64[i];
+      buf_put_le64(outbuf, tmp);
+      outbuf += 8;
+    }
+
+  return 0;
+}
+
+#endif /* NEED_COMMON64 */
+
+
+#ifdef NEED_COMMON32BI
+
+static const u32 round_consts_32bit[2 * 24] =
+{
+  0x00000001UL, 0x00000000UL, 0x00000000UL, 0x00000089UL,
+  0x00000000UL, 0x8000008bUL, 0x00000000UL, 0x80008080UL,
+  0x00000001UL, 0x0000008bUL, 0x00000001UL, 0x00008000UL,
+  0x00000001UL, 0x80008088UL, 0x00000001UL, 0x80000082UL,
+  0x00000000UL, 0x0000000bUL, 0x00000000UL, 0x0000000aUL,
+  0x00000001UL, 0x00008082UL, 0x00000000UL, 0x00008003UL,
+  0x00000001UL, 0x0000808bUL, 0x00000001UL, 0x8000000bUL,
+  0x00000001UL, 0x8000008aUL, 0x00000001UL, 0x80000081UL,
+  0x00000000UL, 0x80000081UL, 0x00000000UL, 0x80000008UL,
+  0x00000000UL, 0x00000083UL, 0x00000000UL, 0x80008003UL,
+  0x00000001UL, 0x80008088UL, 0x00000000UL, 0x80000088UL,
+  0x00000001UL, 0x00008000UL, 0x00000000UL, 0x80008082UL
+};
+
+static unsigned int
+keccak_extract32bi(KECCAK_STATE *hd, unsigned int pos, byte *outbuf,
+                  unsigned int outlen)
+{
+  unsigned int i;
+  u32 x0;
+  u32 x1;
+  u32 t;
+
+  /* NOTE: when pos == 0, hd and outbuf may point to same memory (SHA-3). */
+
+  for (i = pos; i < pos + outlen / 8 + !!(outlen % 8); i++)
+    {
+      x0 = hd->u.state32bi[i * 2 + 0];
+      x1 = hd->u.state32bi[i * 2 + 1];
+
+      t = (x0 & 0x0000FFFFUL) + (x1 << 16);
+      x1 = (x0 >> 16) + (x1 & 0xFFFF0000UL);
+      x0 = t;
+      t = (x0 ^ (x0 >> 8)) & 0x0000FF00UL; x0 = x0 ^ t ^ (t << 8);
+      t = (x0 ^ (x0 >> 4)) & 0x00F000F0UL; x0 = x0 ^ t ^ (t << 4);
+      t = (x0 ^ (x0 >> 2)) & 0x0C0C0C0CUL; x0 = x0 ^ t ^ (t << 2);
+      t = (x0 ^ (x0 >> 1)) & 0x22222222UL; x0 = x0 ^ t ^ (t << 1);
+      t = (x1 ^ (x1 >> 8)) & 0x0000FF00UL; x1 = x1 ^ t ^ (t << 8);
+      t = (x1 ^ (x1 >> 4)) & 0x00F000F0UL; x1 = x1 ^ t ^ (t << 4);
+      t = (x1 ^ (x1 >> 2)) & 0x0C0C0C0CUL; x1 = x1 ^ t ^ (t << 2);
+      t = (x1 ^ (x1 >> 1)) & 0x22222222UL; x1 = x1 ^ t ^ (t << 1);
+
+      buf_put_le32(&outbuf[0], x0);
+      buf_put_le32(&outbuf[4], x1);
+      outbuf += 8;
+    }
+
+  return 0;
+}
+
+static inline void
+keccak_absorb_lane32bi(u32 *lane, u32 x0, u32 x1)
+{
+  u32 t;
+
+  t = (x0 ^ (x0 >> 1)) & 0x22222222UL; x0 = x0 ^ t ^ (t << 1);
+  t = (x0 ^ (x0 >> 2)) & 0x0C0C0C0CUL; x0 = x0 ^ t ^ (t << 2);
+  t = (x0 ^ (x0 >> 4)) & 0x00F000F0UL; x0 = x0 ^ t ^ (t << 4);
+  t = (x0 ^ (x0 >> 8)) & 0x0000FF00UL; x0 = x0 ^ t ^ (t << 8);
+  t = (x1 ^ (x1 >> 1)) & 0x22222222UL; x1 = x1 ^ t ^ (t << 1);
+  t = (x1 ^ (x1 >> 2)) & 0x0C0C0C0CUL; x1 = x1 ^ t ^ (t << 2);
+  t = (x1 ^ (x1 >> 4)) & 0x00F000F0UL; x1 = x1 ^ t ^ (t << 4);
+  t = (x1 ^ (x1 >> 8)) & 0x0000FF00UL; x1 = x1 ^ t ^ (t << 8);
+  lane[0] ^= (x0 & 0x0000FFFFUL) + (x1 << 16);
+  lane[1] ^= (x0 >> 16) + (x1 & 0xFFFF0000UL);
+}
+
+#endif /* NEED_COMMON32BI */
+
+
+/* Construct generic 64-bit implementation. */
+#ifdef USE_64BIT
+
+#if __GNUC__ >= 4 && defined(__x86_64__)
+
+static inline void absorb_lanes64_8(u64 *dst, const byte *in)
+{
+  asm ("movdqu 0*16(%[dst]), %%xmm0\n\t"
+       "movdqu 0*16(%[in]), %%xmm4\n\t"
+       "movdqu 1*16(%[dst]), %%xmm1\n\t"
+       "movdqu 1*16(%[in]), %%xmm5\n\t"
+       "movdqu 2*16(%[dst]), %%xmm2\n\t"
+       "movdqu 3*16(%[dst]), %%xmm3\n\t"
+       "pxor %%xmm4, %%xmm0\n\t"
+       "pxor %%xmm5, %%xmm1\n\t"
+       "movdqu 2*16(%[in]), %%xmm4\n\t"
+       "movdqu 3*16(%[in]), %%xmm5\n\t"
+       "movdqu %%xmm0, 0*16(%[dst])\n\t"
+       "pxor %%xmm4, %%xmm2\n\t"
+       "movdqu %%xmm1, 1*16(%[dst])\n\t"
+       "pxor %%xmm5, %%xmm3\n\t"
+       "movdqu %%xmm2, 2*16(%[dst])\n\t"
+       "movdqu %%xmm3, 3*16(%[dst])\n\t"
+       :
+       : [dst] "r" (dst), [in] "r" (in)
+       : "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "memory");
+}
+
+static inline void absorb_lanes64_4(u64 *dst, const byte *in)
+{
+  asm ("movdqu 0*16(%[dst]), %%xmm0\n\t"
+       "movdqu 0*16(%[in]), %%xmm4\n\t"
+       "movdqu 1*16(%[dst]), %%xmm1\n\t"
+       "movdqu 1*16(%[in]), %%xmm5\n\t"
+       "pxor %%xmm4, %%xmm0\n\t"
+       "pxor %%xmm5, %%xmm1\n\t"
+       "movdqu %%xmm0, 0*16(%[dst])\n\t"
+       "movdqu %%xmm1, 1*16(%[dst])\n\t"
+       :
+       : [dst] "r" (dst), [in] "r" (in)
+       : "xmm0", "xmm1", "xmm4", "xmm5", "memory");
+}
+
+static inline void absorb_lanes64_2(u64 *dst, const byte *in)
+{
+  asm ("movdqu 0*16(%[dst]), %%xmm0\n\t"
+       "movdqu 0*16(%[in]), %%xmm4\n\t"
+       "pxor %%xmm4, %%xmm0\n\t"
+       "movdqu %%xmm0, 0*16(%[dst])\n\t"
+       :
+       : [dst] "r" (dst), [in] "r" (in)
+       : "xmm0", "xmm4", "memory");
+}
+
+#else /* __x86_64__ */
+
+static inline void absorb_lanes64_8(u64 *dst, const byte *in)
+{
+  dst[0] ^= buf_get_le64(in + 8 * 0);
+  dst[1] ^= buf_get_le64(in + 8 * 1);
+  dst[2] ^= buf_get_le64(in + 8 * 2);
+  dst[3] ^= buf_get_le64(in + 8 * 3);
+  dst[4] ^= buf_get_le64(in + 8 * 4);
+  dst[5] ^= buf_get_le64(in + 8 * 5);
+  dst[6] ^= buf_get_le64(in + 8 * 6);
+  dst[7] ^= buf_get_le64(in + 8 * 7);
+}
+
+static inline void absorb_lanes64_4(u64 *dst, const byte *in)
+{
+  dst[0] ^= buf_get_le64(in + 8 * 0);
+  dst[1] ^= buf_get_le64(in + 8 * 1);
+  dst[2] ^= buf_get_le64(in + 8 * 2);
+  dst[3] ^= buf_get_le64(in + 8 * 3);
+}
+
+static inline void absorb_lanes64_2(u64 *dst, const byte *in)
+{
+  dst[0] ^= buf_get_le64(in + 8 * 0);
+  dst[1] ^= buf_get_le64(in + 8 * 1);
+}
+
+#endif /* !__x86_64__ */
+
+static inline void absorb_lanes64_1(u64 *dst, const byte *in)
+{
+  dst[0] ^= buf_get_le64(in + 8 * 0);
+}
+
+
+# define ANDN64(x, y) (~(x) & (y))
+# define ROL64(x, n) (((x) << ((unsigned int)n & 63)) | \
+                     ((x) >> ((64 - (unsigned int)(n)) & 63)))
+
+# define KECCAK_F1600_PERMUTE_FUNC_NAME keccak_f1600_state_permute64
+# define KECCAK_F1600_ABSORB_FUNC_NAME keccak_absorb_lanes64
+# include "keccak_permute_64.h"
+
+# undef ANDN64
+# undef ROL64
+# undef KECCAK_F1600_PERMUTE_FUNC_NAME
+# undef KECCAK_F1600_ABSORB_FUNC_NAME
+
+static const keccak_ops_t keccak_generic64_ops =
+{
+  .permute = keccak_f1600_state_permute64,
+  .absorb = keccak_absorb_lanes64,
+  .extract = keccak_extract64,
+};
+
+#endif /* USE_64BIT */
+
+
+/* Construct 64-bit Intel SHLD implementation. */
+#ifdef USE_64BIT_SHLD
+
+# define ANDN64(x, y) (~(x) & (y))
+# define ROL64(x, n) ({ \
+                       u64 tmp = (x); \
+                       asm ("shldq %1, %0, %0" \
+                            : "+r" (tmp) \
+                            : "J" ((n) & 63) \
+                            : "cc"); \
+                       tmp; })
+
+# define KECCAK_F1600_PERMUTE_FUNC_NAME keccak_f1600_state_permute64_shld
+# define KECCAK_F1600_ABSORB_FUNC_NAME keccak_absorb_lanes64_shld
+# include "keccak_permute_64.h"
+
+# undef ANDN64
+# undef ROL64
+# undef KECCAK_F1600_PERMUTE_FUNC_NAME
+# undef KECCAK_F1600_ABSORB_FUNC_NAME
+
+static const keccak_ops_t keccak_shld_64_ops =
+{
+  .permute = keccak_f1600_state_permute64_shld,
+  .absorb = keccak_absorb_lanes64_shld,
+  .extract = keccak_extract64,
+};
+
+#endif /* USE_64BIT_SHLD */
+
+
+/* Construct 64-bit Intel BMI2 implementation. */
+#ifdef USE_64BIT_BMI2
+
+# define ANDN64(x, y) ({ \
+                       u64 tmp; \
+                       asm ("andnq %2, %1, %0" \
+                            : "=r" (tmp) \
+                            : "r0" (x), "rm" (y)); \
+                       tmp; })
+
+# define ROL64(x, n) ({ \
+                       u64 tmp; \
+                       asm ("rorxq %2, %1, %0" \
+                            : "=r" (tmp) \
+                            : "rm0" (x), "J" (64 - ((n) & 63))); \
+                       tmp; })
+
+# define KECCAK_F1600_PERMUTE_FUNC_NAME keccak_f1600_state_permute64_bmi2
+# define KECCAK_F1600_ABSORB_FUNC_NAME keccak_absorb_lanes64_bmi2
+# include "keccak_permute_64.h"
+
+# undef ANDN64
+# undef ROL64
+# undef KECCAK_F1600_PERMUTE_FUNC_NAME
+# undef KECCAK_F1600_ABSORB_FUNC_NAME
+
+static const keccak_ops_t keccak_bmi2_64_ops =
+{
+  .permute = keccak_f1600_state_permute64_bmi2,
+  .absorb = keccak_absorb_lanes64_bmi2,
+  .extract = keccak_extract64,
+};
+
+#endif /* USE_64BIT_BMI2 */
+
+
+/* 64-bit ARMv7/NEON implementation. */
+#ifdef USE_64BIT_ARM_NEON
+
+unsigned int _gcry_keccak_permute_armv7_neon(u64 *state);
+unsigned int _gcry_keccak_absorb_lanes64_armv7_neon(u64 *state, int pos,
+                                                   const byte *lanes,
+                                                   unsigned int nlanes,
+                                                   int blocklanes);
+
+static unsigned int keccak_permute64_armv7_neon(KECCAK_STATE *hd)
+{
+  return _gcry_keccak_permute_armv7_neon(hd->u.state64);
+}
+
+static unsigned int
+keccak_absorb_lanes64_armv7_neon(KECCAK_STATE *hd, int pos, const byte *lanes,
+                                unsigned int nlanes, int blocklanes)
+{
+  if (blocklanes < 0)
+    {
+      /* blocklanes == -1, permutationless absorb from keccak_final. */
+
+      while (nlanes)
+       {
+         hd->u.state64[pos] ^= buf_get_le64(lanes);
+         lanes += 8;
+         nlanes--;
+       }
+
+      return 0;
+    }
+  else
+    {
+      return _gcry_keccak_absorb_lanes64_armv7_neon(hd->u.state64, pos, lanes,
+                                                   nlanes, blocklanes);
+    }
+}
+
+static const keccak_ops_t keccak_armv7_neon_64_ops =
+{
+  .permute = keccak_permute64_armv7_neon,
+  .absorb = keccak_absorb_lanes64_armv7_neon,
+  .extract = keccak_extract64,
+};
+
+#endif /* USE_64BIT_ARM_NEON */
+
+
+/* Construct generic 32-bit implementation. */
+#ifdef USE_32BIT
+
+# define ANDN32(x, y) (~(x) & (y))
+# define ROL32(x, n) (((x) << ((unsigned int)n & 31)) | \
+                     ((x) >> ((32 - (unsigned int)(n)) & 31)))
+
+# define KECCAK_F1600_PERMUTE_FUNC_NAME keccak_f1600_state_permute32bi
+# include "keccak_permute_32.h"
+
+# undef ANDN32
+# undef ROL32
+# undef KECCAK_F1600_PERMUTE_FUNC_NAME
+
+static unsigned int
+keccak_absorb_lanes32bi(KECCAK_STATE *hd, int pos, const byte *lanes,
+                       unsigned int nlanes, int blocklanes)
+{
+  unsigned int burn = 0;
+
+  while (nlanes)
+    {
+      keccak_absorb_lane32bi(&hd->u.state32bi[pos * 2],
+                            buf_get_le32(lanes + 0),
+                            buf_get_le32(lanes + 4));
+      lanes += 8;
+      nlanes--;
+
+      if (++pos == blocklanes)
+       {
+         burn = keccak_f1600_state_permute32bi(hd);
+         pos = 0;
+       }
+    }
+
+  return burn;
+}
+
+static const keccak_ops_t keccak_generic32bi_ops =
+{
+  .permute = keccak_f1600_state_permute32bi,
+  .absorb = keccak_absorb_lanes32bi,
+  .extract = keccak_extract32bi,
+};
+
+#endif /* USE_32BIT */
+
+
+/* Construct 32-bit Intel BMI2 implementation. */
+#ifdef USE_32BIT_BMI2
+
+# define ANDN32(x, y) ({ \
+                       u32 tmp; \
+                       asm ("andnl %2, %1, %0" \
+                            : "=r" (tmp) \
+                            : "r0" (x), "rm" (y)); \
+                       tmp; })
+
+# define ROL32(x, n) ({ \
+                       u32 tmp; \
+                       asm ("rorxl %2, %1, %0" \
+                            : "=r" (tmp) \
+                            : "rm0" (x), "J" (32 - ((n) & 31))); \
+                       tmp; })
+
+# define KECCAK_F1600_PERMUTE_FUNC_NAME keccak_f1600_state_permute32bi_bmi2
+# include "keccak_permute_32.h"
+
+# undef ANDN32
+# undef ROL32
+# undef KECCAK_F1600_PERMUTE_FUNC_NAME
+
+static inline u32 pext(u32 x, u32 mask)
+{
+  u32 tmp;
+  asm ("pextl %2, %1, %0" : "=r" (tmp) : "r0" (x), "rm" (mask));
+  return tmp;
+}
+
+static inline u32 pdep(u32 x, u32 mask)
+{
+  u32 tmp;
+  asm ("pdepl %2, %1, %0" : "=r" (tmp) : "r0" (x), "rm" (mask));
+  return tmp;
+}
+
+static inline void
+keccak_absorb_lane32bi_bmi2(u32 *lane, u32 x0, u32 x1)
+{
+  x0 = pdep(pext(x0, 0x55555555), 0x0000ffff) | (pext(x0, 0xaaaaaaaa) << 16);
+  x1 = pdep(pext(x1, 0x55555555), 0x0000ffff) | (pext(x1, 0xaaaaaaaa) << 16);
+
+  lane[0] ^= (x0 & 0x0000FFFFUL) + (x1 << 16);
+  lane[1] ^= (x0 >> 16) + (x1 & 0xFFFF0000UL);
+}
+
+static unsigned int
+keccak_absorb_lanes32bi_bmi2(KECCAK_STATE *hd, int pos, const byte *lanes,
+                            unsigned int nlanes, int blocklanes)
+{
+  unsigned int burn = 0;
+
+  while (nlanes)
+    {
+      keccak_absorb_lane32bi_bmi2(&hd->u.state32bi[pos * 2],
+                                 buf_get_le32(lanes + 0),
+                                 buf_get_le32(lanes + 4));
+      lanes += 8;
+      nlanes--;
+
+      if (++pos == blocklanes)
+       {
+         burn = keccak_f1600_state_permute32bi_bmi2(hd);
+         pos = 0;
+       }
+    }
+
+  return burn;
+}
+
+static unsigned int
+keccak_extract32bi_bmi2(KECCAK_STATE *hd, unsigned int pos, byte *outbuf,
+                       unsigned int outlen)
+{
+  unsigned int i;
+  u32 x0;
+  u32 x1;
+  u32 t;
+
+  /* NOTE: when pos == 0, hd and outbuf may point to same memory (SHA-3). */
+
+  for (i = pos; i < pos + outlen / 8 + !!(outlen % 8); i++)
+    {
+      x0 = hd->u.state32bi[i * 2 + 0];
+      x1 = hd->u.state32bi[i * 2 + 1];
+
+      t = (x0 & 0x0000FFFFUL) + (x1 << 16);
+      x1 = (x0 >> 16) + (x1 & 0xFFFF0000UL);
+      x0 = t;
+
+      x0 = pdep(pext(x0, 0xffff0001), 0xaaaaaaab) | pdep(x0 >> 1, 0x55555554);
+      x1 = pdep(pext(x1, 0xffff0001), 0xaaaaaaab) | pdep(x1 >> 1, 0x55555554);
+
+      buf_put_le32(&outbuf[0], x0);
+      buf_put_le32(&outbuf[4], x1);
+      outbuf += 8;
+    }
+
+  return 0;
+}
+
+static const keccak_ops_t keccak_bmi2_32bi_ops =
+{
+  .permute = keccak_f1600_state_permute32bi_bmi2,
+  .absorb = keccak_absorb_lanes32bi_bmi2,
+  .extract = keccak_extract32bi_bmi2,
+};
+
+#endif /* USE_32BIT */
+
+
+static void
+keccak_write (void *context, const void *inbuf_arg, size_t inlen)
+{
+  KECCAK_CONTEXT *ctx = context;
+  const size_t bsize = ctx->blocksize;
+  const size_t blocklanes = bsize / 8;
+  const byte *inbuf = inbuf_arg;
+  unsigned int nburn, burn = 0;
+  unsigned int count, i;
+  unsigned int pos, nlanes;
+
+  count = ctx->count;
+
+  if (inlen && (count % 8))
+    {
+      byte lane[8] = { 0, };
+
+      /* Complete absorbing partial input lane. */
+
+      pos = count / 8;
+
+      for (i = count % 8; inlen && i < 8; i++)
+       {
+         lane[i] = *inbuf++;
+         inlen--;
+         count++;
+       }
+
+      if (count == bsize)
+       count = 0;
+
+      nburn = ctx->ops->absorb(&ctx->state, pos, lane, 1,
+                              (count % 8) ? -1 : blocklanes);
+      burn = nburn > burn ? nburn : burn;
+    }
+
+  /* Absorb full input lanes. */
+
+  pos = count / 8;
+  nlanes = inlen / 8;
+  if (nlanes > 0)
+    {
+      nburn = ctx->ops->absorb(&ctx->state, pos, inbuf, nlanes, blocklanes);
+      burn = nburn > burn ? nburn : burn;
+      inlen -= nlanes * 8;
+      inbuf += nlanes * 8;
+      count += nlanes * 8;
+      count = count % bsize;
+    }
+
+  if (inlen)
+    {
+      byte lane[8] = { 0, };
+
+      /* Absorb remaining partial input lane. */
+
+      pos = count / 8;
+
+      for (i = count % 8; inlen && i < 8; i++)
+       {
+         lane[i] = *inbuf++;
+         inlen--;
+         count++;
+       }
+
+      nburn = ctx->ops->absorb(&ctx->state, pos, lane, 1, -1);
+      burn = nburn > burn ? nburn : burn;
+
+      gcry_assert(count < bsize);
+    }
+
+  ctx->count = count;
+
+  if (burn)
+    _gcry_burn_stack (burn);
+}
+
+
+static void
+keccak_init (int algo, void *context, unsigned int flags)
+{
+  KECCAK_CONTEXT *ctx = context;
+  KECCAK_STATE *hd = &ctx->state;
+  unsigned int features = _gcry_get_hw_features ();
+
+  (void)flags;
+  (void)features;
+
+  memset (hd, 0, sizeof *hd);
+
+  ctx->count = 0;
+
+  /* Select generic implementation. */
+#ifdef USE_64BIT
+  ctx->ops = &keccak_generic64_ops;
+#elif defined USE_32BIT
+  ctx->ops = &keccak_generic32bi_ops;
+#endif
+
+  /* Select optimized implementation based in hw features. */
+  if (0) {}
+#ifdef USE_64BIT_ARM_NEON
+  else if (features & HWF_ARM_NEON)
+    ctx->ops = &keccak_armv7_neon_64_ops;
+#endif
+#ifdef USE_64BIT_BMI2
+  else if (features & HWF_INTEL_BMI2)
+    ctx->ops = &keccak_bmi2_64_ops;
+#endif
+#ifdef USE_32BIT_BMI2
+  else if (features & HWF_INTEL_BMI2)
+    ctx->ops = &keccak_bmi2_32bi_ops;
+#endif
+#ifdef USE_64BIT_SHLD
+  else if (features & HWF_INTEL_FAST_SHLD)
+    ctx->ops = &keccak_shld_64_ops;
+#endif
+
+  /* Set input block size, in Keccak terms this is called 'rate'. */
+
+  switch (algo)
+    {
+    case GCRY_MD_SHA3_224:
+      ctx->suffix = SHA3_DELIMITED_SUFFIX;
+      ctx->blocksize = 1152 / 8;
+      ctx->outlen = 224 / 8;
+      break;
+    case GCRY_MD_SHA3_256:
+      ctx->suffix = SHA3_DELIMITED_SUFFIX;
+      ctx->blocksize = 1088 / 8;
+      ctx->outlen = 256 / 8;
+      break;
+    case GCRY_MD_SHA3_384:
+      ctx->suffix = SHA3_DELIMITED_SUFFIX;
+      ctx->blocksize = 832 / 8;
+      ctx->outlen = 384 / 8;
+      break;
+    case GCRY_MD_SHA3_512:
+      ctx->suffix = SHA3_DELIMITED_SUFFIX;
+      ctx->blocksize = 576 / 8;
+      ctx->outlen = 512 / 8;
+      break;
+    case GCRY_MD_SHAKE128:
+      ctx->suffix = SHAKE_DELIMITED_SUFFIX;
+      ctx->blocksize = 1344 / 8;
+      ctx->outlen = 0;
+      break;
+    case GCRY_MD_SHAKE256:
+      ctx->suffix = SHAKE_DELIMITED_SUFFIX;
+      ctx->blocksize = 1088 / 8;
+      ctx->outlen = 0;
+      break;
+    default:
+      BUG();
+    }
+}
+
+static void
+sha3_224_init (void *context, unsigned int flags)
+{
+  keccak_init (GCRY_MD_SHA3_224, context, flags);
+}
+
+static void
+sha3_256_init (void *context, unsigned int flags)
+{
+  keccak_init (GCRY_MD_SHA3_256, context, flags);
+}
+
+static void
+sha3_384_init (void *context, unsigned int flags)
+{
+  keccak_init (GCRY_MD_SHA3_384, context, flags);
+}
+
+static void
+sha3_512_init (void *context, unsigned int flags)
+{
+  keccak_init (GCRY_MD_SHA3_512, context, flags);
+}
+
+static void
+shake128_init (void *context, unsigned int flags)
+{
+  keccak_init (GCRY_MD_SHAKE128, context, flags);
+}
+
+static void
+shake256_init (void *context, unsigned int flags)
+{
+  keccak_init (GCRY_MD_SHAKE256, context, flags);
+}
+
+/* The routine final terminates the computation and
+ * returns the digest.
+ * The handle is prepared for a new cycle, but adding bytes to the
+ * handle will the destroy the returned buffer.
+ * Returns: 64 bytes representing the digest.  When used for sha384,
+ * we take the leftmost 48 of those bytes.
+ */
+static void
+keccak_final (void *context)
+{
+  KECCAK_CONTEXT *ctx = context;
+  KECCAK_STATE *hd = &ctx->state;
+  const size_t bsize = ctx->blocksize;
+  const byte suffix = ctx->suffix;
+  unsigned int nburn, burn = 0;
+  unsigned int lastbytes;
+  byte lane[8];
+
+  lastbytes = ctx->count;
+
+  /* Do the padding and switch to the squeezing phase */
+
+  /* Absorb the last few bits and add the first bit of padding (which
+     coincides with the delimiter in delimited suffix) */
+  buf_put_le64(lane, (u64)suffix << ((lastbytes % 8) * 8));
+  nburn = ctx->ops->absorb(&ctx->state, lastbytes / 8, lane, 1, -1);
+  burn = nburn > burn ? nburn : burn;
+
+  /* Add the second bit of padding. */
+  buf_put_le64(lane, (u64)0x80 << (((bsize - 1) % 8) * 8));
+  nburn = ctx->ops->absorb(&ctx->state, (bsize - 1) / 8, lane, 1, -1);
+  burn = nburn > burn ? nburn : burn;
+
+  if (suffix == SHA3_DELIMITED_SUFFIX)
+    {
+      /* Switch to the squeezing phase. */
+      nburn = ctx->ops->permute(hd);
+      burn = nburn > burn ? nburn : burn;
+
+      /* Squeeze out the SHA3 digest. */
+      nburn = ctx->ops->extract(hd, 0, (void *)hd, ctx->outlen);
+      burn = nburn > burn ? nburn : burn;
+    }
+  else
+    {
+      /* Output for SHAKE can now be read with md_extract(). */
+
+      ctx->count = 0;
+    }
+
+  wipememory(lane, sizeof(lane));
+  if (burn)
+    _gcry_burn_stack (burn);
+}
+
+
+static byte *
+keccak_read (void *context)
+{
+  KECCAK_CONTEXT *ctx = (KECCAK_CONTEXT *) context;
+  KECCAK_STATE *hd = &ctx->state;
+  return (byte *)&hd->u;
+}
+
+
+static void
+keccak_extract (void *context, void *out, size_t outlen)
+{
+  KECCAK_CONTEXT *ctx = context;
+  KECCAK_STATE *hd = &ctx->state;
+  const size_t bsize = ctx->blocksize;
+  unsigned int nburn, burn = 0;
+  byte *outbuf = out;
+  unsigned int nlanes;
+  unsigned int nleft;
+  unsigned int count;
+  unsigned int i;
+  byte lane[8];
+
+  count = ctx->count;
+
+  while (count && outlen && (outlen < 8 || count % 8))
+    {
+      /* Extract partial lane. */
+      nburn = ctx->ops->extract(hd, count / 8, lane, 8);
+      burn = nburn > burn ? nburn : burn;
+
+      for (i = count % 8; outlen && i < 8; i++)
+       {
+         *outbuf++ = lane[i];
+         outlen--;
+         count++;
+       }
+
+      gcry_assert(count <= bsize);
+
+      if (count == bsize)
+       count = 0;
+    }
+
+  if (outlen >= 8 && count)
+    {
+      /* Extract tail of partial block. */
+      nlanes = outlen / 8;
+      nleft = (bsize - count) / 8;
+      nlanes = nlanes < nleft ? nlanes : nleft;
+
+      nburn = ctx->ops->extract(hd, count / 8, outbuf, nlanes * 8);
+      burn = nburn > burn ? nburn : burn;
+      outlen -= nlanes * 8;
+      outbuf += nlanes * 8;
+      count += nlanes * 8;
+
+      gcry_assert(count <= bsize);
+
+      if (count == bsize)
+       count = 0;
+    }
+
+  while (outlen >= bsize)
+    {
+      gcry_assert(count == 0);
+
+      /* Squeeze more. */
+      nburn = ctx->ops->permute(hd);
+      burn = nburn > burn ? nburn : burn;
+
+      /* Extract full block. */
+      nburn = ctx->ops->extract(hd, 0, outbuf, bsize);
+      burn = nburn > burn ? nburn : burn;
+
+      outlen -= bsize;
+      outbuf += bsize;
+    }
+
+  if (outlen)
+    {
+      gcry_assert(outlen < bsize);
+
+      if (count == 0)
+       {
+         /* Squeeze more. */
+         nburn = ctx->ops->permute(hd);
+         burn = nburn > burn ? nburn : burn;
+       }
+
+      if (outlen >= 8)
+       {
+         /* Extract head of partial block. */
+         nlanes = outlen / 8;
+         nburn = ctx->ops->extract(hd, count / 8, outbuf, nlanes * 8);
+         burn = nburn > burn ? nburn : burn;
+         outlen -= nlanes * 8;
+         outbuf += nlanes * 8;
+         count += nlanes * 8;
+
+         gcry_assert(count < bsize);
+       }
+
+      if (outlen)
+       {
+         /* Extract head of partial lane. */
+         nburn = ctx->ops->extract(hd, count / 8, lane, 8);
+         burn = nburn > burn ? nburn : burn;
+
+         for (i = count % 8; outlen && i < 8; i++)
+           {
+             *outbuf++ = lane[i];
+             outlen--;
+             count++;
+           }
+
+         gcry_assert(count < bsize);
+       }
+    }
+
+  ctx->count = count;
+
+  if (burn)
+    _gcry_burn_stack (burn);
+}
+
+
+\f
+/*
+     Self-test section.
+ */
+
+
+static gpg_err_code_t
+selftests_keccak (int algo, int extended, selftest_report_func_t report)
+{
+  const char *what;
+  const char *errtxt;
+  const char *short_hash;
+  const char *long_hash;
+  const char *one_million_a_hash;
+  int hash_len;
+
+  switch (algo)
+  {
+    default:
+      BUG();
+
+    case GCRY_MD_SHA3_224:
+      short_hash =
+       "\xe6\x42\x82\x4c\x3f\x8c\xf2\x4a\xd0\x92\x34\xee\x7d\x3c\x76\x6f"
+       "\xc9\xa3\xa5\x16\x8d\x0c\x94\xad\x73\xb4\x6f\xdf";
+      long_hash =
+       "\x54\x3e\x68\x68\xe1\x66\x6c\x1a\x64\x36\x30\xdf\x77\x36\x7a\xe5"
+       "\xa6\x2a\x85\x07\x0a\x51\xc1\x4c\xbf\x66\x5c\xbc";
+      one_million_a_hash =
+       "\xd6\x93\x35\xb9\x33\x25\x19\x2e\x51\x6a\x91\x2e\x6d\x19\xa1\x5c"
+       "\xb5\x1c\x6e\xd5\xc1\x52\x43\xe7\xa7\xfd\x65\x3c";
+      hash_len = 28;
+      break;
+
+    case GCRY_MD_SHA3_256:
+      short_hash =
+       "\x3a\x98\x5d\xa7\x4f\xe2\x25\xb2\x04\x5c\x17\x2d\x6b\xd3\x90\xbd"
+       "\x85\x5f\x08\x6e\x3e\x9d\x52\x5b\x46\xbf\xe2\x45\x11\x43\x15\x32";
+      long_hash =
+       "\x91\x6f\x60\x61\xfe\x87\x97\x41\xca\x64\x69\xb4\x39\x71\xdf\xdb"
+       "\x28\xb1\xa3\x2d\xc3\x6c\xb3\x25\x4e\x81\x2b\xe2\x7a\xad\x1d\x18";
+      one_million_a_hash =
+       "\x5c\x88\x75\xae\x47\x4a\x36\x34\xba\x4f\xd5\x5e\xc8\x5b\xff\xd6"
+       "\x61\xf3\x2a\xca\x75\xc6\xd6\x99\xd0\xcd\xcb\x6c\x11\x58\x91\xc1";
+      hash_len = 32;
+      break;
+
+    case GCRY_MD_SHA3_384:
+      short_hash =
+       "\xec\x01\x49\x82\x88\x51\x6f\xc9\x26\x45\x9f\x58\xe2\xc6\xad\x8d"
+       "\xf9\xb4\x73\xcb\x0f\xc0\x8c\x25\x96\xda\x7c\xf0\xe4\x9b\xe4\xb2"
+       "\x98\xd8\x8c\xea\x92\x7a\xc7\xf5\x39\xf1\xed\xf2\x28\x37\x6d\x25";
+      long_hash =
+       "\x79\x40\x7d\x3b\x59\x16\xb5\x9c\x3e\x30\xb0\x98\x22\x97\x47\x91"
+       "\xc3\x13\xfb\x9e\xcc\x84\x9e\x40\x6f\x23\x59\x2d\x04\xf6\x25\xdc"
+       "\x8c\x70\x9b\x98\xb4\x3b\x38\x52\xb3\x37\x21\x61\x79\xaa\x7f\xc7";
+      one_million_a_hash =
+       "\xee\xe9\xe2\x4d\x78\xc1\x85\x53\x37\x98\x34\x51\xdf\x97\xc8\xad"
+       "\x9e\xed\xf2\x56\xc6\x33\x4f\x8e\x94\x8d\x25\x2d\x5e\x0e\x76\x84"
+       "\x7a\xa0\x77\x4d\xdb\x90\xa8\x42\x19\x0d\x2c\x55\x8b\x4b\x83\x40";
+      hash_len = 48;
+      break;
+
+    case GCRY_MD_SHA3_512:
+      short_hash =
+       "\xb7\x51\x85\x0b\x1a\x57\x16\x8a\x56\x93\xcd\x92\x4b\x6b\x09\x6e"
+       "\x08\xf6\x21\x82\x74\x44\xf7\x0d\x88\x4f\x5d\x02\x40\xd2\x71\x2e"
+       "\x10\xe1\x16\xe9\x19\x2a\xf3\xc9\x1a\x7e\xc5\x76\x47\xe3\x93\x40"
+       "\x57\x34\x0b\x4c\xf4\x08\xd5\xa5\x65\x92\xf8\x27\x4e\xec\x53\xf0";
+      long_hash =
+       "\xaf\xeb\xb2\xef\x54\x2e\x65\x79\xc5\x0c\xad\x06\xd2\xe5\x78\xf9"
+       "\xf8\xdd\x68\x81\xd7\xdc\x82\x4d\x26\x36\x0f\xee\xbf\x18\xa4\xfa"
+       "\x73\xe3\x26\x11\x22\x94\x8e\xfc\xfd\x49\x2e\x74\xe8\x2e\x21\x89"
+       "\xed\x0f\xb4\x40\xd1\x87\xf3\x82\x27\x0c\xb4\x55\xf2\x1d\xd1\x85";
+      one_million_a_hash =
+       "\x3c\x3a\x87\x6d\xa1\x40\x34\xab\x60\x62\x7c\x07\x7b\xb9\x8f\x7e"
+       "\x12\x0a\x2a\x53\x70\x21\x2d\xff\xb3\x38\x5a\x18\xd4\xf3\x88\x59"
+       "\xed\x31\x1d\x0a\x9d\x51\x41\xce\x9c\xc5\xc6\x6e\xe6\x89\xb2\x66"
+       "\xa8\xaa\x18\xac\xe8\x28\x2a\x0e\x0d\xb5\x96\xc9\x0b\x0a\x7b\x87";
+      hash_len = 64;
+      break;
+
+    case GCRY_MD_SHAKE128:
+      short_hash =
+       "\x58\x81\x09\x2d\xd8\x18\xbf\x5c\xf8\xa3\xdd\xb7\x93\xfb\xcb\xa7"
+       "\x40\x97\xd5\xc5\x26\xa6\xd3\x5f\x97\xb8\x33\x51\x94\x0f\x2c\xc8";
+      long_hash =
+       "\x7b\x6d\xf6\xff\x18\x11\x73\xb6\xd7\x89\x8d\x7f\xf6\x3f\xb0\x7b"
+       "\x7c\x23\x7d\xaf\x47\x1a\x5a\xe5\x60\x2a\xdb\xcc\xef\x9c\xcf\x4b";
+      one_million_a_hash =
+       "\x9d\x22\x2c\x79\xc4\xff\x9d\x09\x2c\xf6\xca\x86\x14\x3a\xa4\x11"
+       "\xe3\x69\x97\x38\x08\xef\x97\x09\x32\x55\x82\x6c\x55\x72\xef\x58";
+      hash_len = 32;
+      break;
+
+    case GCRY_MD_SHAKE256:
+      short_hash =
+       "\x48\x33\x66\x60\x13\x60\xa8\x77\x1c\x68\x63\x08\x0c\xc4\x11\x4d"
+       "\x8d\xb4\x45\x30\xf8\xf1\xe1\xee\x4f\x94\xea\x37\xe7\x8b\x57\x39";
+      long_hash =
+       "\x98\xbe\x04\x51\x6c\x04\xcc\x73\x59\x3f\xef\x3e\xd0\x35\x2e\xa9"
+       "\xf6\x44\x39\x42\xd6\x95\x0e\x29\xa3\x72\xa6\x81\xc3\xde\xaf\x45";
+      one_million_a_hash =
+       "\x35\x78\xa7\xa4\xca\x91\x37\x56\x9c\xdf\x76\xed\x61\x7d\x31\xbb"
+       "\x99\x4f\xca\x9c\x1b\xbf\x8b\x18\x40\x13\xde\x82\x34\xdf\xd1\x3a";
+      hash_len = 32;
+      break;
+  }
+
+  what = "short string";
+  errtxt = _gcry_hash_selftest_check_one (algo, 0, "abc", 3, short_hash,
+                                         hash_len);
+  if (errtxt)
+    goto failed;
+
+  if (extended)
+    {
+      what = "long string";
+      errtxt = _gcry_hash_selftest_check_one
+       (algo, 0,
+       "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+       "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112,
+       long_hash, hash_len);
+      if (errtxt)
+       goto failed;
+
+      what = "one million \"a\"";
+      errtxt = _gcry_hash_selftest_check_one (algo, 1, NULL, 0,
+                                             one_million_a_hash, hash_len);
+      if (errtxt)
+       goto failed;
+    }
+
+  return 0; /* Succeeded. */
+
+failed:
+  if (report)
+    report ("digest", algo, what, errtxt);
+  return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+/* Run a full self-test for ALGO and return 0 on success.  */
+static gpg_err_code_t
+run_selftests (int algo, int extended, selftest_report_func_t report)
+{
+  gpg_err_code_t ec;
+
+  switch (algo)
+    {
+    case GCRY_MD_SHA3_224:
+    case GCRY_MD_SHA3_256:
+    case GCRY_MD_SHA3_384:
+    case GCRY_MD_SHA3_512:
+    case GCRY_MD_SHAKE128:
+    case GCRY_MD_SHAKE256:
+      ec = selftests_keccak (algo, extended, report);
+      break;
+    default:
+      ec = GPG_ERR_DIGEST_ALGO;
+      break;
+    }
+
+  return ec;
+}
+
+
+
+\f
+static byte sha3_224_asn[] = { 0x30 };
+static gcry_md_oid_spec_t oid_spec_sha3_224[] =
+  {
+    { "2.16.840.1.101.3.4.2.7" },
+    /* PKCS#1 sha3_224WithRSAEncryption */
+    { "?" },
+    { NULL }
+  };
+static byte sha3_256_asn[] = { 0x30 };
+static gcry_md_oid_spec_t oid_spec_sha3_256[] =
+  {
+    { "2.16.840.1.101.3.4.2.8" },
+    /* PKCS#1 sha3_256WithRSAEncryption */
+    { "?" },
+    { NULL }
+  };
+static byte sha3_384_asn[] = { 0x30 };
+static gcry_md_oid_spec_t oid_spec_sha3_384[] =
+  {
+    { "2.16.840.1.101.3.4.2.9" },
+    /* PKCS#1 sha3_384WithRSAEncryption */
+    { "?" },
+    { NULL }
+  };
+static byte sha3_512_asn[] = { 0x30 };
+static gcry_md_oid_spec_t oid_spec_sha3_512[] =
+  {
+    { "2.16.840.1.101.3.4.2.10" },
+    /* PKCS#1 sha3_512WithRSAEncryption */
+    { "?" },
+    { NULL }
+  };
+static byte shake128_asn[] = { 0x30 };
+static gcry_md_oid_spec_t oid_spec_shake128[] =
+  {
+    { "2.16.840.1.101.3.4.2.11" },
+    /* PKCS#1 shake128WithRSAEncryption */
+    { "?" },
+    { NULL }
+  };
+static byte shake256_asn[] = { 0x30 };
+static gcry_md_oid_spec_t oid_spec_shake256[] =
+  {
+    { "2.16.840.1.101.3.4.2.12" },
+    /* PKCS#1 shake256WithRSAEncryption */
+    { "?" },
+    { NULL }
+  };
+
+gcry_md_spec_t _gcry_digest_spec_sha3_224 =
+  {
+    GCRY_MD_SHA3_224, {0, 1},
+    "SHA3-224", sha3_224_asn, DIM (sha3_224_asn), oid_spec_sha3_224, 28,
+    sha3_224_init, keccak_write, keccak_final, keccak_read, NULL,
+    sizeof (KECCAK_CONTEXT),
+    run_selftests
+  };
+gcry_md_spec_t _gcry_digest_spec_sha3_256 =
+  {
+    GCRY_MD_SHA3_256, {0, 1},
+    "SHA3-256", sha3_256_asn, DIM (sha3_256_asn), oid_spec_sha3_256, 32,
+    sha3_256_init, keccak_write, keccak_final, keccak_read, NULL,
+    sizeof (KECCAK_CONTEXT),
+    run_selftests
+  };
+gcry_md_spec_t _gcry_digest_spec_sha3_384 =
+  {
+    GCRY_MD_SHA3_384, {0, 1},
+    "SHA3-384", sha3_384_asn, DIM (sha3_384_asn), oid_spec_sha3_384, 48,
+    sha3_384_init, keccak_write, keccak_final, keccak_read, NULL,
+    sizeof (KECCAK_CONTEXT),
+    run_selftests
+  };
+gcry_md_spec_t _gcry_digest_spec_sha3_512 =
+  {
+    GCRY_MD_SHA3_512, {0, 1},
+    "SHA3-512", sha3_512_asn, DIM (sha3_512_asn), oid_spec_sha3_512, 64,
+    sha3_512_init, keccak_write, keccak_final, keccak_read, NULL,
+    sizeof (KECCAK_CONTEXT),
+    run_selftests
+  };
+gcry_md_spec_t _gcry_digest_spec_shake128 =
+  {
+    GCRY_MD_SHAKE128, {0, 1},
+    "SHAKE128", shake128_asn, DIM (shake128_asn), oid_spec_shake128, 0,
+    shake128_init, keccak_write, keccak_final, NULL, keccak_extract,
+    sizeof (KECCAK_CONTEXT),
+    run_selftests
+  };
+gcry_md_spec_t _gcry_digest_spec_shake256 =
+  {
+    GCRY_MD_SHAKE256, {0, 1},
+    "SHAKE256", shake256_asn, DIM (shake256_asn), oid_spec_shake256, 0,
+    shake256_init, keccak_write, keccak_final, NULL, keccak_extract,
+    sizeof (KECCAK_CONTEXT),
+    run_selftests
+  };
diff --git a/cipher/keccak_permute_32.h b/cipher/keccak_permute_32.h
new file mode 100644 (file)
index 0000000..1ce42a4
--- /dev/null
@@ -0,0 +1,536 @@
+/* keccak_permute_32.h - Keccak permute function (simple 32bit bit-interleaved)
+ * Copyright (C) 2015 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* The code is based on public-domain/CC0 "keccakc1024/simple32bi/
+ * Keccak-simple32BI.c" implementation by Ronny Van Keer from SUPERCOP toolkit
+ * package.
+ */
+
+/* Function that computes the Keccak-f[1600] permutation on the given state. */
+static unsigned int
+KECCAK_F1600_PERMUTE_FUNC_NAME(KECCAK_STATE *hd)
+{
+  const u32 *round_consts = round_consts_32bit;
+  const u32 *round_consts_end = round_consts_32bit + 2 * 24;
+  u32 Aba0, Abe0, Abi0, Abo0, Abu0;
+  u32 Aba1, Abe1, Abi1, Abo1, Abu1;
+  u32 Aga0, Age0, Agi0, Ago0, Agu0;
+  u32 Aga1, Age1, Agi1, Ago1, Agu1;
+  u32 Aka0, Ake0, Aki0, Ako0, Aku0;
+  u32 Aka1, Ake1, Aki1, Ako1, Aku1;
+  u32 Ama0, Ame0, Ami0, Amo0, Amu0;
+  u32 Ama1, Ame1, Ami1, Amo1, Amu1;
+  u32 Asa0, Ase0, Asi0, Aso0, Asu0;
+  u32 Asa1, Ase1, Asi1, Aso1, Asu1;
+  u32 BCa0, BCe0, BCi0, BCo0, BCu0;
+  u32 BCa1, BCe1, BCi1, BCo1, BCu1;
+  u32 Da0, De0, Di0, Do0, Du0;
+  u32 Da1, De1, Di1, Do1, Du1;
+  u32 Eba0, Ebe0, Ebi0, Ebo0, Ebu0;
+  u32 Eba1, Ebe1, Ebi1, Ebo1, Ebu1;
+  u32 Ega0, Ege0, Egi0, Ego0, Egu0;
+  u32 Ega1, Ege1, Egi1, Ego1, Egu1;
+  u32 Eka0, Eke0, Eki0, Eko0, Eku0;
+  u32 Eka1, Eke1, Eki1, Eko1, Eku1;
+  u32 Ema0, Eme0, Emi0, Emo0, Emu0;
+  u32 Ema1, Eme1, Emi1, Emo1, Emu1;
+  u32 Esa0, Ese0, Esi0, Eso0, Esu0;
+  u32 Esa1, Ese1, Esi1, Eso1, Esu1;
+  u32 *state = hd->u.state32bi;
+
+  Aba0 = state[0];
+  Aba1 = state[1];
+  Abe0 = state[2];
+  Abe1 = state[3];
+  Abi0 = state[4];
+  Abi1 = state[5];
+  Abo0 = state[6];
+  Abo1 = state[7];
+  Abu0 = state[8];
+  Abu1 = state[9];
+  Aga0 = state[10];
+  Aga1 = state[11];
+  Age0 = state[12];
+  Age1 = state[13];
+  Agi0 = state[14];
+  Agi1 = state[15];
+  Ago0 = state[16];
+  Ago1 = state[17];
+  Agu0 = state[18];
+  Agu1 = state[19];
+  Aka0 = state[20];
+  Aka1 = state[21];
+  Ake0 = state[22];
+  Ake1 = state[23];
+  Aki0 = state[24];
+  Aki1 = state[25];
+  Ako0 = state[26];
+  Ako1 = state[27];
+  Aku0 = state[28];
+  Aku1 = state[29];
+  Ama0 = state[30];
+  Ama1 = state[31];
+  Ame0 = state[32];
+  Ame1 = state[33];
+  Ami0 = state[34];
+  Ami1 = state[35];
+  Amo0 = state[36];
+  Amo1 = state[37];
+  Amu0 = state[38];
+  Amu1 = state[39];
+  Asa0 = state[40];
+  Asa1 = state[41];
+  Ase0 = state[42];
+  Ase1 = state[43];
+  Asi0 = state[44];
+  Asi1 = state[45];
+  Aso0 = state[46];
+  Aso1 = state[47];
+  Asu0 = state[48];
+  Asu1 = state[49];
+
+  do
+    {
+      /* prepareTheta */
+      BCa0 = Aba0 ^ Aga0 ^ Aka0 ^ Ama0 ^ Asa0;
+      BCa1 = Aba1 ^ Aga1 ^ Aka1 ^ Ama1 ^ Asa1;
+      BCe0 = Abe0 ^ Age0 ^ Ake0 ^ Ame0 ^ Ase0;
+      BCe1 = Abe1 ^ Age1 ^ Ake1 ^ Ame1 ^ Ase1;
+      BCi0 = Abi0 ^ Agi0 ^ Aki0 ^ Ami0 ^ Asi0;
+      BCi1 = Abi1 ^ Agi1 ^ Aki1 ^ Ami1 ^ Asi1;
+      BCo0 = Abo0 ^ Ago0 ^ Ako0 ^ Amo0 ^ Aso0;
+      BCo1 = Abo1 ^ Ago1 ^ Ako1 ^ Amo1 ^ Aso1;
+      BCu0 = Abu0 ^ Agu0 ^ Aku0 ^ Amu0 ^ Asu0;
+      BCu1 = Abu1 ^ Agu1 ^ Aku1 ^ Amu1 ^ Asu1;
+
+      /* thetaRhoPiChiIota(round  , A, E) */
+      Da0 = BCu0 ^ ROL32(BCe1, 1);
+      Da1 = BCu1 ^ BCe0;
+      De0 = BCa0 ^ ROL32(BCi1, 1);
+      De1 = BCa1 ^ BCi0;
+      Di0 = BCe0 ^ ROL32(BCo1, 1);
+      Di1 = BCe1 ^ BCo0;
+      Do0 = BCi0 ^ ROL32(BCu1, 1);
+      Do1 = BCi1 ^ BCu0;
+      Du0 = BCo0 ^ ROL32(BCa1, 1);
+      Du1 = BCo1 ^ BCa0;
+
+      Aba0 ^= Da0;
+      BCa0 = Aba0;
+      Age0 ^= De0;
+      BCe0 = ROL32(Age0, 22);
+      Aki1 ^= Di1;
+      BCi0 = ROL32(Aki1, 22);
+      Amo1 ^= Do1;
+      BCo0 = ROL32(Amo1, 11);
+      Asu0 ^= Du0;
+      BCu0 = ROL32(Asu0, 7);
+      Eba0 = BCa0 ^ ANDN32(BCe0, BCi0);
+      Eba0 ^= *(round_consts++);
+      Ebe0 = BCe0 ^ ANDN32(BCi0, BCo0);
+      Ebi0 = BCi0 ^ ANDN32(BCo0, BCu0);
+      Ebo0 = BCo0 ^ ANDN32(BCu0, BCa0);
+      Ebu0 = BCu0 ^ ANDN32(BCa0, BCe0);
+
+      Aba1 ^= Da1;
+      BCa1 = Aba1;
+      Age1 ^= De1;
+      BCe1 = ROL32(Age1, 22);
+      Aki0 ^= Di0;
+      BCi1 = ROL32(Aki0, 21);
+      Amo0 ^= Do0;
+      BCo1 = ROL32(Amo0, 10);
+      Asu1 ^= Du1;
+      BCu1 = ROL32(Asu1, 7);
+      Eba1 = BCa1 ^ ANDN32(BCe1, BCi1);
+      Eba1 ^= *(round_consts++);
+      Ebe1 = BCe1 ^ ANDN32(BCi1, BCo1);
+      Ebi1 = BCi1 ^ ANDN32(BCo1, BCu1);
+      Ebo1 = BCo1 ^ ANDN32(BCu1, BCa1);
+      Ebu1 = BCu1 ^ ANDN32(BCa1, BCe1);
+
+      Abo0 ^= Do0;
+      BCa0 = ROL32(Abo0, 14);
+      Agu0 ^= Du0;
+      BCe0 = ROL32(Agu0, 10);
+      Aka1 ^= Da1;
+      BCi0 = ROL32(Aka1, 2);
+      Ame1 ^= De1;
+      BCo0 = ROL32(Ame1, 23);
+      Asi1 ^= Di1;
+      BCu0 = ROL32(Asi1, 31);
+      Ega0 = BCa0 ^ ANDN32(BCe0, BCi0);
+      Ege0 = BCe0 ^ ANDN32(BCi0, BCo0);
+      Egi0 = BCi0 ^ ANDN32(BCo0, BCu0);
+      Ego0 = BCo0 ^ ANDN32(BCu0, BCa0);
+      Egu0 = BCu0 ^ ANDN32(BCa0, BCe0);
+
+      Abo1 ^= Do1;
+      BCa1 = ROL32(Abo1, 14);
+      Agu1 ^= Du1;
+      BCe1 = ROL32(Agu1, 10);
+      Aka0 ^= Da0;
+      BCi1 = ROL32(Aka0, 1);
+      Ame0 ^= De0;
+      BCo1 = ROL32(Ame0, 22);
+      Asi0 ^= Di0;
+      BCu1 = ROL32(Asi0, 30);
+      Ega1 = BCa1 ^ ANDN32(BCe1, BCi1);
+      Ege1 = BCe1 ^ ANDN32(BCi1, BCo1);
+      Egi1 = BCi1 ^ ANDN32(BCo1, BCu1);
+      Ego1 = BCo1 ^ ANDN32(BCu1, BCa1);
+      Egu1 = BCu1 ^ ANDN32(BCa1, BCe1);
+
+      Abe1 ^= De1;
+      BCa0 = ROL32(Abe1, 1);
+      Agi0 ^= Di0;
+      BCe0 = ROL32(Agi0, 3);
+      Ako1 ^= Do1;
+      BCi0 = ROL32(Ako1, 13);
+      Amu0 ^= Du0;
+      BCo0 = ROL32(Amu0, 4);
+      Asa0 ^= Da0;
+      BCu0 = ROL32(Asa0, 9);
+      Eka0 = BCa0 ^ ANDN32(BCe0, BCi0);
+      Eke0 = BCe0 ^ ANDN32(BCi0, BCo0);
+      Eki0 = BCi0 ^ ANDN32(BCo0, BCu0);
+      Eko0 = BCo0 ^ ANDN32(BCu0, BCa0);
+      Eku0 = BCu0 ^ ANDN32(BCa0, BCe0);
+
+      Abe0 ^= De0;
+      BCa1 = Abe0;
+      Agi1 ^= Di1;
+      BCe1 = ROL32(Agi1, 3);
+      Ako0 ^= Do0;
+      BCi1 = ROL32(Ako0, 12);
+      Amu1 ^= Du1;
+      BCo1 = ROL32(Amu1, 4);
+      Asa1 ^= Da1;
+      BCu1 = ROL32(Asa1, 9);
+      Eka1 = BCa1 ^ ANDN32(BCe1, BCi1);
+      Eke1 = BCe1 ^ ANDN32(BCi1, BCo1);
+      Eki1 = BCi1 ^ ANDN32(BCo1, BCu1);
+      Eko1 = BCo1 ^ ANDN32(BCu1, BCa1);
+      Eku1 = BCu1 ^ ANDN32(BCa1, BCe1);
+
+      Abu1 ^= Du1;
+      BCa0 = ROL32(Abu1, 14);
+      Aga0 ^= Da0;
+      BCe0 = ROL32(Aga0, 18);
+      Ake0 ^= De0;
+      BCi0 = ROL32(Ake0, 5);
+      Ami1 ^= Di1;
+      BCo0 = ROL32(Ami1, 8);
+      Aso0 ^= Do0;
+      BCu0 = ROL32(Aso0, 28);
+      Ema0 = BCa0 ^ ANDN32(BCe0, BCi0);
+      Eme0 = BCe0 ^ ANDN32(BCi0, BCo0);
+      Emi0 = BCi0 ^ ANDN32(BCo0, BCu0);
+      Emo0 = BCo0 ^ ANDN32(BCu0, BCa0);
+      Emu0 = BCu0 ^ ANDN32(BCa0, BCe0);
+
+      Abu0 ^= Du0;
+      BCa1 = ROL32(Abu0, 13);
+      Aga1 ^= Da1;
+      BCe1 = ROL32(Aga1, 18);
+      Ake1 ^= De1;
+      BCi1 = ROL32(Ake1, 5);
+      Ami0 ^= Di0;
+      BCo1 = ROL32(Ami0, 7);
+      Aso1 ^= Do1;
+      BCu1 = ROL32(Aso1, 28);
+      Ema1 = BCa1 ^ ANDN32(BCe1, BCi1);
+      Eme1 = BCe1 ^ ANDN32(BCi1, BCo1);
+      Emi1 = BCi1 ^ ANDN32(BCo1, BCu1);
+      Emo1 = BCo1 ^ ANDN32(BCu1, BCa1);
+      Emu1 = BCu1 ^ ANDN32(BCa1, BCe1);
+
+      Abi0 ^= Di0;
+      BCa0 = ROL32(Abi0, 31);
+      Ago1 ^= Do1;
+      BCe0 = ROL32(Ago1, 28);
+      Aku1 ^= Du1;
+      BCi0 = ROL32(Aku1, 20);
+      Ama1 ^= Da1;
+      BCo0 = ROL32(Ama1, 21);
+      Ase0 ^= De0;
+      BCu0 = ROL32(Ase0, 1);
+      Esa0 = BCa0 ^ ANDN32(BCe0, BCi0);
+      Ese0 = BCe0 ^ ANDN32(BCi0, BCo0);
+      Esi0 = BCi0 ^ ANDN32(BCo0, BCu0);
+      Eso0 = BCo0 ^ ANDN32(BCu0, BCa0);
+      Esu0 = BCu0 ^ ANDN32(BCa0, BCe0);
+
+      Abi1 ^= Di1;
+      BCa1 = ROL32(Abi1, 31);
+      Ago0 ^= Do0;
+      BCe1 = ROL32(Ago0, 27);
+      Aku0 ^= Du0;
+      BCi1 = ROL32(Aku0, 19);
+      Ama0 ^= Da0;
+      BCo1 = ROL32(Ama0, 20);
+      Ase1 ^= De1;
+      BCu1 = ROL32(Ase1, 1);
+      Esa1 = BCa1 ^ ANDN32(BCe1, BCi1);
+      Ese1 = BCe1 ^ ANDN32(BCi1, BCo1);
+      Esi1 = BCi1 ^ ANDN32(BCo1, BCu1);
+      Eso1 = BCo1 ^ ANDN32(BCu1, BCa1);
+      Esu1 = BCu1 ^ ANDN32(BCa1, BCe1);
+
+      /* prepareTheta */
+      BCa0 = Eba0 ^ Ega0 ^ Eka0 ^ Ema0 ^ Esa0;
+      BCa1 = Eba1 ^ Ega1 ^ Eka1 ^ Ema1 ^ Esa1;
+      BCe0 = Ebe0 ^ Ege0 ^ Eke0 ^ Eme0 ^ Ese0;
+      BCe1 = Ebe1 ^ Ege1 ^ Eke1 ^ Eme1 ^ Ese1;
+      BCi0 = Ebi0 ^ Egi0 ^ Eki0 ^ Emi0 ^ Esi0;
+      BCi1 = Ebi1 ^ Egi1 ^ Eki1 ^ Emi1 ^ Esi1;
+      BCo0 = Ebo0 ^ Ego0 ^ Eko0 ^ Emo0 ^ Eso0;
+      BCo1 = Ebo1 ^ Ego1 ^ Eko1 ^ Emo1 ^ Eso1;
+      BCu0 = Ebu0 ^ Egu0 ^ Eku0 ^ Emu0 ^ Esu0;
+      BCu1 = Ebu1 ^ Egu1 ^ Eku1 ^ Emu1 ^ Esu1;
+
+      /* thetaRhoPiChiIota(round+1, E, A) */
+      Da0 = BCu0 ^ ROL32(BCe1, 1);
+      Da1 = BCu1 ^ BCe0;
+      De0 = BCa0 ^ ROL32(BCi1, 1);
+      De1 = BCa1 ^ BCi0;
+      Di0 = BCe0 ^ ROL32(BCo1, 1);
+      Di1 = BCe1 ^ BCo0;
+      Do0 = BCi0 ^ ROL32(BCu1, 1);
+      Do1 = BCi1 ^ BCu0;
+      Du0 = BCo0 ^ ROL32(BCa1, 1);
+      Du1 = BCo1 ^ BCa0;
+
+      Eba0 ^= Da0;
+      BCa0 = Eba0;
+      Ege0 ^= De0;
+      BCe0 = ROL32(Ege0, 22);
+      Eki1 ^= Di1;
+      BCi0 = ROL32(Eki1, 22);
+      Emo1 ^= Do1;
+      BCo0 = ROL32(Emo1, 11);
+      Esu0 ^= Du0;
+      BCu0 = ROL32(Esu0, 7);
+      Aba0 = BCa0 ^ ANDN32(BCe0, BCi0);
+      Aba0 ^= *(round_consts++);
+      Abe0 = BCe0 ^ ANDN32(BCi0, BCo0);
+      Abi0 = BCi0 ^ ANDN32(BCo0, BCu0);
+      Abo0 = BCo0 ^ ANDN32(BCu0, BCa0);
+      Abu0 = BCu0 ^ ANDN32(BCa0, BCe0);
+
+      Eba1 ^= Da1;
+      BCa1 = Eba1;
+      Ege1 ^= De1;
+      BCe1 = ROL32(Ege1, 22);
+      Eki0 ^= Di0;
+      BCi1 = ROL32(Eki0, 21);
+      Emo0 ^= Do0;
+      BCo1 = ROL32(Emo0, 10);
+      Esu1 ^= Du1;
+      BCu1 = ROL32(Esu1, 7);
+      Aba1 = BCa1 ^ ANDN32(BCe1, BCi1);
+      Aba1 ^= *(round_consts++);
+      Abe1 = BCe1 ^ ANDN32(BCi1, BCo1);
+      Abi1 = BCi1 ^ ANDN32(BCo1, BCu1);
+      Abo1 = BCo1 ^ ANDN32(BCu1, BCa1);
+      Abu1 = BCu1 ^ ANDN32(BCa1, BCe1);
+
+      Ebo0 ^= Do0;
+      BCa0 = ROL32(Ebo0, 14);
+      Egu0 ^= Du0;
+      BCe0 = ROL32(Egu0, 10);
+      Eka1 ^= Da1;
+      BCi0 = ROL32(Eka1, 2);
+      Eme1 ^= De1;
+      BCo0 = ROL32(Eme1, 23);
+      Esi1 ^= Di1;
+      BCu0 = ROL32(Esi1, 31);
+      Aga0 = BCa0 ^ ANDN32(BCe0, BCi0);
+      Age0 = BCe0 ^ ANDN32(BCi0, BCo0);
+      Agi0 = BCi0 ^ ANDN32(BCo0, BCu0);
+      Ago0 = BCo0 ^ ANDN32(BCu0, BCa0);
+      Agu0 = BCu0 ^ ANDN32(BCa0, BCe0);
+
+      Ebo1 ^= Do1;
+      BCa1 = ROL32(Ebo1, 14);
+      Egu1 ^= Du1;
+      BCe1 = ROL32(Egu1, 10);
+      Eka0 ^= Da0;
+      BCi1 = ROL32(Eka0, 1);
+      Eme0 ^= De0;
+      BCo1 = ROL32(Eme0, 22);
+      Esi0 ^= Di0;
+      BCu1 = ROL32(Esi0, 30);
+      Aga1 = BCa1 ^ ANDN32(BCe1, BCi1);
+      Age1 = BCe1 ^ ANDN32(BCi1, BCo1);
+      Agi1 = BCi1 ^ ANDN32(BCo1, BCu1);
+      Ago1 = BCo1 ^ ANDN32(BCu1, BCa1);
+      Agu1 = BCu1 ^ ANDN32(BCa1, BCe1);
+
+      Ebe1 ^= De1;
+      BCa0 = ROL32(Ebe1, 1);
+      Egi0 ^= Di0;
+      BCe0 = ROL32(Egi0, 3);
+      Eko1 ^= Do1;
+      BCi0 = ROL32(Eko1, 13);
+      Emu0 ^= Du0;
+      BCo0 = ROL32(Emu0, 4);
+      Esa0 ^= Da0;
+      BCu0 = ROL32(Esa0, 9);
+      Aka0 = BCa0 ^ ANDN32(BCe0, BCi0);
+      Ake0 = BCe0 ^ ANDN32(BCi0, BCo0);
+      Aki0 = BCi0 ^ ANDN32(BCo0, BCu0);
+      Ako0 = BCo0 ^ ANDN32(BCu0, BCa0);
+      Aku0 = BCu0 ^ ANDN32(BCa0, BCe0);
+
+      Ebe0 ^= De0;
+      BCa1 = Ebe0;
+      Egi1 ^= Di1;
+      BCe1 = ROL32(Egi1, 3);
+      Eko0 ^= Do0;
+      BCi1 = ROL32(Eko0, 12);
+      Emu1 ^= Du1;
+      BCo1 = ROL32(Emu1, 4);
+      Esa1 ^= Da1;
+      BCu1 = ROL32(Esa1, 9);
+      Aka1 = BCa1 ^ ANDN32(BCe1, BCi1);
+      Ake1 = BCe1 ^ ANDN32(BCi1, BCo1);
+      Aki1 = BCi1 ^ ANDN32(BCo1, BCu1);
+      Ako1 = BCo1 ^ ANDN32(BCu1, BCa1);
+      Aku1 = BCu1 ^ ANDN32(BCa1, BCe1);
+
+      Ebu1 ^= Du1;
+      BCa0 = ROL32(Ebu1, 14);
+      Ega0 ^= Da0;
+      BCe0 = ROL32(Ega0, 18);
+      Eke0 ^= De0;
+      BCi0 = ROL32(Eke0, 5);
+      Emi1 ^= Di1;
+      BCo0 = ROL32(Emi1, 8);
+      Eso0 ^= Do0;
+      BCu0 = ROL32(Eso0, 28);
+      Ama0 = BCa0 ^ ANDN32(BCe0, BCi0);
+      Ame0 = BCe0 ^ ANDN32(BCi0, BCo0);
+      Ami0 = BCi0 ^ ANDN32(BCo0, BCu0);
+      Amo0 = BCo0 ^ ANDN32(BCu0, BCa0);
+      Amu0 = BCu0 ^ ANDN32(BCa0, BCe0);
+
+      Ebu0 ^= Du0;
+      BCa1 = ROL32(Ebu0, 13);
+      Ega1 ^= Da1;
+      BCe1 = ROL32(Ega1, 18);
+      Eke1 ^= De1;
+      BCi1 = ROL32(Eke1, 5);
+      Emi0 ^= Di0;
+      BCo1 = ROL32(Emi0, 7);
+      Eso1 ^= Do1;
+      BCu1 = ROL32(Eso1, 28);
+      Ama1 = BCa1 ^ ANDN32(BCe1, BCi1);
+      Ame1 = BCe1 ^ ANDN32(BCi1, BCo1);
+      Ami1 = BCi1 ^ ANDN32(BCo1, BCu1);
+      Amo1 = BCo1 ^ ANDN32(BCu1, BCa1);
+      Amu1 = BCu1 ^ ANDN32(BCa1, BCe1);
+
+      Ebi0 ^= Di0;
+      BCa0 = ROL32(Ebi0, 31);
+      Ego1 ^= Do1;
+      BCe0 = ROL32(Ego1, 28);
+      Eku1 ^= Du1;
+      BCi0 = ROL32(Eku1, 20);
+      Ema1 ^= Da1;
+      BCo0 = ROL32(Ema1, 21);
+      Ese0 ^= De0;
+      BCu0 = ROL32(Ese0, 1);
+      Asa0 = BCa0 ^ ANDN32(BCe0, BCi0);
+      Ase0 = BCe0 ^ ANDN32(BCi0, BCo0);
+      Asi0 = BCi0 ^ ANDN32(BCo0, BCu0);
+      Aso0 = BCo0 ^ ANDN32(BCu0, BCa0);
+      Asu0 = BCu0 ^ ANDN32(BCa0, BCe0);
+
+      Ebi1 ^= Di1;
+      BCa1 = ROL32(Ebi1, 31);
+      Ego0 ^= Do0;
+      BCe1 = ROL32(Ego0, 27);
+      Eku0 ^= Du0;
+      BCi1 = ROL32(Eku0, 19);
+      Ema0 ^= Da0;
+      BCo1 = ROL32(Ema0, 20);
+      Ese1 ^= De1;
+      BCu1 = ROL32(Ese1, 1);
+      Asa1 = BCa1 ^ ANDN32(BCe1, BCi1);
+      Ase1 = BCe1 ^ ANDN32(BCi1, BCo1);
+      Asi1 = BCi1 ^ ANDN32(BCo1, BCu1);
+      Aso1 = BCo1 ^ ANDN32(BCu1, BCa1);
+      Asu1 = BCu1 ^ ANDN32(BCa1, BCe1);
+    }
+  while (round_consts < round_consts_end);
+
+  state[0] = Aba0;
+  state[1] = Aba1;
+  state[2] = Abe0;
+  state[3] = Abe1;
+  state[4] = Abi0;
+  state[5] = Abi1;
+  state[6] = Abo0;
+  state[7] = Abo1;
+  state[8] = Abu0;
+  state[9] = Abu1;
+  state[10] = Aga0;
+  state[11] = Aga1;
+  state[12] = Age0;
+  state[13] = Age1;
+  state[14] = Agi0;
+  state[15] = Agi1;
+  state[16] = Ago0;
+  state[17] = Ago1;
+  state[18] = Agu0;
+  state[19] = Agu1;
+  state[20] = Aka0;
+  state[21] = Aka1;
+  state[22] = Ake0;
+  state[23] = Ake1;
+  state[24] = Aki0;
+  state[25] = Aki1;
+  state[26] = Ako0;
+  state[27] = Ako1;
+  state[28] = Aku0;
+  state[29] = Aku1;
+  state[30] = Ama0;
+  state[31] = Ama1;
+  state[32] = Ame0;
+  state[33] = Ame1;
+  state[34] = Ami0;
+  state[35] = Ami1;
+  state[36] = Amo0;
+  state[37] = Amo1;
+  state[38] = Amu0;
+  state[39] = Amu1;
+  state[40] = Asa0;
+  state[41] = Asa1;
+  state[42] = Ase0;
+  state[43] = Ase1;
+  state[44] = Asi0;
+  state[45] = Asi1;
+  state[46] = Aso0;
+  state[47] = Aso1;
+  state[48] = Asu0;
+  state[49] = Asu1;
+
+  return sizeof(void *) * 4 + sizeof(u32) * 12 * 5 * 2;
+}
diff --git a/cipher/keccak_permute_64.h b/cipher/keccak_permute_64.h
new file mode 100644 (file)
index 0000000..b28c871
--- /dev/null
@@ -0,0 +1,385 @@
+/* keccak_permute_64.h - Keccak permute function (simple 64bit)
+ * Copyright (C) 2015 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* The code is based on public-domain/CC0 "keccakc1024/simple/Keccak-simple.c"
+ * implementation by Ronny Van Keer from SUPERCOP toolkit package.
+ */
+
+/* Function that computes the Keccak-f[1600] permutation on the given state. */
+static unsigned int
+KECCAK_F1600_PERMUTE_FUNC_NAME(KECCAK_STATE *hd)
+{
+  const u64 *round_consts = _gcry_keccak_round_consts_64bit;
+  const u64 *round_consts_end = _gcry_keccak_round_consts_64bit + 24;
+  u64 Aba, Abe, Abi, Abo, Abu;
+  u64 Aga, Age, Agi, Ago, Agu;
+  u64 Aka, Ake, Aki, Ako, Aku;
+  u64 Ama, Ame, Ami, Amo, Amu;
+  u64 Asa, Ase, Asi, Aso, Asu;
+  u64 BCa, BCe, BCi, BCo, BCu;
+  u64 Da, De, Di, Do, Du;
+  u64 Eba, Ebe, Ebi, Ebo, Ebu;
+  u64 Ega, Ege, Egi, Ego, Egu;
+  u64 Eka, Eke, Eki, Eko, Eku;
+  u64 Ema, Eme, Emi, Emo, Emu;
+  u64 Esa, Ese, Esi, Eso, Esu;
+  u64 *state = hd->u.state64;
+
+  Aba = state[0];
+  Abe = state[1];
+  Abi = state[2];
+  Abo = state[3];
+  Abu = state[4];
+  Aga = state[5];
+  Age = state[6];
+  Agi = state[7];
+  Ago = state[8];
+  Agu = state[9];
+  Aka = state[10];
+  Ake = state[11];
+  Aki = state[12];
+  Ako = state[13];
+  Aku = state[14];
+  Ama = state[15];
+  Ame = state[16];
+  Ami = state[17];
+  Amo = state[18];
+  Amu = state[19];
+  Asa = state[20];
+  Ase = state[21];
+  Asi = state[22];
+  Aso = state[23];
+  Asu = state[24];
+
+  do
+    {
+      /* prepareTheta */
+      BCa = Aba ^ Aga ^ Aka ^ Ama ^ Asa;
+      BCe = Abe ^ Age ^ Ake ^ Ame ^ Ase;
+      BCi = Abi ^ Agi ^ Aki ^ Ami ^ Asi;
+      BCo = Abo ^ Ago ^ Ako ^ Amo ^ Aso;
+      BCu = Abu ^ Agu ^ Aku ^ Amu ^ Asu;
+
+      /* thetaRhoPiChiIotaPrepareTheta(round  , A, E) */
+      Da = BCu ^ ROL64(BCe, 1);
+      De = BCa ^ ROL64(BCi, 1);
+      Di = BCe ^ ROL64(BCo, 1);
+      Do = BCi ^ ROL64(BCu, 1);
+      Du = BCo ^ ROL64(BCa, 1);
+
+      Aba ^= Da;
+      BCa = Aba;
+      Age ^= De;
+      BCe = ROL64(Age, 44);
+      Aki ^= Di;
+      BCi = ROL64(Aki, 43);
+      Amo ^= Do;
+      BCo = ROL64(Amo, 21);
+      Asu ^= Du;
+      BCu = ROL64(Asu, 14);
+      Eba = BCa ^ ANDN64(BCe, BCi);
+      Eba ^= *(round_consts++);
+      Ebe = BCe ^ ANDN64(BCi, BCo);
+      Ebi = BCi ^ ANDN64(BCo, BCu);
+      Ebo = BCo ^ ANDN64(BCu, BCa);
+      Ebu = BCu ^ ANDN64(BCa, BCe);
+
+      Abo ^= Do;
+      BCa = ROL64(Abo, 28);
+      Agu ^= Du;
+      BCe = ROL64(Agu, 20);
+      Aka ^= Da;
+      BCi = ROL64(Aka, 3);
+      Ame ^= De;
+      BCo = ROL64(Ame, 45);
+      Asi ^= Di;
+      BCu = ROL64(Asi, 61);
+      Ega = BCa ^ ANDN64(BCe, BCi);
+      Ege = BCe ^ ANDN64(BCi, BCo);
+      Egi = BCi ^ ANDN64(BCo, BCu);
+      Ego = BCo ^ ANDN64(BCu, BCa);
+      Egu = BCu ^ ANDN64(BCa, BCe);
+
+      Abe ^= De;
+      BCa = ROL64(Abe, 1);
+      Agi ^= Di;
+      BCe = ROL64(Agi, 6);
+      Ako ^= Do;
+      BCi = ROL64(Ako, 25);
+      Amu ^= Du;
+      BCo = ROL64(Amu, 8);
+      Asa ^= Da;
+      BCu = ROL64(Asa, 18);
+      Eka = BCa ^ ANDN64(BCe, BCi);
+      Eke = BCe ^ ANDN64(BCi, BCo);
+      Eki = BCi ^ ANDN64(BCo, BCu);
+      Eko = BCo ^ ANDN64(BCu, BCa);
+      Eku = BCu ^ ANDN64(BCa, BCe);
+
+      Abu ^= Du;
+      BCa = ROL64(Abu, 27);
+      Aga ^= Da;
+      BCe = ROL64(Aga, 36);
+      Ake ^= De;
+      BCi = ROL64(Ake, 10);
+      Ami ^= Di;
+      BCo = ROL64(Ami, 15);
+      Aso ^= Do;
+      BCu = ROL64(Aso, 56);
+      Ema = BCa ^ ANDN64(BCe, BCi);
+      Eme = BCe ^ ANDN64(BCi, BCo);
+      Emi = BCi ^ ANDN64(BCo, BCu);
+      Emo = BCo ^ ANDN64(BCu, BCa);
+      Emu = BCu ^ ANDN64(BCa, BCe);
+
+      Abi ^= Di;
+      BCa = ROL64(Abi, 62);
+      Ago ^= Do;
+      BCe = ROL64(Ago, 55);
+      Aku ^= Du;
+      BCi = ROL64(Aku, 39);
+      Ama ^= Da;
+      BCo = ROL64(Ama, 41);
+      Ase ^= De;
+      BCu = ROL64(Ase, 2);
+      Esa = BCa ^ ANDN64(BCe, BCi);
+      Ese = BCe ^ ANDN64(BCi, BCo);
+      Esi = BCi ^ ANDN64(BCo, BCu);
+      Eso = BCo ^ ANDN64(BCu, BCa);
+      Esu = BCu ^ ANDN64(BCa, BCe);
+
+      /* prepareTheta */
+      BCa = Eba ^ Ega ^ Eka ^ Ema ^ Esa;
+      BCe = Ebe ^ Ege ^ Eke ^ Eme ^ Ese;
+      BCi = Ebi ^ Egi ^ Eki ^ Emi ^ Esi;
+      BCo = Ebo ^ Ego ^ Eko ^ Emo ^ Eso;
+      BCu = Ebu ^ Egu ^ Eku ^ Emu ^ Esu;
+
+      /* thetaRhoPiChiIotaPrepareTheta(round+1, E, A) */
+      Da = BCu ^ ROL64(BCe, 1);
+      De = BCa ^ ROL64(BCi, 1);
+      Di = BCe ^ ROL64(BCo, 1);
+      Do = BCi ^ ROL64(BCu, 1);
+      Du = BCo ^ ROL64(BCa, 1);
+
+      Eba ^= Da;
+      BCa = Eba;
+      Ege ^= De;
+      BCe = ROL64(Ege, 44);
+      Eki ^= Di;
+      BCi = ROL64(Eki, 43);
+      Emo ^= Do;
+      BCo = ROL64(Emo, 21);
+      Esu ^= Du;
+      BCu = ROL64(Esu, 14);
+      Aba = BCa ^ ANDN64(BCe, BCi);
+      Aba ^= *(round_consts++);
+      Abe = BCe ^ ANDN64(BCi, BCo);
+      Abi = BCi ^ ANDN64(BCo, BCu);
+      Abo = BCo ^ ANDN64(BCu, BCa);
+      Abu = BCu ^ ANDN64(BCa, BCe);
+
+      Ebo ^= Do;
+      BCa = ROL64(Ebo, 28);
+      Egu ^= Du;
+      BCe = ROL64(Egu, 20);
+      Eka ^= Da;
+      BCi = ROL64(Eka, 3);
+      Eme ^= De;
+      BCo = ROL64(Eme, 45);
+      Esi ^= Di;
+      BCu = ROL64(Esi, 61);
+      Aga = BCa ^ ANDN64(BCe, BCi);
+      Age = BCe ^ ANDN64(BCi, BCo);
+      Agi = BCi ^ ANDN64(BCo, BCu);
+      Ago = BCo ^ ANDN64(BCu, BCa);
+      Agu = BCu ^ ANDN64(BCa, BCe);
+
+      Ebe ^= De;
+      BCa = ROL64(Ebe, 1);
+      Egi ^= Di;
+      BCe = ROL64(Egi, 6);
+      Eko ^= Do;
+      BCi = ROL64(Eko, 25);
+      Emu ^= Du;
+      BCo = ROL64(Emu, 8);
+      Esa ^= Da;
+      BCu = ROL64(Esa, 18);
+      Aka = BCa ^ ANDN64(BCe, BCi);
+      Ake = BCe ^ ANDN64(BCi, BCo);
+      Aki = BCi ^ ANDN64(BCo, BCu);
+      Ako = BCo ^ ANDN64(BCu, BCa);
+      Aku = BCu ^ ANDN64(BCa, BCe);
+
+      Ebu ^= Du;
+      BCa = ROL64(Ebu, 27);
+      Ega ^= Da;
+      BCe = ROL64(Ega, 36);
+      Eke ^= De;
+      BCi = ROL64(Eke, 10);
+      Emi ^= Di;
+      BCo = ROL64(Emi, 15);
+      Eso ^= Do;
+      BCu = ROL64(Eso, 56);
+      Ama = BCa ^ ANDN64(BCe, BCi);
+      Ame = BCe ^ ANDN64(BCi, BCo);
+      Ami = BCi ^ ANDN64(BCo, BCu);
+      Amo = BCo ^ ANDN64(BCu, BCa);
+      Amu = BCu ^ ANDN64(BCa, BCe);
+
+      Ebi ^= Di;
+      BCa = ROL64(Ebi, 62);
+      Ego ^= Do;
+      BCe = ROL64(Ego, 55);
+      Eku ^= Du;
+      BCi = ROL64(Eku, 39);
+      Ema ^= Da;
+      BCo = ROL64(Ema, 41);
+      Ese ^= De;
+      BCu = ROL64(Ese, 2);
+      Asa = BCa ^ ANDN64(BCe, BCi);
+      Ase = BCe ^ ANDN64(BCi, BCo);
+      Asi = BCi ^ ANDN64(BCo, BCu);
+      Aso = BCo ^ ANDN64(BCu, BCa);
+      Asu = BCu ^ ANDN64(BCa, BCe);
+    }
+  while (round_consts < round_consts_end);
+
+  state[0] = Aba;
+  state[1] = Abe;
+  state[2] = Abi;
+  state[3] = Abo;
+  state[4] = Abu;
+  state[5] = Aga;
+  state[6] = Age;
+  state[7] = Agi;
+  state[8] = Ago;
+  state[9] = Agu;
+  state[10] = Aka;
+  state[11] = Ake;
+  state[12] = Aki;
+  state[13] = Ako;
+  state[14] = Aku;
+  state[15] = Ama;
+  state[16] = Ame;
+  state[17] = Ami;
+  state[18] = Amo;
+  state[19] = Amu;
+  state[20] = Asa;
+  state[21] = Ase;
+  state[22] = Asi;
+  state[23] = Aso;
+  state[24] = Asu;
+
+  return sizeof(void *) * 4 + sizeof(u64) * 12 * 5;
+}
+
+static unsigned int
+KECCAK_F1600_ABSORB_FUNC_NAME(KECCAK_STATE *hd, int pos, const byte *lanes,
+                             unsigned int nlanes, int blocklanes)
+{
+  unsigned int burn = 0;
+
+  while (nlanes)
+    {
+      switch (blocklanes)
+       {
+       case 21:
+         /* SHAKE128 */
+         while (pos == 0 && nlanes >= 21)
+           {
+             nlanes -= 21;
+             absorb_lanes64_8(&hd->u.state64[0], lanes); lanes += 8 * 8;
+             absorb_lanes64_8(&hd->u.state64[8], lanes); lanes += 8 * 8;
+             absorb_lanes64_4(&hd->u.state64[16], lanes); lanes += 8 * 4;
+             absorb_lanes64_1(&hd->u.state64[20], lanes); lanes += 8 * 1;
+
+             burn = KECCAK_F1600_PERMUTE_FUNC_NAME(hd);
+           }
+         break;
+
+       case 18:
+         /* SHA3-224 */
+         while (pos == 0 && nlanes >= 18)
+           {
+             nlanes -= 18;
+             absorb_lanes64_8(&hd->u.state64[0], lanes); lanes += 8 * 8;
+             absorb_lanes64_8(&hd->u.state64[8], lanes); lanes += 8 * 8;
+             absorb_lanes64_2(&hd->u.state64[16], lanes); lanes += 8 * 2;
+
+             burn = KECCAK_F1600_PERMUTE_FUNC_NAME(hd);
+           }
+         break;
+
+       case 17:
+         /* SHA3-256 & SHAKE256 */
+         while (pos == 0 && nlanes >= 17)
+           {
+             nlanes -= 17;
+             absorb_lanes64_8(&hd->u.state64[0], lanes); lanes += 8 * 8;
+             absorb_lanes64_8(&hd->u.state64[8], lanes); lanes += 8 * 8;
+             absorb_lanes64_1(&hd->u.state64[16], lanes); lanes += 8 * 1;
+
+             burn = KECCAK_F1600_PERMUTE_FUNC_NAME(hd);
+           }
+         break;
+
+       case 13:
+         /* SHA3-384 */
+         while (pos == 0 && nlanes >= 13)
+           {
+             nlanes -= 13;
+             absorb_lanes64_8(&hd->u.state64[0], lanes); lanes += 8 * 8;
+             absorb_lanes64_4(&hd->u.state64[8], lanes); lanes += 8 * 4;
+             absorb_lanes64_1(&hd->u.state64[12], lanes); lanes += 8 * 1;
+
+             burn = KECCAK_F1600_PERMUTE_FUNC_NAME(hd);
+           }
+         break;
+
+       case 9:
+         /* SHA3-512 */
+         while (pos == 0 && nlanes >= 9)
+           {
+             nlanes -= 9;
+             absorb_lanes64_8(&hd->u.state64[0], lanes); lanes += 8 * 8;
+             absorb_lanes64_1(&hd->u.state64[8], lanes); lanes += 8 * 1;
+
+             burn = KECCAK_F1600_PERMUTE_FUNC_NAME(hd);
+           }
+         break;
+       }
+
+      while (nlanes)
+       {
+         hd->u.state64[pos] ^= buf_get_le64(lanes);
+         lanes += 8;
+         nlanes--;
+
+         if (++pos == blocklanes)
+           {
+             burn = KECCAK_F1600_PERMUTE_FUNC_NAME(hd);
+             pos = 0;
+             break;
+           }
+       }
+    }
+
+  return burn;
+}
index 69a2f17..e42a764 100644 (file)
@@ -1,5 +1,5 @@
 /* mac-cmac.c  -  CMAC glue for MAC API
- * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
index 18d56b5..9bc86d9 100644 (file)
@@ -1,5 +1,5 @@
 /* mac-gmac.c  -  GMAC glue for MAC API
- * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
index 15c613d..9379f4b 100644 (file)
@@ -1,5 +1,5 @@
 /* mac-hmac.c  -  HMAC glue for MAC API
- * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
@@ -35,6 +35,8 @@ map_mac_algo_to_md (int mac_algo)
     {
     default:
       return GCRY_MD_NONE;
+    case GCRY_MAC_HMAC_MD2:
+      return GCRY_MD_MD2;
     case GCRY_MAC_HMAC_MD4:
       return GCRY_MD_MD4;
     case GCRY_MAC_HMAC_MD5:
@@ -49,6 +51,14 @@ map_mac_algo_to_md (int mac_algo)
       return GCRY_MD_SHA384;
     case GCRY_MAC_HMAC_SHA512:
       return GCRY_MD_SHA512;
+    case GCRY_MAC_HMAC_SHA3_224:
+      return GCRY_MD_SHA3_224;
+    case GCRY_MAC_HMAC_SHA3_256:
+      return GCRY_MD_SHA3_256;
+    case GCRY_MAC_HMAC_SHA3_384:
+      return GCRY_MD_SHA3_384;
+    case GCRY_MAC_HMAC_SHA3_512:
+      return GCRY_MD_SHA3_512;
     case GCRY_MAC_HMAC_RMD160:
       return GCRY_MD_RMD160;
     case GCRY_MAC_HMAC_TIGER1:
@@ -170,6 +180,14 @@ hmac_get_keylen (int algo)
   /* Return blocksize for default key length. */
   switch (algo)
     {
+    case GCRY_MD_SHA3_224:
+      return 1152 / 8;
+    case GCRY_MD_SHA3_256:
+      return 1088 / 8;
+    case GCRY_MD_SHA3_384:
+      return 832 / 8;
+    case GCRY_MD_SHA3_512:
+      return 576 / 8;
     case GCRY_MAC_HMAC_SHA384:
     case GCRY_MAC_HMAC_SHA512:
       return 128;
@@ -223,6 +241,27 @@ gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha384 = {
   &hmac_ops
 };
 #endif
+#if USE_SHA3
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha3_224 = {
+  GCRY_MAC_HMAC_SHA3_224, {0, 1}, "HMAC_SHA3_224",
+  &hmac_ops
+};
+
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha3_256 = {
+  GCRY_MAC_HMAC_SHA3_256, {0, 1}, "HMAC_SHA3_256",
+  &hmac_ops
+};
+
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha3_384 = {
+  GCRY_MAC_HMAC_SHA3_384, {0, 1}, "HMAC_SHA3_384",
+  &hmac_ops
+};
+
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha3_512 = {
+  GCRY_MAC_HMAC_SHA3_512, {0, 1}, "HMAC_SHA3_512",
+  &hmac_ops
+};
+#endif
 #ifdef USE_GOST_R_3411_94
 gcry_mac_spec_t _gcry_mac_type_spec_hmac_gost3411_94 = {
   GCRY_MAC_HMAC_GOSTR3411_94, {0, 0}, "HMAC_GOSTR3411_94",
@@ -270,3 +309,9 @@ gcry_mac_spec_t _gcry_mac_type_spec_hmac_md4 = {
   &hmac_ops
 };
 #endif
+#if USE_MD2
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_md2 = {
+  GCRY_MAC_HMAC_MD2, {0, 0}, "HMAC_MD2",
+  &hmac_ops
+};
+#endif
index 6fc304b..2beb284 100644 (file)
@@ -1,5 +1,5 @@
 /* mac-internal.h  -  Internal defs for mac.c
- * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <config.h>
+
+#include "g10lib.h"
+
+
 /* The data object used to hold a handle to an encryption object.  */
 struct gcry_mac_handle;
 
+/* The data object used to hold poly1305-mac context.  */
+struct poly1305mac_context_s;
+
 \f
 /*
  *
@@ -84,7 +92,6 @@ typedef struct gcry_mac_spec
 } gcry_mac_spec_t;
 
 
-
 /* The handle structure.  */
 struct gcry_mac_handle
 {
@@ -106,6 +113,9 @@ struct gcry_mac_handle
       gcry_cipher_hd_t ctx;
       int cipher_algo;
     } gmac;
+    struct {
+      struct poly1305mac_context_s *ctx;
+    } poly1305mac;
   } u;
 };
 
@@ -124,6 +134,12 @@ extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha224;
 extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha512;
 extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha384;
 #endif
+#if USE_SHA3
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha3_224;
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha3_256;
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha3_384;
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha3_512;
+#endif
 #ifdef USE_GOST_R_3411_94
 extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_gost3411_94;
 #endif
@@ -202,3 +218,23 @@ extern gcry_mac_spec_t _gcry_mac_type_spec_gmac_seed;
 #if USE_CAMELLIA
 extern gcry_mac_spec_t _gcry_mac_type_spec_gmac_camellia;
 #endif
+
+/*
+ * The Poly1305 MAC algorithm specifications (mac-poly1305.c).
+ */
+extern gcry_mac_spec_t _gcry_mac_type_spec_poly1305mac;
+#if USE_AES
+extern gcry_mac_spec_t _gcry_mac_type_spec_poly1305mac_aes;
+#endif
+#if USE_CAMELLIA
+extern gcry_mac_spec_t _gcry_mac_type_spec_poly1305mac_camellia;
+#endif
+#if USE_TWOFISH
+extern gcry_mac_spec_t _gcry_mac_type_spec_poly1305mac_twofish;
+#endif
+#if USE_SERPENT
+extern gcry_mac_spec_t _gcry_mac_type_spec_poly1305mac_serpent;
+#endif
+#if USE_SEED
+extern gcry_mac_spec_t _gcry_mac_type_spec_poly1305mac_seed;
+#endif
diff --git a/cipher/mac-poly1305.c b/cipher/mac-poly1305.c
new file mode 100644 (file)
index 0000000..b80f87d
--- /dev/null
@@ -0,0 +1,362 @@
+/* mac-poly1305.c  -  Poly1305 based MACs
+ * Copyright (C) 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "mac-internal.h"
+#include "poly1305-internal.h"
+
+
+struct poly1305mac_context_s {
+  poly1305_context_t ctx;
+  gcry_cipher_hd_t hd;
+  struct {
+    unsigned int key_set:1;
+    unsigned int nonce_set:1;
+    unsigned int tag:1;
+  } marks;
+  byte tag[POLY1305_TAGLEN];
+  byte key[POLY1305_KEYLEN];
+};
+
+
+static gcry_err_code_t
+poly1305mac_open (gcry_mac_hd_t h)
+{
+  struct poly1305mac_context_s *mac_ctx;
+  int secure = (h->magic == CTX_MAGIC_SECURE);
+  unsigned int flags = (secure ? GCRY_CIPHER_SECURE : 0);
+  gcry_err_code_t err;
+  int cipher_algo;
+
+  if (secure)
+    mac_ctx = xtrycalloc_secure (1, sizeof(*mac_ctx));
+  else
+    mac_ctx = xtrycalloc (1, sizeof(*mac_ctx));
+
+  if (!mac_ctx)
+    return gpg_err_code_from_syserror ();
+
+  h->u.poly1305mac.ctx = mac_ctx;
+
+  switch (h->spec->algo)
+    {
+    default:
+      /* already checked. */
+    case GCRY_MAC_POLY1305:
+      /* plain Poly1305. */
+      cipher_algo = -1;
+      return 0;
+    case GCRY_MAC_POLY1305_AES:
+      cipher_algo = GCRY_CIPHER_AES;
+      break;
+    case GCRY_MAC_POLY1305_CAMELLIA:
+      cipher_algo = GCRY_CIPHER_CAMELLIA128;
+      break;
+    case GCRY_MAC_POLY1305_TWOFISH:
+      cipher_algo = GCRY_CIPHER_TWOFISH;
+      break;
+    case GCRY_MAC_POLY1305_SERPENT:
+      cipher_algo = GCRY_CIPHER_SERPENT128;
+      break;
+    case GCRY_MAC_POLY1305_SEED:
+      cipher_algo = GCRY_CIPHER_SEED;
+      break;
+    }
+
+  err = _gcry_cipher_open_internal (&mac_ctx->hd, cipher_algo,
+                                   GCRY_CIPHER_MODE_ECB, flags);
+  if (err)
+    goto err_free;
+
+  return 0;
+
+err_free:
+  xfree(h->u.poly1305mac.ctx);
+  return err;
+}
+
+
+static void
+poly1305mac_close (gcry_mac_hd_t h)
+{
+  struct poly1305mac_context_s *mac_ctx = h->u.poly1305mac.ctx;
+
+  if (h->spec->algo != GCRY_MAC_POLY1305)
+    _gcry_cipher_close (mac_ctx->hd);
+
+  xfree(mac_ctx);
+}
+
+
+static gcry_err_code_t
+poly1305mac_prepare_key (gcry_mac_hd_t h, const unsigned char *key, size_t keylen)
+{
+  struct poly1305mac_context_s *mac_ctx = h->u.poly1305mac.ctx;
+  size_t block_keylen = keylen - 16;
+
+  /* Need at least 16 + 1 byte key. */
+  if (keylen <= 16)
+    return GPG_ERR_INV_KEYLEN;
+
+  /* For Poly1305-AES, first part of key is passed to Poly1305 as is. */
+  memcpy (mac_ctx->key, key + block_keylen, 16);
+
+  /* Remaining part is used as key for the block cipher. */
+  return _gcry_cipher_setkey (mac_ctx->hd, key, block_keylen);
+}
+
+
+static gcry_err_code_t
+poly1305mac_setkey (gcry_mac_hd_t h, const unsigned char *key, size_t keylen)
+{
+  struct poly1305mac_context_s *mac_ctx = h->u.poly1305mac.ctx;
+  gcry_err_code_t err;
+
+  memset(&mac_ctx->ctx, 0, sizeof(mac_ctx->ctx));
+  memset(&mac_ctx->tag, 0, sizeof(mac_ctx->tag));
+  memset(&mac_ctx->key, 0, sizeof(mac_ctx->key));
+
+  mac_ctx->marks.key_set = 0;
+  mac_ctx->marks.nonce_set = 0;
+  mac_ctx->marks.tag = 0;
+
+  if (h->spec->algo != GCRY_MAC_POLY1305)
+    {
+      err = poly1305mac_prepare_key (h, key, keylen);
+      if (err)
+        return err;
+
+      /* Poly1305-AES/etc also need nonce. */
+      mac_ctx->marks.key_set = 1;
+      mac_ctx->marks.nonce_set = 0;
+    }
+  else
+    {
+      /* For plain Poly1305, key is the nonce and setup is complete now. */
+
+      if (keylen != POLY1305_KEYLEN)
+        return GPG_ERR_INV_KEYLEN;
+
+      memcpy (mac_ctx->key, key, keylen);
+
+      err = _gcry_poly1305_init (&mac_ctx->ctx, mac_ctx->key, POLY1305_KEYLEN);
+      if (err)
+        {
+          memset(&mac_ctx->key, 0, sizeof(mac_ctx->key));
+          return err;
+        }
+
+      mac_ctx->marks.key_set = 1;
+      mac_ctx->marks.nonce_set = 1;
+    }
+
+  return 0;
+}
+
+
+static gcry_err_code_t
+poly1305mac_setiv (gcry_mac_hd_t h, const unsigned char *iv, size_t ivlen)
+{
+  struct poly1305mac_context_s *mac_ctx = h->u.poly1305mac.ctx;
+  gcry_err_code_t err;
+
+  if (h->spec->algo == GCRY_MAC_POLY1305)
+    return GPG_ERR_INV_ARG;
+
+  if (ivlen != 16)
+    return GPG_ERR_INV_ARG;
+
+  if (!mac_ctx->marks.key_set)
+    return 0;
+
+  memset(&mac_ctx->ctx, 0, sizeof(mac_ctx->ctx));
+  memset(&mac_ctx->tag, 0, sizeof(mac_ctx->tag));
+  mac_ctx->marks.nonce_set = 0;
+  mac_ctx->marks.tag = 0;
+
+  /* Prepare second part of the poly1305 key. */
+
+  err = _gcry_cipher_encrypt (mac_ctx->hd, mac_ctx->key + 16, 16, iv, 16);
+  if (err)
+    return err;
+
+  err = _gcry_poly1305_init (&mac_ctx->ctx, mac_ctx->key, POLY1305_KEYLEN);
+  if (err)
+    return err;
+
+  mac_ctx->marks.nonce_set = 1;
+  return 0;
+}
+
+
+static gcry_err_code_t
+poly1305mac_reset (gcry_mac_hd_t h)
+{
+  struct poly1305mac_context_s *mac_ctx = h->u.poly1305mac.ctx;
+
+  if (!mac_ctx->marks.key_set || !mac_ctx->marks.nonce_set)
+    return GPG_ERR_INV_STATE;
+
+  memset(&mac_ctx->ctx, 0, sizeof(mac_ctx->ctx));
+  memset(&mac_ctx->tag, 0, sizeof(mac_ctx->tag));
+
+  mac_ctx->marks.key_set = 1;
+  mac_ctx->marks.nonce_set = 1;
+  mac_ctx->marks.tag = 0;
+
+  return _gcry_poly1305_init (&mac_ctx->ctx, mac_ctx->key, POLY1305_KEYLEN);
+}
+
+
+static gcry_err_code_t
+poly1305mac_write (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
+{
+  struct poly1305mac_context_s *mac_ctx = h->u.poly1305mac.ctx;
+
+  if (!mac_ctx->marks.key_set || !mac_ctx->marks.nonce_set ||
+      mac_ctx->marks.tag)
+    return GPG_ERR_INV_STATE;
+
+  _gcry_poly1305_update (&mac_ctx->ctx, buf, buflen);
+  return 0;
+}
+
+
+static gcry_err_code_t
+poly1305mac_read (gcry_mac_hd_t h, unsigned char *outbuf, size_t *outlen)
+{
+  struct poly1305mac_context_s *mac_ctx = h->u.poly1305mac.ctx;
+
+  if (!mac_ctx->marks.key_set || !mac_ctx->marks.nonce_set)
+    return GPG_ERR_INV_STATE;
+
+  if (!mac_ctx->marks.tag)
+    {
+      _gcry_poly1305_finish(&mac_ctx->ctx, mac_ctx->tag);
+
+      memset(&mac_ctx->ctx, 0, sizeof(mac_ctx->ctx));
+      mac_ctx->marks.tag = 1;
+    }
+
+  if (*outlen == 0)
+    return 0;
+
+  if (*outlen <= POLY1305_TAGLEN)
+    buf_cpy (outbuf, mac_ctx->tag, *outlen);
+  else
+    {
+      buf_cpy (outbuf, mac_ctx->tag, POLY1305_TAGLEN);
+      *outlen = POLY1305_TAGLEN;
+    }
+
+  return 0;
+}
+
+
+static gcry_err_code_t
+poly1305mac_verify (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
+{
+  struct poly1305mac_context_s *mac_ctx = h->u.poly1305mac.ctx;
+  gcry_err_code_t err;
+  size_t outlen = 0;
+
+  /* Check and finalize tag. */
+  err = poly1305mac_read(h, NULL, &outlen);
+  if (err)
+    return err;
+
+  if (buflen > POLY1305_TAGLEN)
+    return GPG_ERR_INV_LENGTH;
+
+  return buf_eq_const (buf, mac_ctx->tag, buflen) ? 0 : GPG_ERR_CHECKSUM;
+}
+
+
+static unsigned int
+poly1305mac_get_maclen (int algo)
+{
+  (void)algo;
+
+  return POLY1305_TAGLEN;
+}
+
+
+static unsigned int
+poly1305mac_get_keylen (int algo)
+{
+  (void)algo;
+
+  return POLY1305_KEYLEN;
+}
+
+
+static gcry_mac_spec_ops_t poly1305mac_ops = {
+  poly1305mac_open,
+  poly1305mac_close,
+  poly1305mac_setkey,
+  poly1305mac_setiv,
+  poly1305mac_reset,
+  poly1305mac_write,
+  poly1305mac_read,
+  poly1305mac_verify,
+  poly1305mac_get_maclen,
+  poly1305mac_get_keylen
+};
+
+
+gcry_mac_spec_t _gcry_mac_type_spec_poly1305mac = {
+  GCRY_MAC_POLY1305, {0, 0}, "POLY1305",
+  &poly1305mac_ops
+};
+#if USE_AES
+gcry_mac_spec_t _gcry_mac_type_spec_poly1305mac_aes = {
+  GCRY_MAC_POLY1305_AES, {0, 0}, "POLY1305_AES",
+  &poly1305mac_ops
+};
+#endif
+#if USE_CAMELLIA
+gcry_mac_spec_t _gcry_mac_type_spec_poly1305mac_camellia = {
+  GCRY_MAC_POLY1305_CAMELLIA, {0, 0}, "POLY1305_CAMELLIA",
+  &poly1305mac_ops
+};
+#endif
+#if USE_TWOFISH
+gcry_mac_spec_t _gcry_mac_type_spec_poly1305mac_twofish = {
+  GCRY_MAC_POLY1305_TWOFISH, {0, 0}, "POLY1305_TWOFISH",
+  &poly1305mac_ops
+};
+#endif
+#if USE_SERPENT
+gcry_mac_spec_t _gcry_mac_type_spec_poly1305mac_serpent = {
+  GCRY_MAC_POLY1305_SERPENT, {0, 0}, "POLY1305_SERPENT",
+  &poly1305mac_ops
+};
+#endif
+#if USE_SEED
+gcry_mac_spec_t _gcry_mac_type_spec_poly1305mac_seed = {
+  GCRY_MAC_POLY1305_SEED, {0, 0}, "POLY1305_SEED",
+  &poly1305mac_ops
+};
+#endif
index fa36c7d..46be7b7 100644 (file)
@@ -1,5 +1,5 @@
 /* mac.c  -  message authentication code dispatcher
- * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
@@ -41,6 +41,12 @@ static gcry_mac_spec_t *mac_list[] = {
   &_gcry_mac_type_spec_hmac_sha512,
   &_gcry_mac_type_spec_hmac_sha384,
 #endif
+#if USE_SHA3
+  &_gcry_mac_type_spec_hmac_sha3_224,
+  &_gcry_mac_type_spec_hmac_sha3_256,
+  &_gcry_mac_type_spec_hmac_sha3_384,
+  &_gcry_mac_type_spec_hmac_sha3_512,
+#endif
 #ifdef USE_GOST_R_3411_94
   &_gcry_mac_type_spec_hmac_gost3411_94,
 #endif
@@ -75,14 +81,17 @@ static gcry_mac_spec_t *mac_list[] = {
 #if USE_AES
   &_gcry_mac_type_spec_cmac_aes,
   &_gcry_mac_type_spec_gmac_aes,
+  &_gcry_mac_type_spec_poly1305mac_aes,
 #endif
 #if USE_TWOFISH
   &_gcry_mac_type_spec_cmac_twofish,
   &_gcry_mac_type_spec_gmac_twofish,
+  &_gcry_mac_type_spec_poly1305mac_twofish,
 #endif
 #if USE_SERPENT
   &_gcry_mac_type_spec_cmac_serpent,
   &_gcry_mac_type_spec_gmac_serpent,
+  &_gcry_mac_type_spec_poly1305mac_serpent,
 #endif
 #if USE_RFC2268
   &_gcry_mac_type_spec_cmac_rfc2268,
@@ -90,10 +99,12 @@ static gcry_mac_spec_t *mac_list[] = {
 #if USE_SEED
   &_gcry_mac_type_spec_cmac_seed,
   &_gcry_mac_type_spec_gmac_seed,
+  &_gcry_mac_type_spec_poly1305mac_seed,
 #endif
 #if USE_CAMELLIA
   &_gcry_mac_type_spec_cmac_camellia,
   &_gcry_mac_type_spec_gmac_camellia,
+  &_gcry_mac_type_spec_poly1305mac_camellia,
 #endif
 #ifdef USE_IDEA
   &_gcry_mac_type_spec_cmac_idea,
@@ -101,9 +112,27 @@ static gcry_mac_spec_t *mac_list[] = {
 #if USE_GOST28147
   &_gcry_mac_type_spec_cmac_gost28147,
 #endif
+  &_gcry_mac_type_spec_poly1305mac,
   NULL,
 };
 
+/* Explicitly initialize this module.  */
+gcry_err_code_t
+_gcry_mac_init (void)
+{
+  if (fips_mode())
+    {
+      /* disable algorithms that are disallowed in fips */
+      int idx;
+      gcry_mac_spec_t *spec;
+
+      for (idx = 0; (spec = mac_list[idx]); idx++)
+        if (!spec->flags.fips)
+          spec->flags.disabled = 1;
+    }
+
+  return 0;
+}
 
 \f
 /* Return the spec structure for the MAC algorithm ALGO.  For an
@@ -229,7 +258,7 @@ mac_open (gcry_mac_hd_t * hd, int algo, int secure, gcry_ctx_t ctx)
 }
 
 
-static gcry_error_t
+static gcry_err_code_t
 mac_reset (gcry_mac_hd_t hd)
 {
   if (hd->spec->ops->reset)
@@ -251,7 +280,7 @@ mac_close (gcry_mac_hd_t hd)
 }
 
 
-static gcry_error_t
+static gcry_err_code_t
 mac_setkey (gcry_mac_hd_t hd, const void *key, size_t keylen)
 {
   if (!hd->spec->ops->setkey)
@@ -263,7 +292,7 @@ mac_setkey (gcry_mac_hd_t hd, const void *key, size_t keylen)
 }
 
 
-static gcry_error_t
+static gcry_err_code_t
 mac_setiv (gcry_mac_hd_t hd, const void *iv, size_t ivlen)
 {
   if (!hd->spec->ops->setiv)
@@ -275,7 +304,7 @@ mac_setiv (gcry_mac_hd_t hd, const void *iv, size_t ivlen)
 }
 
 
-static gcry_error_t
+static gcry_err_code_t
 mac_write (gcry_mac_hd_t hd, const void *inbuf, size_t inlen)
 {
   if (!hd->spec->ops->write)
@@ -287,7 +316,7 @@ mac_write (gcry_mac_hd_t hd, const void *inbuf, size_t inlen)
 }
 
 
-static gcry_error_t
+static gcry_err_code_t
 mac_read (gcry_mac_hd_t hd, void *outbuf, size_t * outlen)
 {
   if (!outbuf || !outlen || *outlen == 0 || !hd->spec->ops->read)
@@ -297,7 +326,7 @@ mac_read (gcry_mac_hd_t hd, void *outbuf, size_t * outlen)
 }
 
 
-static gcry_error_t
+static gcry_err_code_t
 mac_verify (gcry_mac_hd_t hd, const void *buf, size_t buflen)
 {
   if (!buf || buflen == 0 || !hd->spec->ops->verify)
@@ -330,7 +359,8 @@ _gcry_mac_open (gcry_mac_hd_t * h, int algo, unsigned int flags,
 void
 _gcry_mac_close (gcry_mac_hd_t hd)
 {
-  mac_close (hd);
+  if (hd)
+    mac_close (hd);
 }
 
 
@@ -369,6 +399,13 @@ _gcry_mac_verify (gcry_mac_hd_t hd, const void *buf, size_t buflen)
 }
 
 
+int
+_gcry_mac_get_algo (gcry_mac_hd_t hd)
+{
+  return hd->algo;
+}
+
+
 unsigned int
 _gcry_mac_get_algo_maclen (int algo)
 {
index 008ef5b..d0ef00f 100644 (file)
@@ -27,9 +27,6 @@
 
 #include "g10lib.h"
 #include "cipher.h"
-#include "ath.h"
-
-#include "rmd.h"
 
 
 /* This is the list of the digest implementations included in
@@ -52,8 +49,17 @@ static gcry_md_spec_t *digest_list[] =
      &_gcry_digest_spec_sha512,
      &_gcry_digest_spec_sha384,
 #endif
+#if USE_SHA3
+     &_gcry_digest_spec_sha3_224,
+     &_gcry_digest_spec_sha3_256,
+     &_gcry_digest_spec_sha3_384,
+     &_gcry_digest_spec_sha3_512,
+     &_gcry_digest_spec_shake128,
+     &_gcry_digest_spec_shake256,
+#endif
 #ifdef USE_GOST_R_3411_94
      &_gcry_digest_spec_gost3411_94,
+     &_gcry_digest_spec_gost3411_cp,
 #endif
 #ifdef USE_GOST_R_3411_12
      &_gcry_digest_spec_stribog_256,
@@ -76,6 +82,9 @@ static gcry_md_spec_t *digest_list[] =
 #if USE_MD4
      &_gcry_digest_spec_md4,
 #endif
+#if USE_MD2
+     &_gcry_digest_spec_md2,
+#endif
     NULL
   };
 
@@ -99,10 +108,9 @@ struct gcry_md_context
     unsigned int secure: 1;
     unsigned int finalized:1;
     unsigned int bugemu1:1;
+    unsigned int hmac:1;
   } flags;
   GcryDigestEntry *list;
-  byte *macpads;
-  int macpads_Bsize;             /* Blocksize as used for the HMAC pads. */
 };
 
 
@@ -312,7 +320,7 @@ md_open (gcry_md_hd_t *h, int algo, unsigned int flags)
 
   if (! err)
     {
-      hd->ctx = ctx = (struct gcry_md_context *) ((char *) hd + n);
+      hd->ctx = ctx = (void *) ((char *) hd + n);
       /* Setup the globally visible data (bctl in the diagram).*/
       hd->bufsize = n - sizeof (struct gcry_md_handle) + 1;
       hd->bufpos = 0;
@@ -322,30 +330,8 @@ md_open (gcry_md_hd_t *h, int algo, unsigned int flags)
       ctx->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
       ctx->actual_handle_size = n + sizeof (struct gcry_md_context);
       ctx->flags.secure = secure;
+      ctx->flags.hmac = hmac;
       ctx->flags.bugemu1 = !!(flags & GCRY_MD_FLAG_BUGEMU1);
-
-      if (hmac)
-       {
-         switch (algo)
-            {
-              case GCRY_MD_SHA384:
-              case GCRY_MD_SHA512:
-                ctx->macpads_Bsize = 128;
-                break;
-              case GCRY_MD_GOSTR3411_94:
-                ctx->macpads_Bsize = 32;
-                break;
-              default:
-                ctx->macpads_Bsize = 64;
-                break;
-            }
-          ctx->macpads = xtrymalloc_secure (2*(ctx->macpads_Bsize));
-         if (!ctx->macpads)
-           {
-             err = gpg_err_code_from_errno (errno);
-             md_close (hd);
-           }
-       }
     }
 
   if (! err)
@@ -422,10 +408,16 @@ md_enable (gcry_md_hd_t hd, int algorithm)
         }
     }
 
+  if (!err && h->flags.hmac && spec->read == NULL)
+    {
+      /* Expandable output function cannot act as part of HMAC. */
+      err = GPG_ERR_DIGEST_ALGO;
+    }
+
   if (!err)
     {
       size_t size = (sizeof (*entry)
-                     + spec->contextsize
+                     + spec->contextsize * (h->flags.hmac? 3 : 1)
                      - sizeof (entry->context));
 
       /* And allocate a new list entry. */
@@ -484,7 +476,7 @@ md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd)
 
   if (! err)
     {
-      bhd->ctx = b = (struct gcry_md_context *) ((char *) bhd + n);
+      bhd->ctx = b = (void *) ((char *) bhd + n);
       /* No need to copy the buffer due to the write above. */
       gcry_assert (ahd->bufsize == (n - sizeof (struct gcry_md_handle) + 1));
       bhd->bufsize = ahd->bufsize;
@@ -493,17 +485,6 @@ md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd)
       memcpy (b, a, sizeof *a);
       b->list = NULL;
       b->debug = NULL;
-      if (a->macpads)
-       {
-         b->macpads = xtrymalloc_secure (2*(a->macpads_Bsize));
-         if (! b->macpads)
-           {
-             err = gpg_err_code_from_errno (errno);
-             md_close (bhd);
-           }
-         else
-           memcpy (b->macpads, a->macpads, (2*(a->macpads_Bsize)));
-       }
     }
 
   /* Copy the complete list of algorithms.  The copied list is
@@ -513,13 +494,9 @@ md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd)
       for (ar = a->list; ar; ar = ar->next)
         {
           if (a->flags.secure)
-            br = xtrymalloc_secure (sizeof *br
-                                    + ar->spec->contextsize
-                                    - sizeof(ar->context));
+            br = xtrymalloc_secure (ar->actual_struct_size);
           else
-            br = xtrymalloc (sizeof *br
-                             + ar->spec->contextsize
-                             - sizeof (ar->context));
+            br = xtrymalloc (ar->actual_struct_size);
           if (!br)
             {
              err = gpg_err_code_from_errno (errno);
@@ -527,8 +504,7 @@ md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd)
               break;
             }
 
-          memcpy (br, ar, (sizeof (*br) + ar->spec->contextsize
-                           - sizeof (ar->context)));
+          memcpy (br, ar, ar->actual_struct_size);
           br->next = b->list;
           b->list = br;
         }
@@ -569,14 +545,19 @@ _gcry_md_reset (gcry_md_hd_t a)
 
   a->bufpos = a->ctx->flags.finalized = 0;
 
-  for (r = a->ctx->list; r; r = r->next)
-    {
-      memset (r->context.c, 0, r->spec->contextsize);
-      (*r->spec->init) (&r->context.c,
-                        a->ctx->flags.bugemu1? GCRY_MD_FLAG_BUGEMU1:0);
-    }
-  if (a->ctx->macpads)
-    md_write (a, a->ctx->macpads, a->ctx->macpads_Bsize); /* inner pad */
+  if (a->ctx->flags.hmac)
+    for (r = a->ctx->list; r; r = r->next)
+      {
+        memcpy (r->context.c, r->context.c + r->spec->contextsize,
+                r->spec->contextsize);
+      }
+  else
+    for (r = a->ctx->list; r; r = r->next)
+      {
+        memset (r->context.c, 0, r->spec->contextsize);
+        (*r->spec->init) (&r->context.c,
+                          a->ctx->flags.bugemu1? GCRY_MD_FLAG_BUGEMU1:0);
+      }
 }
 
 
@@ -596,12 +577,6 @@ md_close (gcry_md_hd_t a)
       xfree (r);
     }
 
-  if (a->ctx->macpads)
-    {
-      wipememory (a->ctx->macpads, 2*(a->ctx->macpads_Bsize));
-      xfree(a->ctx->macpads);
-    }
-
   wipememory (a, a->ctx->actual_handle_size);
   xfree(a);
 }
@@ -638,6 +613,9 @@ md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen)
 }
 
 
+/* Note that this function may be used after finalize and read to keep
+   on writing to the transform function so to mitigate timing
+   attacks.  */
 void
 _gcry_md_write (gcry_md_hd_t hd, const void *inbuf, size_t inlen)
 {
@@ -661,66 +639,128 @@ md_final (gcry_md_hd_t a)
 
   a->ctx->flags.finalized = 1;
 
-  if (a->ctx->macpads)
+  if (!a->ctx->flags.hmac)
+    return;
+
+  for (r = a->ctx->list; r; r = r->next)
     {
-      /* Finish the hmac. */
-      int algo = md_get_algo (a);
-      byte *p = md_read (a, algo);
-      size_t dlen = md_digest_length (algo);
-      gcry_md_hd_t om;
+      byte *p;
+      size_t dlen = r->spec->mdlen;
+      byte *hash;
       gcry_err_code_t err;
 
-      err = md_open (&om, algo,
-                     ((a->ctx->flags.secure? GCRY_MD_FLAG_SECURE:0)
-                      | (a->ctx->flags.bugemu1? GCRY_MD_FLAG_BUGEMU1:0)));
-      if (err)
-       _gcry_fatal_error (err, NULL);
-      md_write (om,
-                (a->ctx->macpads)+(a->ctx->macpads_Bsize),
-                a->ctx->macpads_Bsize);
-      md_write (om, p, dlen);
-      md_final (om);
-      /* Replace our digest with the mac (they have the same size). */
-      memcpy (p, md_read (om, algo), dlen);
-      md_close (om);
+      if (r->spec->read == NULL)
+        continue;
+
+      p = r->spec->read (&r->context.c);
+
+      if (a->ctx->flags.secure)
+        hash = xtrymalloc_secure (dlen);
+      else
+        hash = xtrymalloc (dlen);
+      if (!hash)
+        {
+          err = gpg_err_code_from_errno (errno);
+          _gcry_fatal_error (err, NULL);
+        }
+
+      memcpy (hash, p, dlen);
+      memcpy (r->context.c, r->context.c + r->spec->contextsize * 2,
+              r->spec->contextsize);
+      (*r->spec->write) (&r->context.c, hash, dlen);
+      (*r->spec->final) (&r->context.c);
+      xfree (hash);
     }
 }
 
 
 static gcry_err_code_t
-prepare_macpads (gcry_md_hd_t hd, const unsigned char *key, size_t keylen)
+prepare_macpads (gcry_md_hd_t a, const unsigned char *key, size_t keylen)
 {
-  int i;
-  int algo = md_get_algo (hd);
-  unsigned char *helpkey = NULL;
-  unsigned char *ipad, *opad;
+  GcryDigestEntry *r;
 
-  if (!algo)
+  if (!a->ctx->list)
     return GPG_ERR_DIGEST_ALGO; /* Might happen if no algo is enabled.  */
 
-  if ( keylen > hd->ctx->macpads_Bsize )
-    {
-      helpkey = xtrymalloc_secure (md_digest_length (algo));
-      if (!helpkey)
-        return gpg_err_code_from_errno (errno);
-      _gcry_md_hash_buffer (algo, helpkey, key, keylen);
-      key = helpkey;
-      keylen = md_digest_length (algo);
-      gcry_assert ( keylen <= hd->ctx->macpads_Bsize );
-    }
+  if (!a->ctx->flags.hmac)
+    return GPG_ERR_DIGEST_ALGO; /* Tried setkey for non-HMAC md. */
 
-  memset ( hd->ctx->macpads, 0, 2*(hd->ctx->macpads_Bsize) );
-  ipad = hd->ctx->macpads;
-  opad = (hd->ctx->macpads)+(hd->ctx->macpads_Bsize);
-  memcpy ( ipad, key, keylen );
-  memcpy ( opad, key, keylen );
-  for (i=0; i < hd->ctx->macpads_Bsize; i++ )
+  for (r = a->ctx->list; r; r = r->next)
     {
-      ipad[i] ^= 0x36;
-      opad[i] ^= 0x5c;
+      const unsigned char *k;
+      size_t k_len;
+      unsigned char *key_allocated = NULL;
+      int macpad_Bsize;
+      int i;
+
+      switch (r->spec->algo)
+        {
+        case GCRY_MD_SHA3_224:
+          macpad_Bsize = 1152 / 8;
+          break;
+        case GCRY_MD_SHA3_256:
+          macpad_Bsize = 1088 / 8;
+          break;
+        case GCRY_MD_SHA3_384:
+          macpad_Bsize = 832 / 8;
+          break;
+        case GCRY_MD_SHA3_512:
+          macpad_Bsize = 576 / 8;
+          break;
+        case GCRY_MD_SHA384:
+        case GCRY_MD_SHA512:
+          macpad_Bsize = 128;
+          break;
+        case GCRY_MD_GOSTR3411_94:
+        case GCRY_MD_GOSTR3411_CP:
+          macpad_Bsize = 32;
+          break;
+        default:
+          macpad_Bsize = 64;
+          break;
+        }
+
+      if ( keylen > macpad_Bsize )
+        {
+          k = key_allocated = xtrymalloc_secure (r->spec->mdlen);
+          if (!k)
+            return gpg_err_code_from_errno (errno);
+          _gcry_md_hash_buffer (r->spec->algo, key_allocated, key, keylen);
+          k_len = r->spec->mdlen;
+          gcry_assert ( k_len <= macpad_Bsize );
+        }
+      else
+        {
+          k = key;
+          k_len = keylen;
+        }
+
+      (*r->spec->init) (&r->context.c,
+                        a->ctx->flags.bugemu1? GCRY_MD_FLAG_BUGEMU1:0);
+      a->bufpos = 0;
+      for (i=0; i < k_len; i++ )
+        _gcry_md_putc (a, k[i] ^ 0x36);
+      for (; i < macpad_Bsize; i++ )
+        _gcry_md_putc (a, 0x36);
+      (*r->spec->write) (&r->context.c, a->buf, a->bufpos);
+      memcpy (r->context.c + r->spec->contextsize, r->context.c,
+              r->spec->contextsize);
+
+      (*r->spec->init) (&r->context.c,
+                        a->ctx->flags.bugemu1? GCRY_MD_FLAG_BUGEMU1:0);
+      a->bufpos = 0;
+      for (i=0; i < k_len; i++ )
+        _gcry_md_putc (a, k[i] ^ 0x5c);
+      for (; i < macpad_Bsize; i++ )
+        _gcry_md_putc (a, 0x5c);
+      (*r->spec->write) (&r->context.c, a->buf, a->bufpos);
+      memcpy (r->context.c + r->spec->contextsize*2, r->context.c,
+              r->spec->contextsize);
+
+      xfree (key_allocated);
     }
-  xfree (helpkey);
 
+  a->bufpos = 0;
   return 0;
 }
 
@@ -755,14 +795,9 @@ _gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen)
 {
   gcry_err_code_t rc;
 
-  if (!hd->ctx->macpads)
-    rc = GPG_ERR_CONFLICT;
-  else
-    {
-      rc = prepare_macpads (hd, key, keylen);
-      if (!rc)
-       _gcry_md_reset (hd);
-    }
+  rc = prepare_macpads (hd, key, keylen);
+  if (!rc)
+    _gcry_md_reset (hd);
 
   return rc;
 }
@@ -797,6 +832,8 @@ md_read( gcry_md_hd_t a, int algo )
         {
           if (r->next)
             log_debug ("more than one algorithm in md_read(0)\n");
+          if (r->spec->read == NULL)
+            return NULL;
           return r->spec->read (&r->context.c);
         }
     }
@@ -804,7 +841,11 @@ md_read( gcry_md_hd_t a, int algo )
     {
       for (r = a->ctx->list; r; r = r->next)
        if (r->spec->algo == algo)
-         return r->spec->read (&r->context.c);
+         {
+           if (r->spec->read == NULL)
+             return NULL;
+           return r->spec->read (&r->context.c);
+         }
     }
   BUG();
   return NULL;
@@ -826,6 +867,52 @@ _gcry_md_read (gcry_md_hd_t hd, int algo)
 }
 
 
+/****************
+ * If ALGO is null get the digest for the used algo (which should be
+ * only one)
+ */
+static gcry_err_code_t
+md_extract(gcry_md_hd_t a, int algo, void *out, size_t outlen)
+{
+  GcryDigestEntry *r = a->ctx->list;
+
+  if (!algo)
+    {
+      /* Return the first algorithm */
+      if (r && r->spec->extract)
+       {
+         if (r->next)
+           log_debug ("more than one algorithm in md_extract(0)\n");
+         r->spec->extract (&r->context.c, out, outlen);
+         return 0;
+       }
+    }
+  else
+    {
+      for (r = a->ctx->list; r; r = r->next)
+       if (r->spec->algo == algo && r->spec->extract)
+         {
+           r->spec->extract (&r->context.c, out, outlen);
+           return 0;
+         }
+    }
+
+  return GPG_ERR_DIGEST_ALGO;
+}
+
+
+/*
+ * Expand the output from XOF class digest, this function implictly finalizes
+ * the hash.
+ */
+gcry_err_code_t
+_gcry_md_extract (gcry_md_hd_t hd, int algo, void *out, size_t outlen)
+{
+  _gcry_md_ctl (hd, GCRYCTL_FINALIZE, NULL, 0);
+  return md_extract (hd, algo, out, outlen);
+}
+
+
 /*
  * Read out an intermediate digest.  Not yet functional.
  */
@@ -1139,15 +1226,13 @@ md_stop_debug( gcry_md_hd_t md )
       md->ctx->debug = NULL;
     }
 
-#ifdef HAVE_U64_TYPEDEF
   {  /* a kludge to pull in the __muldi3 for Solaris */
-    volatile u32 a = (u32)(ulong)md;
+    volatile u32 a = (u32)(uintptr_t)md;
     volatile u64 b = 42;
     volatile u64 c;
     c = a * b;
     (void)c;
   }
-#endif
 }
 
 
@@ -1207,6 +1292,17 @@ _gcry_md_info (gcry_md_hd_t h, int cmd, void *buffer, size_t *nbytes)
 gcry_err_code_t
 _gcry_md_init (void)
 {
+  if (fips_mode())
+    {
+      /* disable algorithms that are disallowed in fips */
+      int idx;
+      gcry_md_spec_t *spec;
+
+      for (idx = 0; (spec = digest_list[idx]); idx++)
+        if (!spec->flags.fips)
+          spec->flags.disabled = 1;
+    }
+
   return 0;
 }
 
index 624ae99..afa6382 100644 (file)
@@ -66,7 +66,7 @@ typedef struct {
 } MD4_CONTEXT;
 
 static unsigned int
-transform ( void *c, const unsigned char *data );
+transform ( void *c, const unsigned char *data, size_t nblks );
 
 static void
 md4_init (void *context, unsigned int flags)
@@ -96,7 +96,7 @@ md4_init (void *context, unsigned int flags)
  * transform 64 bytes
  */
 static unsigned int
-transform ( void *c, const unsigned char *data )
+transform_blk ( void *c, const unsigned char *data )
 {
   MD4_CONTEXT *ctx = c;
   u32 in[16];
@@ -183,6 +183,21 @@ transform ( void *c, const unsigned char *data )
 }
 
 
+static unsigned int
+transform ( void *c, const unsigned char *data, size_t nblks )
+{
+  unsigned int burn;
+
+  do
+    {
+      burn = transform_blk (c, data);
+      data += 64;
+    }
+  while (--nblks);
+
+  return burn;
+}
+
 
 /* The routine final terminates the message-digest computation and
  * ends with the desired message digest in mdContext->digest[0...15].
@@ -236,11 +251,11 @@ md4_final( void *context )
   /* append the 64 bit count */
   buf_put_le32(hd->bctx.buf + 56, lsb);
   buf_put_le32(hd->bctx.buf + 60, msb);
-  burn = transform( hd, hd->bctx.buf );
+  burn = transform ( hd, hd->bctx.buf, 1 );
   _gcry_burn_stack (burn);
 
   p = hd->bctx.buf;
-#define X(a) do { *(u32*)p = le_bswap32((*hd).a) ; p += 4; } while(0)
+#define X(a) do { buf_put_le32(p, hd->a); p += 4; } while(0)
   X(A);
   X(B);
   X(C);
@@ -271,6 +286,6 @@ gcry_md_spec_t _gcry_digest_spec_md4 =
   {
     GCRY_MD_MD4, {0, 0},
     "MD4", asn, DIM (asn), oid_spec_md4,16,
-    md4_init, _gcry_md_block_write, md4_final, md4_read,
+    md4_init, _gcry_md_block_write, md4_final, md4_read, NULL,
     sizeof (MD4_CONTEXT)
   };
index b0187c9..ed942cf 100644 (file)
@@ -50,7 +50,7 @@ typedef struct {
 } MD5_CONTEXT;
 
 static unsigned int
-transform ( void *ctx, const unsigned char *data );
+transform ( void *ctx, const unsigned char *data, size_t datalen );
 
 static void
 md5_init( void *context, unsigned int flags)
@@ -83,10 +83,10 @@ md5_init( void *context, unsigned int flags)
 
 
 /****************
- * transform n*64 bytes
+ * transform 64 bytes
  */
 static unsigned int
-transform ( void *c, const unsigned char *data )
+transform_blk ( void *c, const unsigned char *data )
 {
   MD5_CONTEXT *ctx = c;
   u32 correct_words[16];
@@ -207,6 +207,21 @@ transform ( void *c, const unsigned char *data )
 }
 
 
+static unsigned int
+transform ( void *c, const unsigned char *data, size_t nblks )
+{
+  unsigned int burn;
+
+  do
+    {
+      burn = transform_blk (c, data);
+      data += 64;
+    }
+  while (--nblks);
+
+  return burn;
+}
+
 
 /* The routine final terminates the message-digest computation and
  * ends with the desired message digest in mdContext->digest[0...15].
@@ -260,11 +275,11 @@ md5_final( void *context)
   /* append the 64 bit count */
   buf_put_le32(hd->bctx.buf + 56, lsb);
   buf_put_le32(hd->bctx.buf + 60, msb);
-  burn = transform( hd, hd->bctx.buf );
+  burn = transform ( hd, hd->bctx.buf, 1 );
   _gcry_burn_stack (burn);
 
   p = hd->bctx.buf;
-#define X(a) do { *(u32*)p = le_bswap32((*hd).a) ; p += 4; } while(0)
+#define X(a) do { buf_put_le32(p, hd->a); p += 4; } while(0)
   X(A);
   X(B);
   X(C);
@@ -295,8 +310,8 @@ static gcry_md_oid_spec_t oid_spec_md5[] =
 
 gcry_md_spec_t _gcry_digest_spec_md5 =
   {
-    GCRY_MD_MD5, {0, 1},
+    GCRY_MD_MD5, {0, 0},
     "MD5", asn, DIM (asn), oid_spec_md5, 16,
-    md5_init, _gcry_md_block_write, md5_final, md5_read,
+    md5_init, _gcry_md_block_write, md5_final, md5_read, NULL,
     sizeof (MD5_CONTEXT)
   };
diff --git a/cipher/poly1305-armv7-neon.S b/cipher/poly1305-armv7-neon.S
new file mode 100644 (file)
index 0000000..1134e85
--- /dev/null
@@ -0,0 +1,705 @@
+/* poly1305-armv7-neon.S  -  ARMv7/NEON implementation of Poly1305
+ *
+ * Copyright (C) 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Based on public domain implementation by Andrew Moon at
+ *  https://github.com/floodyberry/poly1305-opt
+ */
+
+#include <config.h>
+
+#if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) && \
+    defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \
+    defined(HAVE_GCC_INLINE_ASM_NEON)
+
+.syntax unified
+.fpu neon
+.arm
+
+.text
+
+.p2align 2
+.Lpoly1305_init_constants_neon:
+.long 0x3ffff03
+.long 0x3ffc0ff
+.long 0x3f03fff
+.long 0x00fffff
+
+.globl _gcry_poly1305_armv7_neon_init_ext
+.type  _gcry_poly1305_armv7_neon_init_ext,%function;
+_gcry_poly1305_armv7_neon_init_ext:
+.Lpoly1305_init_ext_neon_local:
+       stmfd sp!, {r4-r11, lr}
+       sub sp, sp, #32
+       mov r14, r2
+       and r2, r2, r2
+       moveq r14, #-1
+       ldmia r1!, {r2-r5}
+       ldr r7, =.Lpoly1305_init_constants_neon
+       mov r6, r2
+       mov r8, r2, lsr #26
+       mov r9, r3, lsr #20
+       mov r10, r4, lsr #14
+       mov r11, r5, lsr #8
+       orr r8, r8, r3, lsl #6
+       orr r9, r9, r4, lsl #12
+       orr r10, r10, r5, lsl #18
+       ldmia r7, {r2-r5}
+       and r2, r2, r8
+       and r3, r3, r9
+       and r4, r4, r10
+       and r5, r5, r11
+       and r6, r6, 0x3ffffff
+       stmia r0!, {r2-r6}
+       eor r8, r8, r8
+       str r8, [sp, #24]
+.Lpoly1305_init_ext_neon_squareloop:
+       ldr r8, [sp, #24]
+       mov r12, #16
+       cmp r8, #2
+       beq .Lpoly1305_init_ext_neon_donesquaring
+       cmp r8, #1
+       moveq r12, #64
+       cmp r14, r12
+       bls .Lpoly1305_init_ext_neon_donesquaring
+       add r8, #1
+       str r8, [sp, #24]
+       mov r6, r6, lsl #1
+       mov r2, r2, lsl #1
+       umull r7, r8, r3, r3
+       umull r9, r10, r6, r4
+       umlal r7, r8, r6, r5
+       umlal r9, r10, r2, r3
+       add r11, r5, r5, lsl #2
+       umlal r7, r8, r2, r4
+       umlal r9, r10, r5, r11
+       str r7, [sp, #16]
+       str r8, [sp, #20]
+       mov r2, r2, lsr #1
+       mov r5, r5, lsl #1
+       str r9, [sp, #8]
+       str r10, [sp, #12]
+       umull r7, r8, r2, r2
+       umull r9, r10, r6, r2
+       add r11, r3, r3, lsl #2
+       add r12, r4, r4, lsl #2
+       umlal r7, r8, r6, r3
+       umlal r9, r10, r5, r11
+       umlal r7, r8, r5, r12
+       umlal r9, r10, r4, r12
+       mov r6, r6, lsr #1
+       mov r3, r3, lsl #1
+       add r11, r2, r2, lsl #2
+       str r7, [sp, #0]
+       str r8, [sp, #4]
+       umull r7, r8, r6, r6
+       umlal r7, r8, r3, r12
+       umlal r7, r8, r5, r11
+       and r6, r7, 0x3ffffff
+       mov r11, r7, lsr #26
+       orr r11, r11, r8, lsl #6
+       ldr r7, [sp, #0]
+       ldr r8, [sp, #4]
+       adds r9, r9, r11
+       adc r10, r10, #0
+       and r2, r9, 0x3ffffff
+       mov r11, r9, lsr #26
+       orr r11, r11, r10, lsl #6
+       ldr r9, [sp, #8]
+       ldr r10, [sp, #12]
+       adds r7, r7, r11
+       adc r8, r8, #0
+       and r3, r7, 0x3ffffff
+       mov r11, r7, lsr #26
+       orr r11, r11, r8, lsl #6
+       ldr r7, [sp, #16]
+       ldr r8, [sp, #20]
+       adds r9, r9, r11
+       adc r10, r10, #0
+       and r4, r9, 0x3ffffff
+       mov r11, r9, lsr #26
+       orr r11, r11, r10, lsl #6
+       adds r7, r7, r11
+       adc r8, r8, #0
+       and r5, r7, 0x3ffffff
+       mov r11, r7, lsr #26
+       orr r11, r11, r8, lsl #6
+       add r11, r11, r11, lsl #2
+       add r6, r6, r11
+       mov r11, r6, lsr #26
+       and r6, r6, 0x3ffffff
+       add r2, r2, r11
+       stmia r0!, {r2-r6}
+       b .Lpoly1305_init_ext_neon_squareloop
+.Lpoly1305_init_ext_neon_donesquaring:
+       mov r2, #2
+       ldr r14, [sp, #24]
+       sub r14, r2, r14
+       mov r3, r14, lsl #4
+       add r3, r3, r14, lsl #2
+       add r0, r0, r3
+       eor r2, r2, r2
+       eor r3, r3, r3
+       eor r4, r4, r4
+       eor r5, r5, r5
+       eor r6, r6, r6
+       stmia r0!, {r2-r6}
+       stmia r0!, {r2-r6}
+       ldmia r1!, {r2-r5}
+       stmia r0, {r2-r6}
+       add sp, sp, #32
+       ldmfd sp!, {r4-r11, lr}
+       mov r0, #(9*4+32)
+       bx lr
+.ltorg
+.size _gcry_poly1305_armv7_neon_init_ext,.-_gcry_poly1305_armv7_neon_init_ext;
+
+.globl _gcry_poly1305_armv7_neon_blocks
+.type  _gcry_poly1305_armv7_neon_blocks,%function;
+_gcry_poly1305_armv7_neon_blocks:
+.Lpoly1305_blocks_neon_local:
+       vmov.i32 q0, #0xffffffff
+       vmov.i32 d4, #1
+       vsubw.u32 q0, q0, d4
+       vstmdb sp!, {q4,q5,q6,q7}
+       stmfd sp!, {r4-r11, lr}
+       mov r8, sp
+       and sp, sp, #~63
+       sub sp, sp, #192
+       str r0, [sp, #108]
+       str r1, [sp, #112]
+       str r2, [sp, #116]
+       str r8, [sp, #120]
+       mov r3, r0
+       mov r0, r1
+       mov r1, r2
+       mov r2, r3
+       ldr r8, [r2, #116]
+       veor d15, d15, d15
+       vorr.i32 d15, #(1 << 24)
+       tst r8, #2
+       beq .Lpoly1305_blocks_neon_skip_shift8
+       vshr.u64 d15, #32
+.Lpoly1305_blocks_neon_skip_shift8:
+       tst r8, #4
+       beq .Lpoly1305_blocks_neon_skip_shift16
+       veor d15, d15, d15
+.Lpoly1305_blocks_neon_skip_shift16:
+       vst1.64 d15, [sp, :64]
+       tst r8, #1
+       bne .Lpoly1305_blocks_neon_started
+       vld1.64 {q0-q1}, [r0]!
+       vswp d1, d2
+       vmovn.i64 d21, q0
+       vshrn.i64 d22, q0, #26
+       vshrn.u64 d24, q1, #14
+       vext.8 d0, d0, d2, #4
+       vext.8 d1, d1, d3, #4
+       vshr.u64 q1, q1, #32
+       vshrn.i64 d23, q0, #20
+       vshrn.u64 d25, q1, #8
+       vand.i32 d21, #0x03ffffff
+       vand.i32 q11, #0x03ffffff
+       vand.i32 q12, #0x03ffffff
+       orr r8, r8, #1
+       sub r1, r1, #32
+       str r8, [r2, #116]
+       vorr d25, d25, d15
+       b .Lpoly1305_blocks_neon_setupr20
+.Lpoly1305_blocks_neon_started:
+       add r9, r2, #60
+       vldm r9, {d21-d25}
+.Lpoly1305_blocks_neon_setupr20:
+       vmov.i32 d0, #5
+       tst r8, #(8|16)
+       beq .Lpoly1305_blocks_neon_setupr20_simple
+       tst r8, #(8)
+       beq .Lpoly1305_blocks_neon_setupr20_r_1
+       mov r9, r2
+       add r10, r2, #20
+       vld1.64 {q9}, [r9]!
+       vld1.64 {q8}, [r10]!
+       vld1.64 {d2}, [r9]
+       vld1.64 {d20}, [r10]
+       b .Lpoly1305_blocks_neon_setupr20_hard
+.Lpoly1305_blocks_neon_setupr20_r_1:
+       mov r9, r2
+       vmov.i32 d2, #1
+       vld1.64 {q8}, [r9]!
+       veor q9, q9, q9
+       vshr.u64 d2, d2, #32
+       vld1.64 {d20}, [r9]
+.Lpoly1305_blocks_neon_setupr20_hard:
+       vzip.i32 q8, q9
+       vzip.i32 d20, d2
+       b .Lpoly1305_blocks_neon_setups20
+.Lpoly1305_blocks_neon_setupr20_simple:
+       add r9, r2, #20
+       vld1.64 {d2-d4}, [r9]
+       vdup.32 d16, d2[0]
+       vdup.32 d17, d2[1]
+       vdup.32 d18, d3[0]
+       vdup.32 d19, d3[1]
+       vdup.32 d20, d4[0]
+.Lpoly1305_blocks_neon_setups20:
+       vmul.i32 q13, q8, d0[0]
+       vmov.i64 q15, 0x00000000ffffffff
+       vmul.i32 q14, q9, d0[0]
+       vshr.u64 q15, q15, #6
+       cmp r1, #64
+       blo .Lpoly1305_blocks_neon_try32
+       add r9, sp, #16
+       add r10, r2, #40
+       add r11, sp, #64
+       str r1, [sp, #116]
+       vld1.64 {d10-d12}, [r10]
+       vmov d14, d12
+       vmul.i32 q6, q5, d0[0]
+.Lpoly1305_blocks_neon_mainloop:
+       ldmia r0!, {r2-r5}
+       vmull.u32 q0, d25, d12[0]
+       mov r7, r2, lsr #26
+       vmlal.u32 q0, d24, d12[1]
+       mov r8, r3, lsr #20
+       ldr r6, [sp, #0]
+       vmlal.u32 q0, d23, d13[0]
+       mov r9, r4, lsr #14
+       vmlal.u32 q0, d22, d13[1]
+       orr r6, r6, r5, lsr #8
+       vmlal.u32 q0, d21, d14[0]
+       orr r3, r7, r3, lsl #6
+       vmull.u32 q1, d25, d12[1]
+       orr r4, r8, r4, lsl #12
+       orr r5, r9, r5, lsl #18
+       vmlal.u32 q1, d24, d13[0]
+       ldmia r0!, {r7-r10}
+       vmlal.u32 q1, d23, d13[1]
+       mov r1, r7, lsr #26
+       vmlal.u32 q1, d22, d14[0]
+       ldr r11, [sp, #4]
+       mov r12, r8, lsr #20
+       vmlal.u32 q1, d21, d10[0]
+       mov r14, r9, lsr #14
+       vmull.u32 q2, d25, d13[0]
+       orr r11, r11, r10, lsr #8
+       orr r8, r1, r8, lsl #6
+       vmlal.u32 q2, d24, d13[1]
+       orr r9, r12, r9, lsl #12
+       vmlal.u32 q2, d23, d14[0]
+       orr r10, r14, r10, lsl #18
+       vmlal.u32 q2, d22, d10[0]
+       mov r12, r3
+       and r2, r2, #0x3ffffff
+       vmlal.u32 q2, d21, d10[1]
+       mov r14, r5
+       vmull.u32 q3, d25, d13[1]
+       and r3, r7, #0x3ffffff
+       vmlal.u32 q3, d24, d14[0]
+       and r5, r8, #0x3ffffff
+       vmlal.u32 q3, d23, d10[0]
+       and r7, r9, #0x3ffffff
+       vmlal.u32 q3, d22, d10[1]
+       and r8, r14, #0x3ffffff
+       vmlal.u32 q3, d21, d11[0]
+       and r9, r10, #0x3ffffff
+       add r14, sp, #128
+       vmull.u32 q4, d25, d14[0]
+       mov r10, r6
+       vmlal.u32 q4, d24, d10[0]
+       and r6, r4, #0x3ffffff
+       vmlal.u32 q4, d23, d10[1]
+       and r4, r12, #0x3ffffff
+       vmlal.u32 q4, d22, d11[0]
+       stm r14, {r2-r11}
+       vmlal.u32 q4, d21, d11[1]
+       vld1.64 {d21-d24}, [r14, :256]!
+       vld1.64 {d25}, [r14, :64]
+       ldmia r0!, {r2-r5}
+       vmlal.u32 q0, d25, d26
+       mov r7, r2, lsr #26
+       vmlal.u32 q0, d24, d27
+       ldr r6, [sp, #0]
+       mov r8, r3, lsr #20
+       vmlal.u32 q0, d23, d28
+       mov r9, r4, lsr #14
+       vmlal.u32 q0, d22, d29
+       orr r6, r6, r5, lsr #8
+       vmlal.u32 q0, d21, d20
+       orr r3, r7, r3, lsl #6
+       vmlal.u32 q1, d25, d27
+       orr r4, r8, r4, lsl #12
+       orr r5, r9, r5, lsl #18
+       vmlal.u32 q1, d24, d28
+       ldmia r0!, {r7-r10}
+       vmlal.u32 q1, d23, d29
+       mov r1, r7, lsr #26
+       vmlal.u32 q1, d22, d20
+       ldr r11, [sp, #4]
+       mov r12, r8, lsr #20
+       vmlal.u32 q1, d21, d16
+       mov r14, r9, lsr #14
+       vmlal.u32 q2, d25, d28
+       orr r11, r11, r10, lsr #8
+       orr r8, r1, r8, lsl #6
+       orr r9, r12, r9, lsl #12
+       vmlal.u32 q2, d24, d29
+       orr r10, r14, r10, lsl #18
+       and r2, r2, #0x3ffffff
+       mov r12, r3
+       vmlal.u32 q2, d23, d20
+       mov r14, r5
+       vmlal.u32 q2, d22, d16
+       and r3, r7, #0x3ffffff
+       vmlal.u32 q2, d21, d17
+       and r5, r8, #0x3ffffff
+       vmlal.u32 q3, d25, d29
+       and r7, r9, #0x3ffffff
+       vmlal.u32 q3, d24, d20
+       and r8, r14, #0x3ffffff
+       vmlal.u32 q3, d23, d16
+       and r9, r10, #0x3ffffff
+       vmlal.u32 q3, d22, d17
+       add r14, sp, #128
+       vmlal.u32 q3, d21, d18
+       mov r10, r6
+       vmlal.u32 q4, d25, d20
+       vmlal.u32 q4, d24, d16
+       and r6, r4, #0x3ffffff
+       vmlal.u32 q4, d23, d17
+       and r4, r12, #0x3ffffff
+       vmlal.u32 q4, d22, d18
+       stm r14, {r2-r11}
+       vmlal.u32 q4, d21, d19
+       vld1.64 {d21-d24}, [r14, :256]!
+       vld1.64 {d25}, [r14, :64]
+       vaddw.u32 q0, q0, d21
+       vaddw.u32 q1, q1, d22
+       vaddw.u32 q2, q2, d23
+       vaddw.u32 q3, q3, d24
+       vaddw.u32 q4, q4, d25
+       vshr.u64 q11, q0, #26
+       vand q0, q0, q15
+       vadd.i64 q1, q1, q11
+       vshr.u64 q12, q3, #26
+       vand q3, q3, q15
+       vadd.i64 q4, q4, q12
+       vshr.u64 q11, q1, #26
+       vand q1, q1, q15
+       vadd.i64 q2, q2, q11
+       vshr.u64 q12, q4, #26
+       vand q4, q4, q15
+       vadd.i64 q0, q0, q12
+       vshl.i64 q12, q12, #2
+       ldr r1, [sp, #116]
+       vadd.i64 q0, q0, q12
+       vshr.u64 q11, q2, #26
+       vand q2, q2, q15
+       vadd.i64 q3, q3, q11
+       sub r1, #64
+       vshr.u64 q12, q0, #26
+       vand q0, q0, q15
+       vadd.i64 q1, q1, q12
+       cmp r1, #64
+       vshr.u64 q11, q3, #26
+       vand q3, q3, q15
+       vadd.i64 q4, q4, q11
+       vmovn.i64 d21, q0
+       str r1, [sp, #116]
+       vmovn.i64 d22, q1
+       vmovn.i64 d23, q2
+       vmovn.i64 d24, q3
+       vmovn.i64 d25, q4
+       bhs .Lpoly1305_blocks_neon_mainloop
+.Lpoly1305_blocks_neon_try32:
+       cmp r1, #32
+       blo .Lpoly1305_blocks_neon_done
+       tst r0, r0
+       bne .Lpoly1305_blocks_loadm32
+       veor q0, q0, q0
+       veor q1, q1, q1
+       veor q2, q2, q2
+       veor q3, q3, q3
+       veor q4, q4, q4
+       b .Lpoly1305_blocks_continue32
+.Lpoly1305_blocks_loadm32:
+       vld1.64 {q0-q1}, [r0]!
+       veor q4, q4, q4
+       vswp d1, d2
+       veor q3, q3, q3
+       vtrn.32 q0, q4
+       vtrn.32 q1, q3
+       vshl.i64 q2, q1, #12
+       vshl.i64 q3, q3, #18
+       vshl.i64 q1, q4, #6
+       vmovl.u32 q4, d15
+.Lpoly1305_blocks_continue32:
+       vmlal.u32 q0, d25, d26
+       vmlal.u32 q0, d24, d27
+       vmlal.u32 q0, d23, d28
+       vmlal.u32 q0, d22, d29
+       vmlal.u32 q0, d21, d20
+       vmlal.u32 q1, d25, d27
+       vmlal.u32 q1, d24, d28
+       vmlal.u32 q1, d23, d29
+       vmlal.u32 q1, d22, d20
+       vmlal.u32 q1, d21, d16
+       vmlal.u32 q2, d25, d28
+       vmlal.u32 q2, d24, d29
+       vmlal.u32 q2, d23, d20
+       vmlal.u32 q2, d22, d16
+       vmlal.u32 q2, d21, d17
+       vmlal.u32 q3, d25, d29
+       vmlal.u32 q3, d24, d20
+       vmlal.u32 q3, d23, d16
+       vmlal.u32 q3, d22, d17
+       vmlal.u32 q3, d21, d18
+       vmlal.u32 q4, d25, d20
+       vmlal.u32 q4, d24, d16
+       vmlal.u32 q4, d23, d17
+       vmlal.u32 q4, d22, d18
+       vmlal.u32 q4, d21, d19
+       vshr.u64 q11, q0, #26
+       vand q0, q0, q15
+       vadd.i64 q1, q1, q11
+       vshr.u64 q12, q3, #26
+       vand q3, q3, q15
+       vadd.i64 q4, q4, q12
+       vshr.u64 q11, q1, #26
+       vand q1, q1, q15
+       vadd.i64 q2, q2, q11
+       vshr.u64 q12, q4, #26
+       vand q4, q4, q15
+       vadd.i64 q0, q0, q12
+       vshl.i64 q12, q12, #2
+       vadd.i64 q0, q0, q12
+       vshr.u64 q11, q2, #26
+       vand q2, q2, q15
+       vadd.i64 q3, q3, q11
+       vshr.u64 q12, q0, #26
+       vand q0, q0, q15
+       vadd.i64 q1, q1, q12
+       vshr.u64 q11, q3, #26
+       vand q3, q3, q15
+       vadd.i64 q4, q4, q11
+       vmovn.i64 d21, q0
+       vmovn.i64 d22, q1
+       vmovn.i64 d23, q2
+       vmovn.i64 d24, q3
+       vmovn.i64 d25, q4
+.Lpoly1305_blocks_neon_done:
+       tst r0, r0
+       beq .Lpoly1305_blocks_neon_final
+       ldr r2, [sp, #108]
+       add r2, r2, #60
+       vst1.64 {d21}, [r2]!
+       vst1.64 {d22-d25}, [r2]
+       b .Lpoly1305_blocks_neon_leave
+.Lpoly1305_blocks_neon_final:
+       vadd.u32 d10, d0, d1
+       vadd.u32 d13, d2, d3
+       vadd.u32 d11, d4, d5
+       ldr r5, [sp, #108]
+       vadd.u32 d14, d6, d7
+       vadd.u32 d12, d8, d9
+       vtrn.32 d10, d13
+       vtrn.32 d11, d14
+       vst1.64 {d10-d12}, [sp]
+       ldm sp, {r0-r4}
+       mov r12, r0, lsr #26
+       and r0, r0, #0x3ffffff
+       add r1, r1, r12
+       mov r12, r1, lsr #26
+       and r1, r1, #0x3ffffff
+       add r2, r2, r12
+       mov r12, r2, lsr #26
+       and r2, r2, #0x3ffffff
+       add r3, r3, r12
+       mov r12, r3, lsr #26
+       and r3, r3, #0x3ffffff
+       add r4, r4, r12
+       mov r12, r4, lsr #26
+       and r4, r4, #0x3ffffff
+       add r12, r12, r12, lsl #2
+       add r0, r0, r12
+       mov r12, r0, lsr #26
+       and r0, r0, #0x3ffffff
+       add r1, r1, r12
+       mov r12, r1, lsr #26
+       and r1, r1, #0x3ffffff
+       add r2, r2, r12
+       mov r12, r2, lsr #26
+       and r2, r2, #0x3ffffff
+       add r3, r3, r12
+       mov r12, r3, lsr #26
+       and r3, r3, #0x3ffffff
+       add r4, r4, r12
+       mov r12, r4, lsr #26
+       and r4, r4, #0x3ffffff
+       add r12, r12, r12, lsl #2
+       add r0, r0, r12
+       mov r12, r0, lsr #26
+       and r0, r0, #0x3ffffff
+       add r1, r1, r12
+       add r6, r0, #5
+       mov r12, r6, lsr #26
+       and r6, r6, #0x3ffffff
+       add r7, r1, r12
+       mov r12, r7, lsr #26
+       and r7, r7, #0x3ffffff
+       add r10, r2, r12
+       mov r12, r10, lsr #26
+       and r10, r10, #0x3ffffff
+       add r11, r3, r12
+       mov r12, #-(1 << 26)
+       add r12, r12, r11, lsr #26
+       and r11, r11, #0x3ffffff
+       add r14, r4, r12
+       mov r12, r14, lsr #31
+       sub r12, #1
+       and r6, r6, r12
+       and r7, r7, r12
+       and r10, r10, r12
+       and r11, r11, r12
+       and r14, r14, r12
+       mvn r12, r12
+       and r0, r0, r12
+       and r1, r1, r12
+       and r2, r2, r12
+       and r3, r3, r12
+       and r4, r4, r12
+       orr r0, r0, r6
+       orr r1, r1, r7
+       orr r2, r2, r10
+       orr r3, r3, r11
+       orr r4, r4, r14
+       orr r0, r0, r1, lsl #26
+       lsr r1, r1, #6
+       orr r1, r1, r2, lsl #20
+       lsr r2, r2, #12
+       orr r2, r2, r3, lsl #14
+       lsr r3, r3, #18
+       orr r3, r3, r4, lsl #8
+       add r5, r5, #60
+       stm r5, {r0-r3}
+.Lpoly1305_blocks_neon_leave:
+       sub r0, sp, #8
+       ldr sp, [sp, #120]
+       ldmfd sp!, {r4-r11, lr}
+       vldm sp!, {q4-q7}
+       sub r0, sp, r0
+       bx lr
+.size _gcry_poly1305_armv7_neon_blocks,.-_gcry_poly1305_armv7_neon_blocks;
+
+.globl _gcry_poly1305_armv7_neon_finish_ext
+.type  _gcry_poly1305_armv7_neon_finish_ext,%function;
+_gcry_poly1305_armv7_neon_finish_ext:
+.Lpoly1305_finish_ext_neon_local:
+       stmfd sp!, {r4-r11, lr}
+       sub sp, sp, #32
+       mov r5, r0
+       mov r6, r1
+       mov r7, r2
+       mov r8, r3
+       ands r7, r7, r7
+       beq .Lpoly1305_finish_ext_neon_noremaining
+       mov r9, sp
+       veor q0, q0, q0
+       veor q1, q1, q1
+       vst1.64 {q0-q1}, [sp]
+       tst r7, #16
+       beq .Lpoly1305_finish_ext_neon_skip16
+       vld1.u64 {q0}, [r1]!
+       vst1.64 {q0}, [r9]!
+.Lpoly1305_finish_ext_neon_skip16:
+       tst r7, #8
+       beq .Lpoly1305_finish_ext_neon_skip8
+       ldmia r1!, {r10-r11}
+       stmia r9!, {r10-r11}
+.Lpoly1305_finish_ext_neon_skip8:
+       tst r7, #4
+       beq .Lpoly1305_finish_ext_neon_skip4
+       ldr r10, [r1], #4
+       str r10, [r9], #4
+.Lpoly1305_finish_ext_neon_skip4:
+       tst r7, #2
+       beq .Lpoly1305_finish_ext_neon_skip2
+       ldrh r10, [r1], #2
+       strh r10, [r9], #2
+.Lpoly1305_finish_ext_neon_skip2:
+       tst r7, #1
+       beq .Lpoly1305_finish_ext_neon_skip1
+       ldrb r10, [r1], #1
+       strb r10, [r9], #1
+.Lpoly1305_finish_ext_neon_skip1:
+       cmp r7, #16
+       beq .Lpoly1305_finish_ext_neon_skipfinalbit
+       mov r10, #1
+       strb r10, [r9]
+.Lpoly1305_finish_ext_neon_skipfinalbit:
+       ldr r10, [r5, #116]
+       orrhs r10, #2
+       orrlo r10, #4
+       str r10, [r5, #116]
+       mov r0, r5
+       mov r1, sp
+       mov r2, #32
+       bl .Lpoly1305_blocks_neon_local
+.Lpoly1305_finish_ext_neon_noremaining:
+       ldr r10, [r5, #116]
+       tst r10, #1
+       beq .Lpoly1305_finish_ext_neon_notstarted
+       cmp r7, #0
+       beq .Lpoly1305_finish_ext_neon_user2r
+       cmp r7, #16
+       bls .Lpoly1305_finish_ext_neon_user1
+.Lpoly1305_finish_ext_neon_user2r:
+       orr r10, r10, #8
+       b .Lpoly1305_finish_ext_neon_finalblock
+.Lpoly1305_finish_ext_neon_user1:
+       orr r10, r10, #16
+.Lpoly1305_finish_ext_neon_finalblock:
+       str r10, [r5, #116]
+       mov r0, r5
+       eor r1, r1, r1
+       mov r2, #32
+       bl .Lpoly1305_blocks_neon_local
+.Lpoly1305_finish_ext_neon_notstarted:
+       add r0, r5, #60
+       add r9, r5, #100
+       ldm r0, {r0-r3}
+       ldm r9, {r9-r12}
+       adds r0, r0, r9
+       adcs r1, r1, r10
+       adcs r2, r2, r11
+       adcs r3, r3, r12
+       stm r8, {r0-r3}
+       veor q0, q0, q0
+       veor q1, q1, q1
+       veor q2, q2, q2
+       veor q3, q3, q3
+       vstmia r5!, {q0-q3}
+       vstm r5, {q0-q3}
+       add sp, sp, #32
+       ldmfd sp!, {r4-r11, lr}
+       mov r0, #(9*4+32)
+       bx lr
+.size _gcry_poly1305_armv7_neon_finish_ext,.-_gcry_poly1305_armv7_neon_finish_ext;
+
+#endif
diff --git a/cipher/poly1305-avx2-amd64.S b/cipher/poly1305-avx2-amd64.S
new file mode 100644 (file)
index 0000000..9362a5a
--- /dev/null
@@ -0,0 +1,962 @@
+/* poly1305-avx2-amd64.S  -  AMD64/AVX2 implementation of Poly1305
+ *
+ * Copyright (C) 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Based on public domain implementation by Andrew Moon at
+ *  https://github.com/floodyberry/poly1305-opt
+ */
+
+#include <config.h>
+
+#if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+    defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
+    defined(ENABLE_AVX2_SUPPORT)
+
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
+
+
+.text
+
+
+.align 8
+.globl _gcry_poly1305_amd64_avx2_init_ext
+ELF(.type  _gcry_poly1305_amd64_avx2_init_ext,@function;)
+_gcry_poly1305_amd64_avx2_init_ext:
+.Lpoly1305_init_ext_avx2_local:
+       xor %edx, %edx
+       vzeroupper
+       pushq %r12
+       pushq %r13
+       pushq %r14
+       pushq %r15
+       pushq %rbx
+       movq %rdx, %rcx
+       vpxor %ymm0, %ymm0, %ymm0
+       movq $-1, %r8
+       testq %rcx, %rcx
+       vmovdqu %ymm0, (%rdi)
+       vmovdqu %ymm0, 32(%rdi)
+       vmovdqu %ymm0, 64(%rdi)
+       vmovdqu %ymm0, 96(%rdi)
+       vmovdqu %ymm0, 128(%rdi)
+       movq 8(%rsi), %r9
+       cmove %r8, %rcx
+       movq $0xffc0fffffff, %r8
+       movq %r9, %r13
+       movq (%rsi), %r10
+       andq %r10, %r8
+       shrq $44, %r10
+       movq %r8, %r14
+       shlq $20, %r13
+       orq %r13, %r10
+       movq $0xfffffc0ffff, %r13
+       shrq $24, %r9
+       andq %r13, %r10
+       movq $0xffffffc0f, %r13
+       andq %r13, %r9
+       movl %r8d, %r13d
+       andl $67108863, %r13d
+       movl %r13d, 164(%rdi)
+       movq %r10, %r13
+       shrq $26, %r14
+       shlq $18, %r13
+       orq %r13, %r14
+       movq %r10, %r13
+       shrq $8, %r13
+       andl $67108863, %r14d
+       andl $67108863, %r13d
+       movl %r14d, 172(%rdi)
+       movq %r10, %r14
+       movl %r13d, 180(%rdi)
+       movq %r9, %r13
+       shrq $34, %r14
+       shlq $10, %r13
+       orq %r13, %r14
+       movq %r9, %r13
+       shrq $16, %r13
+       andl $67108863, %r14d
+       movl %r14d, 188(%rdi)
+       movl %r13d, 196(%rdi)
+       cmpq $16, %rcx
+       jbe .Lpoly1305_init_ext_avx2_continue
+       lea (%r9,%r9,4), %r11
+       shlq $2, %r11
+       lea (%r10,%r10), %rax
+       mulq %r11
+       movq %rax, %r13
+       movq %r8, %rax
+       movq %rdx, %r14
+       mulq %r8
+       addq %rax, %r13
+       lea (%r8,%r8), %rax
+       movq %r13, %r12
+       adcq %rdx, %r14
+       mulq %r10
+       shlq $20, %r14
+       movq %rax, %r15
+       shrq $44, %r12
+       movq %r11, %rax
+       orq %r12, %r14
+       movq %rdx, %r12
+       mulq %r9
+       addq %rax, %r15
+       movq %r8, %rax
+       adcq %rdx, %r12
+       addq %r15, %r14
+       lea (%r9,%r9), %r15
+       movq %r14, %rbx
+       adcq $0, %r12
+       mulq %r15
+       shlq $20, %r12
+       movq %rdx, %r11
+       shrq $44, %rbx
+       orq %rbx, %r12
+       movq %rax, %rbx
+       movq %r10, %rax
+       mulq %r10
+       addq %rax, %rbx
+       adcq %rdx, %r11
+       addq %rbx, %r12
+       movq $0xfffffffffff, %rbx
+       movq %r12, %r15
+       adcq $0, %r11
+       andq %rbx, %r13
+       shlq $22, %r11
+       andq %rbx, %r14
+       shrq $42, %r15
+       orq %r15, %r11
+       lea (%r11,%r11,4), %r11
+       addq %r11, %r13
+       movq %rbx, %r11
+       andq %r13, %r11
+       shrq $44, %r13
+       movq %r11, %r15
+       addq %r13, %r14
+       movq $0x3ffffffffff, %r13
+       andq %r14, %rbx
+       andq %r13, %r12
+       movq %rbx, %r13
+       shrq $26, %r15
+       shlq $18, %r13
+       orq %r13, %r15
+       movq %rbx, %r13
+       shrq $44, %r14
+       shrq $8, %r13
+       addq %r14, %r12
+       movl %r11d, %r14d
+       andl $67108863, %r15d
+       andl $67108863, %r14d
+       andl $67108863, %r13d
+       movl %r14d, 204(%rdi)
+       movq %rbx, %r14
+       movl %r13d, 220(%rdi)
+       movq %r12, %r13
+       shrq $34, %r14
+       shlq $10, %r13
+       orq %r13, %r14
+       movq %r12, %r13
+       shrq $16, %r13
+       andl $67108863, %r14d
+       movl %r15d, 212(%rdi)
+       movl %r14d, 228(%rdi)
+       movl %r13d, 236(%rdi)
+       cmpq $32, %rcx
+       jbe .Lpoly1305_init_ext_avx2_continue
+       movq %r9, %rax
+       lea (%rbx,%rbx,4), %r14
+       shlq $2, %r14
+       mulq %r14
+       movq %rdi, -32(%rsp)
+       lea (%r12,%r12,4), %rdi
+       shlq $2, %rdi
+       movq %rax, %r14
+       movq %r10, %rax
+       movq %rdx, %r15
+       mulq %rdi
+       movq %rax, %r13
+       movq %r11, %rax
+       movq %rcx, -16(%rsp)
+       movq %rdx, %rcx
+       mulq %r8
+       addq %rax, %r13
+       movq %rdi, %rax
+       movq %rsi, -24(%rsp)
+       adcq %rdx, %rcx
+       addq %r13, %r14
+       adcq %rcx, %r15
+       movq %r14, %rcx
+       mulq %r9
+       shlq $20, %r15
+       movq %rax, %r13
+       shrq $44, %rcx
+       movq %r11, %rax
+       orq %rcx, %r15
+       movq %rdx, %rcx
+       mulq %r10
+       movq %rax, %rsi
+       movq %rbx, %rax
+       movq %rdx, %rdi
+       mulq %r8
+       addq %rax, %rsi
+       movq %r11, %rax
+       adcq %rdx, %rdi
+       addq %rsi, %r13
+       adcq %rdi, %rcx
+       addq %r13, %r15
+       movq %r15, %rdi
+       adcq $0, %rcx
+       mulq %r9
+       shlq $20, %rcx
+       movq %rdx, %rsi
+       shrq $44, %rdi
+       orq %rdi, %rcx
+       movq %rax, %rdi
+       movq %rbx, %rax
+       mulq %r10
+       movq %rax, %r9
+       movq %r8, %rax
+       movq %rdx, %r10
+       movq $0xfffffffffff, %r8
+       mulq %r12
+       addq %rax, %r9
+       adcq %rdx, %r10
+       andq %r8, %r14
+       addq %r9, %rdi
+       adcq %r10, %rsi
+       andq %r8, %r15
+       addq %rdi, %rcx
+       movq $0x3ffffffffff, %rdi
+       movq %rcx, %r10
+       adcq $0, %rsi
+       andq %rdi, %rcx
+       shlq $22, %rsi
+       shrq $42, %r10
+       orq %r10, %rsi
+       movq -32(%rsp), %rdi
+       lea (%rsi,%rsi,4), %r9
+       movq %r8, %rsi
+       addq %r9, %r14
+       andq %r14, %rsi
+       shrq $44, %r14
+       addq %r14, %r15
+       andq %r15, %r8
+       shrq $44, %r15
+       movq %r8, %r14
+       addq %r15, %rcx
+       movl %esi, %r15d
+       movq %rcx, %r10
+       movq %r8, %r9
+       shrq $26, %rsi
+       andl $67108863, %r15d
+       shlq $18, %r14
+       shrq $34, %r8
+       orq %r14, %rsi
+       shlq $10, %r10
+       shrq $8, %r9
+       orq %r10, %r8
+       shrq $16, %rcx
+       andl $67108863, %esi
+       movl %esi, 252(%rdi)
+       andl $67108863, %r9d
+       movl %ecx, 276(%rdi)
+       andl $67108863, %r8d
+       movl %r15d, 244(%rdi)
+       movl %r9d, 260(%rdi)
+       movl %r8d, 268(%rdi)
+       movq -16(%rsp), %rcx
+       movq -24(%rsp), %rsi
+.Lpoly1305_init_ext_avx2_continue:
+       movl 16(%rsi), %r8d
+       movl %r8d, 284(%rdi)
+       movl 20(%rsi), %r9d
+       movl %r9d, 292(%rdi)
+       movl 24(%rsi), %r10d
+       movl %r10d, 300(%rdi)
+       movl 28(%rsi), %esi
+       movl %esi, 308(%rdi)
+       cmpq $48, %rcx
+       jbe .Lpoly1305_init_ext_avx2_done
+       lea (%r12,%r12,4), %r9
+       shlq $2, %r9
+       lea (%rbx,%rbx), %rax
+       mulq %r9
+       movq %rax, %rsi
+       movq %r11, %rax
+       movq %rdx, %r8
+       mulq %r11
+       addq %rax, %rsi
+       lea (%r11,%r11), %rax
+       movq %rsi, %r10
+       adcq %rdx, %r8
+       mulq %rbx
+       movq %rax, %r13
+       movq %r12, %rax
+       movq %rdx, %rcx
+       addq %r12, %r12
+       mulq %r9
+       addq %rax, %r13
+       movq %r11, %rax
+       movq $0xfffffffffff, %r9
+       adcq %rdx, %rcx
+       andq %r9, %rsi
+       mulq %r12
+       shlq $20, %r8
+       movq %rax, %r11
+       shrq $44, %r10
+       movq %rbx, %rax
+       orq %r10, %r8
+       movq %rdx, %r12
+       mulq %rbx
+       addq %r13, %r8
+       movq %r8, %r14
+       adcq $0, %rcx
+       andq %r9, %r8
+       addq %rax, %r11
+       adcq %rdx, %r12
+       shlq $20, %rcx
+       shrq $44, %r14
+       orq %r14, %rcx
+       addq %r11, %rcx
+       movq %rcx, %rbx
+       adcq $0, %r12
+       shlq $22, %r12
+       shrq $42, %rbx
+       orq %rbx, %r12
+       movq %r9, %rbx
+       lea (%r12,%r12,4), %r15
+       addq %r15, %rsi
+       andq %rsi, %rbx
+       shrq $44, %rsi
+       movl %ebx, %r11d
+       addq %rsi, %r8
+       movq $0x3ffffffffff, %rsi
+       andq %r8, %r9
+       andq %rsi, %rcx
+       shrq $44, %r8
+       movq %r9, %rax
+       addq %r8, %rcx
+       movq %r9, %r8
+       movq %rcx, %r10
+       andl $67108863, %r11d
+       shrq $26, %rbx
+       shlq $18, %r8
+       shrq $34, %r9
+       orq %r8, %rbx
+       shlq $10, %r10
+       shrq $8, %rax
+       orq %r10, %r9
+       shrq $16, %rcx
+       andl $67108863, %ebx
+       andl $67108863, %eax
+       andl $67108863, %r9d
+       movl %r11d, 184(%rdi)
+       movl %r11d, 176(%rdi)
+       movl %r11d, 168(%rdi)
+       movl %r11d, 160(%rdi)
+       movl %ebx, 216(%rdi)
+       movl %ebx, 208(%rdi)
+       movl %ebx, 200(%rdi)
+       movl %ebx, 192(%rdi)
+       movl %eax, 248(%rdi)
+       movl %eax, 240(%rdi)
+       movl %eax, 232(%rdi)
+       movl %eax, 224(%rdi)
+       movl %r9d, 280(%rdi)
+       movl %r9d, 272(%rdi)
+       movl %r9d, 264(%rdi)
+       movl %r9d, 256(%rdi)
+       movl %ecx, 312(%rdi)
+       movl %ecx, 304(%rdi)
+       movl %ecx, 296(%rdi)
+       movl %ecx, 288(%rdi)
+.Lpoly1305_init_ext_avx2_done:
+       movq $0, 320(%rdi)
+       vzeroall
+       popq %rbx
+       popq %r15
+       popq %r14
+       popq %r13
+       popq %r12
+       ret
+ELF(.size _gcry_poly1305_amd64_avx2_init_ext,.-_gcry_poly1305_amd64_avx2_init_ext;)
+
+
+.align 8
+.globl _gcry_poly1305_amd64_avx2_blocks
+ELF(.type  _gcry_poly1305_amd64_avx2_blocks,@function;)
+_gcry_poly1305_amd64_avx2_blocks:
+.Lpoly1305_blocks_avx2_local:
+       vzeroupper
+       pushq %rbp
+       movq %rsp, %rbp
+       pushq %rbx
+       andq $-64, %rsp
+       subq $200, %rsp
+       movl $((1<<26)-1), %r8d
+       movl $(5), %r9d
+       movl $((1<<24)), %r10d
+       vmovd %r8d, %xmm0
+       vmovd %r9d, %xmm8
+       vmovd %r10d, %xmm7
+       vpbroadcastq %xmm0, %ymm0
+       vpbroadcastq %xmm8, %ymm8
+       vpbroadcastq %xmm7, %ymm7
+       vmovdqa %ymm7, 168(%rsp)
+       movq 320(%rdi), %rax
+       testb $60, %al
+       je .Lpoly1305_blocks_avx2_9
+       vmovdqa 168(%rsp), %ymm7
+       vpsrldq $8, %ymm7, %ymm1
+       vmovdqa %ymm1, 168(%rsp)
+       testb $4, %al
+       je .Lpoly1305_blocks_avx2_10
+       vpermq $192, %ymm1, %ymm7
+       vmovdqa %ymm7, 168(%rsp)
+.Lpoly1305_blocks_avx2_10:
+       testb $8, %al
+       je .Lpoly1305_blocks_avx2_11
+       vpermq $240, 168(%rsp), %ymm7
+       vmovdqa %ymm7, 168(%rsp)
+.Lpoly1305_blocks_avx2_11:
+       testb $16, %al
+       je .Lpoly1305_blocks_avx2_12
+       vpermq $252, 168(%rsp), %ymm6
+       vmovdqa %ymm6, 168(%rsp)
+.Lpoly1305_blocks_avx2_12:
+       testb $32, %al
+       je .Lpoly1305_blocks_avx2_9
+       vpxor %xmm6, %xmm6, %xmm6
+       vmovdqa %ymm6, 168(%rsp)
+.Lpoly1305_blocks_avx2_9:
+       testb $1, %al
+       jne .Lpoly1305_blocks_avx2_13
+       vmovdqu (%rsi), %ymm3
+       vmovdqu 32(%rsi), %ymm1
+       vpunpcklqdq %ymm1, %ymm3, %ymm2
+       vpunpckhqdq %ymm1, %ymm3, %ymm1
+       vpermq $216, %ymm2, %ymm2
+       vpermq $216, %ymm1, %ymm1
+       vpand %ymm2, %ymm0, %ymm5
+       vpsrlq $26, %ymm2, %ymm4
+       vpand %ymm4, %ymm0, %ymm4
+       vpsllq $12, %ymm1, %ymm3
+       vpsrlq $52, %ymm2, %ymm2
+       vpor %ymm3, %ymm2, %ymm2
+       vpand %ymm2, %ymm0, %ymm3
+       vpsrlq $26, %ymm2, %ymm2
+       vpand %ymm2, %ymm0, %ymm2
+       vpsrlq $40, %ymm1, %ymm1
+       vpor 168(%rsp), %ymm1, %ymm1
+       addq $64, %rsi
+       subq $64, %rdx
+       orq $1, 320(%rdi)
+       jmp .Lpoly1305_blocks_avx2_14
+.Lpoly1305_blocks_avx2_13:
+       vmovdqa (%rdi), %ymm5
+       vmovdqa 32(%rdi), %ymm4
+       vmovdqa 64(%rdi), %ymm3
+       vmovdqa 96(%rdi), %ymm2
+       vmovdqa 128(%rdi), %ymm1
+.Lpoly1305_blocks_avx2_14:
+       cmpq $63, %rdx
+       jbe .Lpoly1305_blocks_avx2_15
+       vmovdqa 160(%rdi), %ymm6
+       vmovdqa %ymm8, 136(%rsp)
+       vmovdqa 192(%rdi), %ymm7
+       vpmuludq %ymm8, %ymm7, %ymm11
+       vmovdqa %ymm11, 104(%rsp)
+       vmovdqa 224(%rdi), %ymm11
+       vmovdqa %ymm11, 72(%rsp)
+       vpmuludq %ymm11, %ymm8, %ymm11
+       vmovdqa %ymm11, 40(%rsp)
+       vmovdqa 256(%rdi), %ymm11
+       vmovdqa %ymm11, 8(%rsp)
+       vpmuludq %ymm11, %ymm8, %ymm11
+       vmovdqa %ymm11, -24(%rsp)
+       vmovdqa 288(%rdi), %ymm13
+       vmovdqa %ymm13, -56(%rsp)
+       vpmuludq %ymm13, %ymm8, %ymm13
+       vmovdqa %ymm13, -88(%rsp)
+.Lpoly1305_blocks_avx2_16:
+       vpmuludq 104(%rsp), %ymm1, %ymm14
+       vmovdqa 40(%rsp), %ymm13
+       vpmuludq %ymm13, %ymm2, %ymm8
+       vpmuludq %ymm13, %ymm1, %ymm13
+       vmovdqa -24(%rsp), %ymm9
+       vpmuludq %ymm9, %ymm2, %ymm10
+       vpmuludq %ymm9, %ymm1, %ymm11
+       vpaddq %ymm8, %ymm14, %ymm14
+       vpmuludq %ymm9, %ymm3, %ymm8
+       vmovdqa -88(%rsp), %ymm12
+       vpmuludq %ymm12, %ymm1, %ymm9
+       vpaddq %ymm10, %ymm13, %ymm13
+       vpmuludq %ymm12, %ymm4, %ymm15
+       vmovdqa %ymm12, %ymm10
+       vpmuludq %ymm12, %ymm3, %ymm12
+       vpaddq %ymm8, %ymm14, %ymm14
+       vpmuludq %ymm10, %ymm2, %ymm10
+       vpmuludq %ymm6, %ymm2, %ymm8
+       vpaddq %ymm15, %ymm14, %ymm14
+       vpmuludq %ymm6, %ymm1, %ymm1
+       vpaddq %ymm12, %ymm13, %ymm13
+       vpmuludq %ymm6, %ymm5, %ymm15
+       vpaddq %ymm10, %ymm11, %ymm11
+       vpmuludq %ymm6, %ymm4, %ymm12
+       vpaddq %ymm8, %ymm9, %ymm9
+       vpmuludq %ymm6, %ymm3, %ymm10
+       vpmuludq %ymm7, %ymm3, %ymm8
+       vpaddq %ymm15, %ymm14, %ymm14
+       vpmuludq %ymm7, %ymm2, %ymm2
+       vpaddq %ymm12, %ymm13, %ymm12
+       vpmuludq %ymm7, %ymm5, %ymm15
+       vpaddq %ymm10, %ymm11, %ymm10
+       vpmuludq %ymm7, %ymm4, %ymm13
+       vpaddq %ymm8, %ymm9, %ymm8
+       vmovdqa 72(%rsp), %ymm9
+       vpmuludq %ymm9, %ymm4, %ymm11
+       vpaddq %ymm2, %ymm1, %ymm1
+       vpmuludq %ymm9, %ymm3, %ymm3
+       vpaddq %ymm15, %ymm12, %ymm12
+       vpmuludq %ymm9, %ymm5, %ymm15
+       vpaddq %ymm13, %ymm10, %ymm10
+       vmovdqa 8(%rsp), %ymm2
+       vpmuludq %ymm2, %ymm5, %ymm9
+       vpaddq %ymm11, %ymm8, %ymm8
+       vpmuludq %ymm2, %ymm4, %ymm4
+       vpaddq %ymm3, %ymm1, %ymm1
+       vpmuludq -56(%rsp), %ymm5, %ymm5
+       vpaddq %ymm15, %ymm10, %ymm10
+       vpaddq %ymm9, %ymm8, %ymm8
+       vpaddq %ymm4, %ymm1, %ymm1
+       vpaddq %ymm5, %ymm1, %ymm5
+       vmovdqu (%rsi), %ymm3
+       vmovdqu 32(%rsi), %ymm2
+       vperm2i128 $32, %ymm2, %ymm3, %ymm1
+       vperm2i128 $49, %ymm2, %ymm3, %ymm2
+       vpunpckldq %ymm2, %ymm1, %ymm15
+       vpunpckhdq %ymm2, %ymm1, %ymm2
+       vpxor %xmm4, %xmm4, %xmm4
+       vpunpckldq %ymm4, %ymm15, %ymm1
+       vpunpckhdq %ymm4, %ymm15, %ymm15
+       vpunpckldq %ymm4, %ymm2, %ymm3
+       vpunpckhdq %ymm4, %ymm2, %ymm2
+       vpsllq $6, %ymm15, %ymm15
+       vpsllq $12, %ymm3, %ymm3
+       vpsllq $18, %ymm2, %ymm2
+       vpaddq %ymm1, %ymm14, %ymm14
+       vpaddq %ymm15, %ymm12, %ymm12
+       vpaddq %ymm3, %ymm10, %ymm10
+       vpaddq %ymm2, %ymm8, %ymm8
+       vpaddq 168(%rsp), %ymm5, %ymm5
+       addq $64, %rsi
+       vpsrlq $26, %ymm14, %ymm4
+       vpsrlq $26, %ymm8, %ymm2
+       vpand %ymm0, %ymm14, %ymm14
+       vpand %ymm0, %ymm8, %ymm8
+       vpaddq %ymm4, %ymm12, %ymm12
+       vpaddq %ymm2, %ymm5, %ymm5
+       vpsrlq $26, %ymm12, %ymm3
+       vpsrlq $26, %ymm5, %ymm9
+       vpand %ymm0, %ymm12, %ymm12
+       vpand %ymm0, %ymm5, %ymm11
+       vpaddq %ymm3, %ymm10, %ymm3
+       vpmuludq 136(%rsp), %ymm9, %ymm9
+       vpaddq %ymm9, %ymm14, %ymm14
+       vpsrlq $26, %ymm3, %ymm2
+       vpsrlq $26, %ymm14, %ymm4
+       vpand %ymm0, %ymm3, %ymm3
+       vpand %ymm0, %ymm14, %ymm5
+       vpaddq %ymm2, %ymm8, %ymm2
+       vpaddq %ymm4, %ymm12, %ymm4
+       vpsrlq $26, %ymm2, %ymm1
+       vpand %ymm0, %ymm2, %ymm2
+       vpaddq %ymm1, %ymm11, %ymm1
+       subq $64, %rdx
+       cmpq $63, %rdx
+       ja .Lpoly1305_blocks_avx2_16
+.Lpoly1305_blocks_avx2_15:
+       testb $64, 320(%rdi)
+       jne .Lpoly1305_blocks_avx2_17
+       vmovdqa %ymm5, (%rdi)
+       vmovdqa %ymm4, 32(%rdi)
+       vmovdqa %ymm3, 64(%rdi)
+       vmovdqa %ymm2, 96(%rdi)
+       vmovdqa %ymm1, 128(%rdi)
+       jmp .Lpoly1305_blocks_avx2_8
+.Lpoly1305_blocks_avx2_17:
+       vpermq $245, %ymm5, %ymm0
+       vpaddq %ymm0, %ymm5, %ymm5
+       vpermq $245, %ymm4, %ymm0
+       vpaddq %ymm0, %ymm4, %ymm4
+       vpermq $245, %ymm3, %ymm0
+       vpaddq %ymm0, %ymm3, %ymm3
+       vpermq $245, %ymm2, %ymm0
+       vpaddq %ymm0, %ymm2, %ymm2
+       vpermq $245, %ymm1, %ymm0
+       vpaddq %ymm0, %ymm1, %ymm1
+       vpermq $170, %ymm5, %ymm0
+       vpaddq %ymm0, %ymm5, %ymm5
+       vpermq $170, %ymm4, %ymm0
+       vpaddq %ymm0, %ymm4, %ymm4
+       vpermq $170, %ymm3, %ymm0
+       vpaddq %ymm0, %ymm3, %ymm3
+       vpermq $170, %ymm2, %ymm0
+       vpaddq %ymm0, %ymm2, %ymm2
+       vpermq $170, %ymm1, %ymm0
+       vpaddq %ymm0, %ymm1, %ymm1
+       vmovd %xmm5, %eax
+       vmovd %xmm4, %edx
+       movl %eax, %ecx
+       shrl $26, %ecx
+       addl %edx, %ecx
+       movl %ecx, %edx
+       andl $67108863, %edx
+       vmovd %xmm3, %esi
+       shrl $26, %ecx
+       movl %ecx, %r11d
+       addl %esi, %r11d
+       vmovd %xmm2, %ecx
+       movl %r11d, %r10d
+       shrl $26, %r10d
+       addl %ecx, %r10d
+       movl %r10d, %r9d
+       andl $67108863, %r9d
+       vmovd %xmm1, %r8d
+       movl %edx, %esi
+       salq $26, %rsi
+       andl $67108863, %eax
+       orq %rax, %rsi
+       movabsq $17592186044415, %rax
+       andq %rax, %rsi
+       andl $67108863, %r11d
+       salq $8, %r11
+       shrl $18, %edx
+       movl %edx, %edx
+       orq %r11, %rdx
+       movq %r9, %rcx
+       salq $34, %rcx
+       orq %rcx, %rdx
+       andq %rax, %rdx
+       shrl $26, %r10d
+       addl %r10d, %r8d
+       salq $16, %r8
+       shrl $10, %r9d
+       movl %r9d, %r9d
+       orq %r9, %r8
+       movabsq $4398046511103, %r10
+       movq %r8, %r9
+       andq %r10, %r9
+       shrq $42, %r8
+       leaq (%r8,%r8,4), %rcx
+       addq %rcx, %rsi
+       movq %rsi, %r8
+       andq %rax, %r8
+       movq %rsi, %rcx
+       shrq $44, %rcx
+       addq %rdx, %rcx
+       movq %rcx, %rsi
+       andq %rax, %rsi
+       shrq $44, %rcx
+       movq %rcx, %rdx
+       addq %r9, %rdx
+       andq %rdx, %r10
+       shrq $42, %rdx
+       leaq (%r8,%rdx,4), %rcx
+       leaq (%rcx,%rdx), %rdx
+       movq %rdx, %rbx
+       andq %rax, %rbx
+       shrq $44, %rdx
+       movq %rdx, %r11
+       addq %rsi, %r11
+       leaq 5(%rbx), %r9
+       movq %r9, %r8
+       shrq $44, %r8
+       addq %r11, %r8
+       movabsq $-4398046511104, %rsi
+       addq %r10, %rsi
+       movq %r8, %rdx
+       shrq $44, %rdx
+       addq %rdx, %rsi
+       movq %rsi, %rdx
+       shrq $63, %rdx
+       subq $1, %rdx
+       movq %rdx, %rcx
+       notq %rcx
+       andq %rcx, %rbx
+       andq %rcx, %r11
+       andq %r10, %rcx
+       andq %rax, %r9
+       andq %rdx, %r9
+       orq %r9, %rbx
+       movq %rbx, (%rdi)
+       andq %r8, %rax
+       andq %rdx, %rax
+       orq %rax, %r11
+       movq %r11, 8(%rdi)
+       andq %rsi, %rdx
+       orq %rcx, %rdx
+       movq %rdx, 16(%rdi)
+.Lpoly1305_blocks_avx2_8:
+       movq -8(%rbp), %rbx
+       vzeroall
+       movq %rbp, %rax
+       subq %rsp, %rax
+       leave
+       addq $8, %rax
+       ret
+ELF(.size _gcry_poly1305_amd64_avx2_blocks,.-_gcry_poly1305_amd64_avx2_blocks;)
+
+
+.align 8
+.globl _gcry_poly1305_amd64_avx2_finish_ext
+ELF(.type  _gcry_poly1305_amd64_avx2_finish_ext,@function;)
+_gcry_poly1305_amd64_avx2_finish_ext:
+.Lpoly1305_finish_ext_avx2_local:
+       vzeroupper
+       pushq %rbp
+       movq %rsp, %rbp
+       pushq %r13
+       pushq %r12
+       pushq %rbx
+       andq $-64, %rsp
+       subq $64, %rsp
+       movq %rdi, %rbx
+       movq %rdx, %r13
+       movq %rcx, %r12
+       testq %rdx, %rdx
+       je .Lpoly1305_finish_ext_avx2_22
+       vpxor %xmm0, %xmm0, %xmm0
+       vmovdqa %ymm0, (%rsp)
+       vmovdqa %ymm0, 32(%rsp)
+       movq %rsp, %rax
+       subq %rsp, %rsi
+       testb $32, %dl
+       je .Lpoly1305_finish_ext_avx2_23
+       vmovdqu (%rsp,%rsi), %ymm0
+       vmovdqa %ymm0, (%rsp)
+       leaq 32(%rsp), %rax
+.Lpoly1305_finish_ext_avx2_23:
+       testb $16, %r13b
+       je .Lpoly1305_finish_ext_avx2_24
+       vmovdqu (%rax,%rsi), %xmm0
+       vmovdqa %xmm0, (%rax)
+       addq $16, %rax
+.Lpoly1305_finish_ext_avx2_24:
+       testb $8, %r13b
+       je .Lpoly1305_finish_ext_avx2_25
+       movq (%rax,%rsi), %rdx
+       movq %rdx, (%rax)
+       addq $8, %rax
+.Lpoly1305_finish_ext_avx2_25:
+       testb $4, %r13b
+       je .Lpoly1305_finish_ext_avx2_26
+       movl (%rax,%rsi), %edx
+       movl %edx, (%rax)
+       addq $4, %rax
+.Lpoly1305_finish_ext_avx2_26:
+       testb $2, %r13b
+       je .Lpoly1305_finish_ext_avx2_27
+       movzwl (%rax,%rsi), %edx
+       movw %dx, (%rax)
+       addq $2, %rax
+.Lpoly1305_finish_ext_avx2_27:
+       testb $1, %r13b
+       je .Lpoly1305_finish_ext_avx2_28
+       movzbl (%rax,%rsi), %edx
+       movb %dl, (%rax)
+.Lpoly1305_finish_ext_avx2_28:
+       testb $15, %r13b
+       je .Lpoly1305_finish_ext_avx2_29
+       movb $1, (%rsp,%r13)
+.Lpoly1305_finish_ext_avx2_29:
+       cmpq $47, %r13
+       jbe .Lpoly1305_finish_ext_avx2_30
+       orq $4, 320(%rbx)
+       jmp .Lpoly1305_finish_ext_avx2_31
+.Lpoly1305_finish_ext_avx2_30:
+       cmpq $31, %r13
+       jbe .Lpoly1305_finish_ext_avx2_32
+       orq $8, 320(%rbx)
+       jmp .Lpoly1305_finish_ext_avx2_31
+.Lpoly1305_finish_ext_avx2_32:
+       cmpq $15, %r13
+       jbe .Lpoly1305_finish_ext_avx2_33
+       orq $16, 320(%rbx)
+       jmp .Lpoly1305_finish_ext_avx2_31
+.Lpoly1305_finish_ext_avx2_33:
+       orq $32, 320(%rbx)
+.Lpoly1305_finish_ext_avx2_31:
+       testb $1, 320(%rbx)
+       je .Lpoly1305_finish_ext_avx2_34
+       cmpq $32, %r13
+       ja .Lpoly1305_finish_ext_avx2_34
+       cmpq $17, %r13
+       sbbq %rsi, %rsi
+       notq %rsi
+       addq $2, %rsi
+       cmpq $17, %r13
+       sbbq %rax, %rax
+       movq %rbx, %rdx
+       addq $23, %rax
+       leaq (%rbx,%rax,8), %rax
+       movl $0, %ecx
+.Lpoly1305_finish_ext_avx2_37:
+       movl 244(%rdx), %edi
+       movl %edi, (%rax)
+       movl 252(%rdx), %edi
+       movl %edi, 32(%rax)
+       movl 260(%rdx), %edi
+       movl %edi, 64(%rax)
+       movl 268(%rdx), %edi
+       movl %edi, 96(%rax)
+       movl 276(%rdx), %edi
+       movl %edi, 128(%rax)
+       addq $1, %rcx
+       subq $40, %rdx
+       addq $8, %rax
+       cmpq %rcx, %rsi
+       ja .Lpoly1305_finish_ext_avx2_37
+.Lpoly1305_finish_ext_avx2_34:
+       movl $64, %edx
+       movq %rsp, %rsi
+       movq %rbx, %rdi
+       call .Lpoly1305_blocks_avx2_local
+.Lpoly1305_finish_ext_avx2_22:
+       movq 320(%rbx), %r8
+       testb $1, %r8b
+       je .Lpoly1305_finish_ext_avx2_38
+       leaq -1(%r13), %rax
+       cmpq $47, %rax
+       ja .Lpoly1305_finish_ext_avx2_46
+       cmpq $32, %r13
+       ja .Lpoly1305_finish_ext_avx2_47
+       cmpq $17, %r13
+       sbbq %r9, %r9
+       addq $2, %r9
+       movl $0, %edi
+       cmpq $17, %r13
+       sbbq %rax, %rax
+       notq %rax
+       andl $5, %eax
+       jmp .Lpoly1305_finish_ext_avx2_39
+.Lpoly1305_finish_ext_avx2_41:
+       movl (%rdx), %esi
+       movl %esi, (%rax)
+       movl 8(%rdx), %esi
+       movl %esi, 32(%rax)
+       movl 16(%rdx), %esi
+       movl %esi, 64(%rax)
+       movl 24(%rdx), %esi
+       movl %esi, 96(%rax)
+       movl 32(%rdx), %esi
+       movl %esi, 128(%rax)
+       addq $1, %rcx
+       subq $40, %rdx
+       addq $8, %rax
+       movq %rcx, %rsi
+       subq %rdi, %rsi
+       cmpq %rsi, %r9
+       ja .Lpoly1305_finish_ext_avx2_41
+       cmpq $3, %rcx
+       ja .Lpoly1305_finish_ext_avx2_42
+       leaq 160(%rbx,%rcx,8), %rax
+.Lpoly1305_finish_ext_avx2_43:
+       movl $1, (%rax)
+       movl $0, 32(%rax)
+       movl $0, 64(%rax)
+       movl $0, 96(%rax)
+       movl $0, 128(%rax)
+       addq $1, %rcx
+       addq $8, %rax
+       cmpq $4, %rcx
+       jne .Lpoly1305_finish_ext_avx2_43
+.Lpoly1305_finish_ext_avx2_42:
+       orq $96, %r8
+       movq %r8, 320(%rbx)
+       vpxor %ymm0, %ymm0, %ymm0
+       vmovdqa %ymm0, (%rsp)
+       vmovdqa %ymm0, 32(%rsp)
+       movl $64, %edx
+       movq %rsp, %rsi
+       movq %rbx, %rdi
+       call .Lpoly1305_blocks_avx2_local
+.Lpoly1305_finish_ext_avx2_38:
+       movq 8(%rbx), %rax
+       movq %rax, %rdx
+       salq $44, %rdx
+       orq (%rbx), %rdx
+       shrq $20, %rax
+       movl $24, %edi
+       shlx %rdi, 16(%rbx), %rcx
+       orq %rcx, %rax
+       movl 292(%rbx), %ecx
+       salq $32, %rcx
+       movl 284(%rbx), %esi
+       orq %rsi, %rcx
+       movl 308(%rbx), %esi
+       salq $32, %rsi
+       movl 300(%rbx), %edi
+       orq %rdi, %rsi
+       addq %rcx, %rdx
+       adcq %rsi, %rax
+       movq %rdx, (%r12)
+       movq %rax, 8(%r12)
+       vpxor %xmm0, %xmm0, %xmm0
+       vmovdqu %ymm0, (%rbx)
+       vmovdqu %ymm0, 32(%rbx)
+       vmovdqu %ymm0, 64(%rbx)
+       vmovdqu %ymm0, 96(%rbx)
+       vmovdqu %ymm0, 128(%rbx)
+       vmovdqu %ymm0, 160(%rbx)
+       vmovdqu %ymm0, 192(%rbx)
+       vmovdqu %ymm0, 224(%rbx)
+       jmp .Lpoly1305_finish_ext_avx2_49
+.Lpoly1305_finish_ext_avx2_46:
+       movl $3, %r9d
+       movl $1, %edi
+       movl $10, %eax
+       jmp .Lpoly1305_finish_ext_avx2_39
+.Lpoly1305_finish_ext_avx2_47:
+       movl $3, %r9d
+       movl $0, %edi
+       movl $10, %eax
+.Lpoly1305_finish_ext_avx2_39:
+       leaq 164(%rbx,%rax,8), %rdx
+       leaq 160(%rbx,%rdi,8), %rax
+       movq %rdi, %rcx
+       jmp .Lpoly1305_finish_ext_avx2_41
+.Lpoly1305_finish_ext_avx2_49:
+       movq %rbp, %rax
+       subq %rsp, %rax
+       leaq -24(%rbp), %rsp
+       vzeroall
+       popq %rbx
+       popq %r12
+       popq %r13
+       popq %rbp
+       addq $(8*5), %rax
+ret
+ELF(.size _gcry_poly1305_amd64_avx2_finish_ext,.-_gcry_poly1305_amd64_avx2_finish_ext;)
+
+#endif
diff --git a/cipher/poly1305-internal.h b/cipher/poly1305-internal.h
new file mode 100644 (file)
index 0000000..bcbe5df
--- /dev/null
@@ -0,0 +1,167 @@
+/* poly1305-internal.h  -  Poly1305 internals
+ * Copyright (C) 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef G10_POLY1305_INTERNAL_H
+#define G10_POLY1305_INTERNAL_H
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "types.h"
+#include "g10lib.h"
+#include "cipher.h"
+#include "bufhelp.h"
+
+
+#define POLY1305_TAGLEN 16
+#define POLY1305_KEYLEN 32
+
+
+/* Block-size used in default implementation. */
+#define POLY1305_REF_BLOCKSIZE 16
+
+/* State size of default implementation. */
+#define POLY1305_REF_STATESIZE 64
+
+/* State alignment for default implementation. */
+#define POLY1305_REF_ALIGNMENT sizeof(void *)
+
+
+#undef POLY1305_SYSV_FUNC_ABI
+
+/* POLY1305_USE_SSE2 indicates whether to compile with AMD64 SSE2 code. */
+#undef POLY1305_USE_SSE2
+#if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+    defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define POLY1305_USE_SSE2 1
+# define POLY1305_SSE2_BLOCKSIZE 32
+# define POLY1305_SSE2_STATESIZE 248
+# define POLY1305_SSE2_ALIGNMENT 16
+# define POLY1305_SYSV_FUNC_ABI 1
+#endif
+
+
+/* POLY1305_USE_AVX2 indicates whether to compile with AMD64 AVX2 code. */
+#undef POLY1305_USE_AVX2
+#if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+    defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
+    defined(ENABLE_AVX2_SUPPORT)
+# define POLY1305_USE_AVX2 1
+# define POLY1305_AVX2_BLOCKSIZE 64
+# define POLY1305_AVX2_STATESIZE 328
+# define POLY1305_AVX2_ALIGNMENT 32
+# define POLY1305_SYSV_FUNC_ABI 1
+#endif
+
+
+/* POLY1305_USE_NEON indicates whether to enable ARM NEON assembly code. */
+#undef POLY1305_USE_NEON
+#if defined(ENABLE_NEON_SUPPORT) && defined(HAVE_ARM_ARCH_V6) && \
+    defined(__ARMEL__) && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \
+    defined(HAVE_GCC_INLINE_ASM_NEON)
+# define POLY1305_USE_NEON 1
+# define POLY1305_NEON_BLOCKSIZE 32
+# define POLY1305_NEON_STATESIZE 128
+# define POLY1305_NEON_ALIGNMENT 16
+#endif
+
+
+/* Largest block-size used in any implementation (optimized implementations
+ * might use block-size multiple of 16). */
+#ifdef POLY1305_USE_AVX2
+# define POLY1305_LARGEST_BLOCKSIZE POLY1305_AVX2_BLOCKSIZE
+#elif defined(POLY1305_USE_NEON)
+# define POLY1305_LARGEST_BLOCKSIZE POLY1305_NEON_BLOCKSIZE
+#elif defined(POLY1305_USE_SSE2)
+# define POLY1305_LARGEST_BLOCKSIZE POLY1305_SSE2_BLOCKSIZE
+#else
+# define POLY1305_LARGEST_BLOCKSIZE POLY1305_REF_BLOCKSIZE
+#endif
+
+/* Largest state-size used in any implementation. */
+#ifdef POLY1305_USE_AVX2
+# define POLY1305_LARGEST_STATESIZE POLY1305_AVX2_STATESIZE
+#elif defined(POLY1305_USE_NEON)
+# define POLY1305_LARGEST_STATESIZE POLY1305_NEON_STATESIZE
+#elif defined(POLY1305_USE_SSE2)
+# define POLY1305_LARGEST_STATESIZE POLY1305_SSE2_STATESIZE
+#else
+# define POLY1305_LARGEST_STATESIZE POLY1305_REF_STATESIZE
+#endif
+
+/* Minimum alignment for state pointer passed to implementations. */
+#ifdef POLY1305_USE_AVX2
+# define POLY1305_STATE_ALIGNMENT POLY1305_AVX2_ALIGNMENT
+#elif defined(POLY1305_USE_NEON)
+# define POLY1305_STATE_ALIGNMENT POLY1305_NEON_ALIGNMENT
+#elif defined(POLY1305_USE_SSE2)
+# define POLY1305_STATE_ALIGNMENT POLY1305_SSE2_ALIGNMENT
+#else
+# define POLY1305_STATE_ALIGNMENT POLY1305_REF_ALIGNMENT
+#endif
+
+
+/* Assembly implementations use SystemV ABI, ABI conversion and additional
+ * stack to store XMM6-XMM15 needed on Win64. */
+#undef OPS_FUNC_ABI
+#if defined(POLY1305_SYSV_FUNC_ABI) && \
+    defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)
+# define OPS_FUNC_ABI __attribute__((sysv_abi))
+#else
+# define OPS_FUNC_ABI
+#endif
+
+
+typedef struct poly1305_key_s
+{
+  byte b[POLY1305_KEYLEN];
+} poly1305_key_t;
+
+
+typedef struct poly1305_ops_s
+{
+  size_t block_size;
+  void (*init_ext) (void *ctx, const poly1305_key_t * key) OPS_FUNC_ABI;
+  unsigned int (*blocks) (void *ctx, const byte * m, size_t bytes) OPS_FUNC_ABI;
+  unsigned int (*finish_ext) (void *ctx, const byte * m, size_t remaining,
+                             byte mac[POLY1305_TAGLEN]) OPS_FUNC_ABI;
+} poly1305_ops_t;
+
+
+typedef struct poly1305_context_s
+{
+  byte state[POLY1305_LARGEST_STATESIZE + POLY1305_STATE_ALIGNMENT];
+  byte buffer[POLY1305_LARGEST_BLOCKSIZE];
+  const poly1305_ops_t *ops;
+  unsigned int leftover;
+} poly1305_context_t;
+
+
+gcry_err_code_t _gcry_poly1305_init (poly1305_context_t * ctx, const byte * key,
+                                    size_t keylen);
+
+void _gcry_poly1305_finish (poly1305_context_t * ctx,
+                           byte mac[POLY1305_TAGLEN]);
+
+void _gcry_poly1305_update (poly1305_context_t * ctx, const byte * buf,
+                           size_t buflen);
+
+
+#endif /* G10_POLY1305_INTERNAL_H */
diff --git a/cipher/poly1305-sse2-amd64.S b/cipher/poly1305-sse2-amd64.S
new file mode 100644 (file)
index 0000000..219eb07
--- /dev/null
@@ -0,0 +1,1043 @@
+/* poly1305-sse2-amd64.S  -  AMD64/SSE2 implementation of Poly1305
+ *
+ * Copyright (C) 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Based on public domain implementation by Andrew Moon at
+ *  https://github.com/floodyberry/poly1305-opt
+ */
+
+#include <config.h>
+
+#if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+    defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
+
+
+.text
+
+
+.align 8
+.globl _gcry_poly1305_amd64_sse2_init_ext
+ELF(.type  _gcry_poly1305_amd64_sse2_init_ext,@function;)
+_gcry_poly1305_amd64_sse2_init_ext:
+.Lpoly1305_init_ext_x86_local:
+       xor %edx, %edx
+       pushq %r12
+       pushq %r13
+       pushq %r14
+       movq %rdx, %r10
+       movq $-1, %rcx
+       testq %r10, %r10
+       pxor %xmm0, %xmm0
+       movq $0xfffffc0ffff, %r9
+       movdqa %xmm0, (%rdi)
+       cmove %rcx, %r10
+       movdqa %xmm0, 16(%rdi)
+       movq $0xffc0fffffff, %rcx
+       movdqa %xmm0, 32(%rdi)
+       movdqa %xmm0, 48(%rdi)
+       movdqa %xmm0, 64(%rdi)
+       movq 8(%rsi), %r11
+       movq %r11, %r8
+       movq (%rsi), %r12
+       andq %r12, %rcx
+       shrq $44, %r12
+       shlq $20, %r8
+       shrq $24, %r11
+       orq %r8, %r12
+       movq $0xffffffc0f, %r8
+       andq %r9, %r12
+       andq %r8, %r11
+       movl %ecx, %r8d
+       andl $67108863, %r8d
+       movq %rcx, %r9
+       movl %r8d, 84(%rdi)
+       movq %r12, %r8
+       shrq $26, %r9
+       shlq $18, %r8
+       orq %r8, %r9
+       movq %r12, %r8
+       shrq $8, %r8
+       andl $67108863, %r9d
+       andl $67108863, %r8d
+       movl %r9d, 92(%rdi)
+       movq %r12, %r9
+       movl %r8d, 100(%rdi)
+       movq %r11, %r8
+       shrq $34, %r9
+       shlq $10, %r8
+       orq %r8, %r9
+       movq %r11, %r8
+       shrq $16, %r8
+       andl $67108863, %r9d
+       movl %r9d, 108(%rdi)
+       cmpq $16, %r10
+       movl %r8d, 116(%rdi)
+       movl 16(%rsi), %r8d
+       movl %r8d, 124(%rdi)
+       movl 20(%rsi), %r8d
+       movl %r8d, 132(%rdi)
+       movl 24(%rsi), %r8d
+       movl %r8d, 140(%rdi)
+       movl 28(%rsi), %esi
+       movl %esi, 148(%rdi)
+       jbe .Lpoly1305_init_ext_sse2_done
+       lea (%r11,%r11,4), %r14
+       shlq $2, %r14
+       lea (%r12,%r12), %rax
+       mulq %r14
+       movq %rax, %r13
+       movq %rcx, %rax
+       movq %rdx, %r8
+       mulq %rcx
+       addq %rax, %r13
+       lea (%rcx,%rcx), %rax
+       movq %r13, %r9
+       adcq %rdx, %r8
+       mulq %r12
+       shlq $20, %r8
+       movq %rax, %rsi
+       shrq $44, %r9
+       movq %r11, %rax
+       orq %r9, %r8
+       movq %rdx, %r9
+       mulq %r14
+       addq %rax, %rsi
+       movq %rcx, %rax
+       adcq %rdx, %r9
+       addq %r11, %r11
+       mulq %r11
+       addq %rsi, %r8
+       movq %rax, %r11
+       movq %r12, %rax
+       movq %rdx, %rcx
+       adcq $0, %r9
+       mulq %r12
+       addq %rax, %r11
+       movq %r8, %rsi
+       adcq %rdx, %rcx
+       shlq $20, %r9
+       shrq $44, %rsi
+       orq %rsi, %r9
+       movq $0xfffffffffff, %rsi
+       addq %r11, %r9
+       movq %r9, %r12
+       adcq $0, %rcx
+       andq %rsi, %r13
+       shlq $22, %rcx
+       andq %rsi, %r8
+       shrq $42, %r12
+       orq %r12, %rcx
+       movq %rsi, %r12
+       lea (%rcx,%rcx,4), %rcx
+       addq %rcx, %r13
+       movq %rsi, %rcx
+       andq %r13, %rcx
+       shrq $44, %r13
+       movq %rcx, %r14
+       addq %r13, %r8
+       movq $0x3ffffffffff, %r13
+       andq %r8, %r12
+       andq %r13, %r9
+       shrq $44, %r8
+       movq %r12, %r11
+       addq %r8, %r9
+       movq %r12, %rax
+       movq %r9, %r13
+       movl %ecx, %r8d
+       shrq $26, %r14
+       andl $67108863, %r8d
+       shlq $18, %r11
+       shrq $34, %rax
+       orq %r11, %r14
+       shlq $10, %r13
+       movq %r12, %r11
+       orq %r13, %rax
+       movq %r9, %r13
+       shrq $8, %r11
+       shrq $16, %r13
+       andl $67108863, %r14d
+       andl $67108863, %r11d
+       andl $67108863, %eax
+       movl %r8d, 88(%rdi)
+       cmpq $64, %r10
+       movl %r8d, 80(%rdi)
+       movl %r14d, 104(%rdi)
+       movl %r14d, 96(%rdi)
+       movl %r11d, 120(%rdi)
+       movl %r11d, 112(%rdi)
+       movl %eax, 136(%rdi)
+       movl %eax, 128(%rdi)
+       movl %r13d, 152(%rdi)
+       movl %r13d, 144(%rdi)
+       jbe .Lpoly1305_init_ext_sse2_done
+       lea (%r9,%r9,4), %r14
+       shlq $2, %r14
+       lea (%r12,%r12), %rax
+       mulq %r14
+       movq %rax, %r8
+       movq %rcx, %rax
+       movq %rdx, %r10
+       mulq %rcx
+       addq %rax, %r8
+       lea (%rcx,%rcx), %rax
+       movq %r8, %r11
+       adcq %rdx, %r10
+       andq %rsi, %r8
+       mulq %r12
+       shlq $20, %r10
+       movq %rax, %r13
+       shrq $44, %r11
+       movq %r9, %rax
+       orq %r11, %r10
+       movq %rdx, %r11
+       mulq %r14
+       addq %rax, %r13
+       movq %rcx, %rax
+       adcq %rdx, %r11
+       addq %r9, %r9
+       mulq %r9
+       addq %r13, %r10
+       movq %rax, %r9
+       movq %r12, %rax
+       movq %rdx, %rcx
+       adcq $0, %r11
+       mulq %r12
+       addq %rax, %r9
+       movq %r10, %r13
+       adcq %rdx, %rcx
+       andq %rsi, %r10
+       shlq $20, %r11
+       shrq $44, %r13
+       orq %r13, %r11
+       addq %r9, %r11
+       movq %rsi, %r9
+       movq %r11, %r12
+       adcq $0, %rcx
+       shlq $22, %rcx
+       shrq $42, %r12
+       orq %r12, %rcx
+       lea (%rcx,%rcx,4), %rcx
+       addq %rcx, %r8
+       andq %r8, %r9
+       shrq $44, %r8
+       movl %r9d, %eax
+       addq %r8, %r10
+       movq $0x3ffffffffff, %r8
+       andq %r10, %rsi
+       andq %r8, %r11
+       shrq $44, %r10
+       movq %rsi, %r8
+       addq %r10, %r11
+       andl $67108863, %eax
+       shrq $26, %r9
+       movq %r11, %r10
+       shlq $18, %r8
+       shlq $10, %r10
+       orq %r8, %r9
+       movq %rsi, %r8
+       shrq $34, %rsi
+       andl $67108863, %r9d
+       shrq $8, %r8
+       orq %r10, %rsi
+       shrq $16, %r11
+       andl $67108863, %r8d
+       andl $67108863, %esi
+       movl %eax, 168(%rdi)
+       movl %eax, 160(%rdi)
+       movl %r9d, 184(%rdi)
+       movl %r9d, 176(%rdi)
+       movl %r8d, 200(%rdi)
+       movl %r8d, 192(%rdi)
+       movl %esi, 216(%rdi)
+       movl %esi, 208(%rdi)
+       movl %r11d, 232(%rdi)
+       movl %r11d, 224(%rdi)
+.Lpoly1305_init_ext_sse2_done:
+       movq $0, 240(%rdi)
+       popq %r14
+       popq %r13
+       popq %r12
+       ret
+ELF(.size _gcry_poly1305_amd64_sse2_init_ext,.-_gcry_poly1305_amd64_sse2_init_ext;)
+
+
+.align 8
+.globl _gcry_poly1305_amd64_sse2_finish_ext
+ELF(.type  _gcry_poly1305_amd64_sse2_finish_ext,@function;)
+_gcry_poly1305_amd64_sse2_finish_ext:
+.Lpoly1305_finish_ext_x86_local:
+       pushq %rbp
+       movq %rsp, %rbp
+       subq $64, %rsp
+       andq $~63, %rsp
+       movq %rdx, 32(%rsp)
+       movq %rcx, 40(%rsp)
+       andq %rdx, %rdx
+       jz .Lpoly1305_finish_x86_no_leftover
+       pxor %xmm0, %xmm0
+       movdqa %xmm0, 0+0(%rsp)
+       movdqa %xmm0, 16+0(%rsp)
+       leaq 0(%rsp), %r8
+       testq $16, %rdx
+       jz .Lpoly1305_finish_x86_skip16
+       movdqu 0(%rsi), %xmm0
+       movdqa %xmm0, 0(%r8)
+       addq $16, %rsi
+       addq $16, %r8
+.Lpoly1305_finish_x86_skip16:
+       testq $8, %rdx
+       jz .Lpoly1305_finish_x86_skip8
+       movq 0(%rsi), %rax
+       movq %rax, 0(%r8)
+       addq $8, %rsi
+       addq $8, %r8
+.Lpoly1305_finish_x86_skip8:
+       testq $4, %rdx
+       jz .Lpoly1305_finish_x86_skip4
+       movl 0(%rsi), %eax
+       movl %eax, 0(%r8)
+       addq $4, %rsi
+       addq $4, %r8
+.Lpoly1305_finish_x86_skip4:
+       testq $2, %rdx
+       jz .Lpoly1305_finish_x86_skip2
+       movw 0(%rsi), %ax
+       movw %ax, 0(%r8)
+       addq $2, %rsi
+       addq $2, %r8
+.Lpoly1305_finish_x86_skip2:
+       testq $1, %rdx
+       jz .Lpoly1305_finish_x86_skip1
+       movb 0(%rsi), %al
+       movb %al, 0(%r8)
+       addq $1, %r8
+.Lpoly1305_finish_x86_skip1:
+       cmpq $16, %rdx
+       je .Lpoly1305_finish_x86_is16
+       movb $1, 0(%r8)
+.Lpoly1305_finish_x86_is16:
+       movq $4, %rax
+       jae .Lpoly1305_finish_x86_16andover
+       movq $8, %rax
+.Lpoly1305_finish_x86_16andover:
+       orq %rax, 240(%rdi)
+       leaq 0(%rsp), %rsi
+       movq $32, %rdx
+       callq .Lpoly1305_blocks_x86_local
+.Lpoly1305_finish_x86_no_leftover:
+       testq $1, 240(%rdi)
+       jz .Lpoly1305_finish_x86_not_started
+       movq 32(%rsp), %rdx
+       andq %rdx, %rdx
+       jz .Lpoly1305_finish_x86_r2r
+       cmpq $16, %rdx
+       jg .Lpoly1305_finish_x86_r2r
+       xorl %r10d, %r10d
+       movl 84(%rdi), %eax
+       movl 92(%rdi), %ecx
+       movl 100(%rdi), %edx
+       movl 108(%rdi), %r8d
+       movl 116(%rdi), %r9d
+       movl %eax, 80(%rdi)
+       movl $1, 8+80(%rdi)
+       movl %ecx, 96(%rdi)
+       movl %r10d, 8+96(%rdi)
+       movl %edx, 112(%rdi)
+       movl %r10d, 8+112(%rdi)
+       movl %r8d, 128(%rdi)
+       movl %r10d, 8+128(%rdi)
+       movl %r9d, 144(%rdi)
+       movl %r10d, 8+144(%rdi)
+       jmp .Lpoly1305_finish_x86_combine
+.Lpoly1305_finish_x86_r2r:
+       movl 84(%rdi), %eax
+       movl 92(%rdi), %ecx
+       movl 100(%rdi), %edx
+       movl 108(%rdi), %r8d
+       movl 116(%rdi), %r9d
+       movl %eax, 8+80(%rdi)
+       movl %ecx, 8+96(%rdi)
+       movl %edx, 8+112(%rdi)
+       movl %r8d, 8+128(%rdi)
+       movl %r9d, 8+144(%rdi)
+.Lpoly1305_finish_x86_combine:
+       xorq %rsi, %rsi
+       movq $32, %rdx
+       callq .Lpoly1305_blocks_x86_local
+.Lpoly1305_finish_x86_not_started:
+       movq 0(%rdi), %r8
+       movq 8(%rdi), %r9
+       movq %r9, %r10
+       movq 16(%rdi), %r11
+       shlq $44, %r9
+       shrq $20, %r10
+       shlq $24, %r11
+       orq %r9, %r8
+       orq %r11, %r10
+       pxor %xmm0, %xmm0
+       movl 124(%rdi), %eax
+       movl 132(%rdi), %ecx
+       movl 140(%rdi), %edx
+       movl 148(%rdi), %esi
+       movq 40(%rsp), %r11
+       shlq $32, %rcx
+       shlq $32, %rsi
+       orq %rcx, %rax
+       orq %rsi, %rdx
+       addq %r8, %rax
+       adcq %r10, %rdx
+       movq %rax, 0(%r11)
+       movq %rdx, 8(%r11)
+       movq %rbp, %rax
+       subq %rsp, %rax
+       movq %rbp, %rsp
+       movdqa %xmm0, 0(%rdi)
+       movdqa %xmm0, 16(%rdi)
+       movdqa %xmm0, 32(%rdi)
+       movdqa %xmm0, 48(%rdi)
+       movdqa %xmm0, 64(%rdi)
+       movdqa %xmm0, 80(%rdi)
+       movdqa %xmm0, 96(%rdi)
+       movdqa %xmm0, 112(%rdi)
+       movdqa %xmm0, 128(%rdi)
+       movdqa %xmm0, 144(%rdi)
+       movdqa %xmm0, 160(%rdi)
+       movdqa %xmm0, 176(%rdi)
+       movdqa %xmm0, 192(%rdi)
+       movdqa %xmm0, 208(%rdi)
+       movdqa %xmm0, 224(%rdi)
+       popq %rbp
+       addq $8, %rax
+       ret
+ELF(.size _gcry_poly1305_amd64_sse2_finish_ext,.-_gcry_poly1305_amd64_sse2_finish_ext;)
+
+
+.align 8
+.globl _gcry_poly1305_amd64_sse2_blocks
+ELF(.type  _gcry_poly1305_amd64_sse2_blocks,@function;)
+_gcry_poly1305_amd64_sse2_blocks:
+.Lpoly1305_blocks_x86_local:
+       pushq %rbp
+       movq %rsp, %rbp
+       pushq %rbx
+       andq $-64, %rsp
+       subq $328, %rsp
+       movq 240(%rdi), %rax
+       movl $(1<<24), %r8d
+       movl $((1<<26)-1), %r9d
+       movd %r8, %xmm0
+       movd %r9, %xmm5
+       pshufd $0x44, %xmm0, %xmm0
+       pshufd $0x44, %xmm5, %xmm5
+       testb $4, %al
+       je .Lpoly1305_blocks_x86_3
+       psrldq $8, %xmm0
+.Lpoly1305_blocks_x86_3:
+       testb $8, %al
+       je .Lpoly1305_blocks_x86_4
+       pxor %xmm0, %xmm0
+.Lpoly1305_blocks_x86_4:
+       movdqa %xmm0, 168(%rsp)
+       testb $1, %al
+       jne .Lpoly1305_blocks_x86_5
+       movq 16(%rsi), %xmm0
+       movdqa %xmm5, %xmm7
+       movdqa %xmm5, %xmm10
+       movq (%rsi), %xmm6
+       orq $1, %rax
+       subq $32, %rdx
+       movq 8(%rsi), %xmm1
+       punpcklqdq %xmm0, %xmm6
+       movq 24(%rsi), %xmm0
+       pand %xmm6, %xmm7
+       movdqa %xmm6, %xmm9
+       psrlq $52, %xmm6
+       addq $32, %rsi
+       punpcklqdq %xmm0, %xmm1
+       movdqa %xmm1, %xmm0
+       psrlq $26, %xmm9
+       psllq $12, %xmm0
+       movq %rax, 240(%rdi)
+       pand %xmm5, %xmm9
+       por %xmm0, %xmm6
+       psrlq $40, %xmm1
+       pand %xmm6, %xmm10
+       por 168(%rsp), %xmm1
+       psrlq $26, %xmm6
+       pand %xmm5, %xmm6
+.Lpoly1305_blocks_x86_6:
+       movdqa 80(%rdi), %xmm13
+       cmpq $63, %rdx
+       movl $(5), %r8d
+       movd %r8, %xmm14
+       pshufd $0x44, %xmm14, %xmm14
+       movdqa 96(%rdi), %xmm15
+       movdqa %xmm13, -8(%rsp)
+       movdqa 112(%rdi), %xmm0
+       movdqa %xmm14, 136(%rsp)
+       movdqa 128(%rdi), %xmm3
+       movdqa %xmm15, 312(%rsp)
+       pmuludq %xmm14, %xmm15
+       movdqa 144(%rdi), %xmm13
+       movdqa %xmm0, 232(%rsp)
+       pmuludq %xmm14, %xmm0
+       movdqa %xmm3, 152(%rsp)
+       pmuludq %xmm14, %xmm3
+       movdqa %xmm13, 56(%rsp)
+       pmuludq %xmm14, %xmm13
+       movdqa %xmm15, 40(%rsp)
+       movdqa %xmm0, -24(%rsp)
+       movdqa %xmm3, -40(%rsp)
+       movdqa %xmm13, -56(%rsp)
+       jbe .Lpoly1305_blocks_x86_7
+       movdqa 192(%rdi), %xmm15
+       leaq 32(%rsi), %rax
+       movq %rdx, %rcx
+       movdqa 176(%rdi), %xmm14
+       movdqa %xmm15, %xmm2
+       movdqa 208(%rdi), %xmm0
+       movdqa %xmm15, 216(%rsp)
+       movdqa %xmm14, 296(%rsp)
+       movdqa 224(%rdi), %xmm3
+       pmuludq 136(%rsp), %xmm14
+       movdqa -24(%rsp), %xmm13
+       movdqa %xmm14, 8(%rsp)
+       pmuludq 136(%rsp), %xmm2
+       movdqa -40(%rsp), %xmm14
+       movdqa %xmm0, 120(%rsp)
+       pmuludq 136(%rsp), %xmm0
+       movdqa %xmm3, 24(%rsp)
+       movdqa 160(%rdi), %xmm12
+       movdqa %xmm0, %xmm8
+       movdqa -56(%rsp), %xmm15
+       movdqa %xmm13, 88(%rsp)
+       pmuludq 136(%rsp), %xmm3
+       movdqa %xmm2, 104(%rsp)
+       movdqa %xmm0, %xmm13
+       movdqa -8(%rsp), %xmm11
+       movdqa %xmm3, 280(%rsp)
+       movdqa %xmm2, %xmm3
+       movdqa %xmm0, 200(%rsp)
+       movdqa %xmm14, 184(%rsp)
+       movdqa %xmm15, 264(%rsp)
+       jmp .Lpoly1305_blocks_x86_8
+.p2align 6,,63
+.Lpoly1305_blocks_x86_13:
+       movdqa 200(%rsp), %xmm13
+       movdqa %xmm3, %xmm6
+       movdqa 200(%rsp), %xmm8
+       movdqa 104(%rsp), %xmm3
+.Lpoly1305_blocks_x86_8:
+       movdqa 8(%rsp), %xmm4
+       pmuludq %xmm6, %xmm3
+       subq $64, %rcx
+       pmuludq %xmm10, %xmm8
+       movdqa 104(%rsp), %xmm2
+       movdqa 200(%rsp), %xmm0
+       pmuludq %xmm1, %xmm4
+       movdqa 280(%rsp), %xmm15
+       pmuludq %xmm6, %xmm13
+       movdqa 280(%rsp), %xmm14
+       pmuludq %xmm1, %xmm0
+       paddq %xmm3, %xmm4
+       pmuludq %xmm1, %xmm2
+       movdqa 280(%rsp), %xmm3
+       paddq %xmm8, %xmm4
+       pmuludq %xmm9, %xmm15
+       movdqa 280(%rsp), %xmm8
+       pmuludq %xmm10, %xmm14
+       pmuludq %xmm6, %xmm8
+       paddq %xmm13, %xmm2
+       movdqa %xmm6, %xmm13
+       pmuludq %xmm1, %xmm3
+       paddq %xmm15, %xmm4
+       movdqa 296(%rsp), %xmm15
+       pmuludq %xmm12, %xmm13
+       paddq %xmm14, %xmm2
+       movdqa %xmm7, %xmm14
+       paddq %xmm8, %xmm0
+       pmuludq %xmm12, %xmm14
+       movdqa %xmm9, %xmm8
+       pmuludq 296(%rsp), %xmm6
+       pmuludq %xmm12, %xmm8
+       movdqa %xmm6, 248(%rsp)
+       pmuludq %xmm10, %xmm15
+       movq -16(%rax), %xmm6
+       paddq %xmm13, %xmm3
+       movdqa %xmm10, %xmm13
+       paddq %xmm14, %xmm4
+       movq -8(%rax), %xmm14
+       paddq %xmm8, %xmm2
+       movq -32(%rax), %xmm8
+       pmuludq %xmm12, %xmm13
+       paddq %xmm15, %xmm3
+       pmuludq %xmm12, %xmm1
+       movdqa 216(%rsp), %xmm15
+       pmuludq 216(%rsp), %xmm10
+       punpcklqdq %xmm6, %xmm8
+       movq -24(%rax), %xmm6
+       pmuludq %xmm9, %xmm15
+       paddq %xmm13, %xmm0
+       movdqa 296(%rsp), %xmm13
+       paddq 248(%rsp), %xmm1
+       punpcklqdq %xmm14, %xmm6
+       movdqa 296(%rsp), %xmm14
+       pmuludq %xmm9, %xmm13
+       pmuludq 120(%rsp), %xmm9
+       movdqa %xmm15, 72(%rsp)
+       paddq %xmm10, %xmm1
+       movdqa 216(%rsp), %xmm15
+       pmuludq %xmm7, %xmm14
+       movdqa %xmm6, %xmm10
+       paddq %xmm9, %xmm1
+       pmuludq %xmm7, %xmm15
+       paddq %xmm13, %xmm0
+       paddq 72(%rsp), %xmm3
+       movdqa 120(%rsp), %xmm13
+       psllq $12, %xmm10
+       paddq %xmm14, %xmm2
+       movdqa %xmm5, %xmm14
+       pand %xmm8, %xmm14
+       pmuludq %xmm7, %xmm13
+       paddq %xmm15, %xmm0
+       movdqa %xmm14, 248(%rsp)
+       movdqa %xmm8, %xmm14
+       psrlq $52, %xmm8
+       movdqu (%rax), %xmm9
+       por %xmm10, %xmm8
+       pmuludq 24(%rsp), %xmm7
+       movdqu 16(%rax), %xmm10
+       paddq %xmm13, %xmm3
+       pxor %xmm13, %xmm13
+       movdqa %xmm9, %xmm15
+       paddq %xmm7, %xmm1
+       movdqa %xmm6, %xmm7
+       movdqa %xmm10, -72(%rsp)
+       punpckldq %xmm10, %xmm15
+       movdqa %xmm15, %xmm10
+       punpckldq %xmm13, %xmm10
+       punpckhdq -72(%rsp), %xmm9
+       psrlq $40, %xmm6
+       movdqa %xmm10, 72(%rsp)
+       movdqa %xmm9, %xmm10
+       punpckhdq %xmm13, %xmm9
+       psllq $18, %xmm9
+       paddq 72(%rsp), %xmm4
+       addq $64, %rax
+       paddq %xmm9, %xmm3
+       movdqa 40(%rsp), %xmm9
+       cmpq $63, %rcx
+       punpckhdq %xmm13, %xmm15
+       psllq $6, %xmm15
+       punpckldq %xmm13, %xmm10
+       paddq %xmm15, %xmm2
+       psllq $12, %xmm10
+       por 168(%rsp), %xmm6
+       pmuludq %xmm6, %xmm9
+       movdqa 88(%rsp), %xmm15
+       paddq %xmm10, %xmm0
+       movdqa 88(%rsp), %xmm13
+       psrlq $14, %xmm7
+       pand %xmm5, %xmm8
+       movdqa 184(%rsp), %xmm10
+       pand %xmm5, %xmm7
+       pmuludq %xmm7, %xmm15
+       paddq %xmm9, %xmm4
+       pmuludq %xmm6, %xmm13
+       movdqa 184(%rsp), %xmm9
+       paddq 168(%rsp), %xmm1
+       pmuludq %xmm7, %xmm10
+       pmuludq %xmm6, %xmm9
+       paddq %xmm15, %xmm4
+       movdqa 184(%rsp), %xmm15
+       paddq %xmm13, %xmm2
+       psrlq $26, %xmm14
+       movdqa 264(%rsp), %xmm13
+       paddq %xmm10, %xmm2
+       pmuludq %xmm8, %xmm15
+       pand %xmm5, %xmm14
+       paddq %xmm9, %xmm0
+       pmuludq %xmm6, %xmm13
+       movdqa 264(%rsp), %xmm9
+       movdqa 264(%rsp), %xmm10
+       pmuludq %xmm11, %xmm6
+       pmuludq %xmm8, %xmm9
+       paddq %xmm15, %xmm4
+       movdqa 264(%rsp), %xmm15
+       pmuludq %xmm14, %xmm10
+       paddq %xmm13, %xmm3
+       movdqa %xmm7, %xmm13
+       pmuludq %xmm7, %xmm15
+       paddq %xmm6, %xmm1
+       movdqa 312(%rsp), %xmm6
+       paddq %xmm9, %xmm2
+       pmuludq %xmm11, %xmm13
+       movdqa 248(%rsp), %xmm9
+       paddq %xmm10, %xmm4
+       pmuludq %xmm8, %xmm6
+       pmuludq 312(%rsp), %xmm7
+       paddq %xmm15, %xmm0
+       movdqa %xmm9, %xmm10
+       movdqa %xmm14, %xmm15
+       pmuludq %xmm11, %xmm10
+       paddq %xmm13, %xmm3
+       movdqa %xmm8, %xmm13
+       pmuludq %xmm11, %xmm13
+       paddq %xmm6, %xmm3
+       paddq %xmm7, %xmm1
+       movdqa 232(%rsp), %xmm6
+       pmuludq %xmm11, %xmm15
+       pmuludq 232(%rsp), %xmm8
+       paddq %xmm10, %xmm4
+       paddq %xmm8, %xmm1
+       movdqa 312(%rsp), %xmm10
+       paddq %xmm13, %xmm0
+       pmuludq %xmm14, %xmm6
+       movdqa 312(%rsp), %xmm13
+       pmuludq %xmm9, %xmm10
+       paddq %xmm15, %xmm2
+       movdqa 232(%rsp), %xmm7
+       pmuludq %xmm14, %xmm13
+       pmuludq 152(%rsp), %xmm14
+       paddq %xmm14, %xmm1
+       pmuludq %xmm9, %xmm7
+       paddq %xmm6, %xmm3
+       paddq %xmm10, %xmm2
+       movdqa 152(%rsp), %xmm10
+       paddq %xmm13, %xmm0
+       pmuludq %xmm9, %xmm10
+       paddq %xmm7, %xmm0
+       movdqa %xmm4, %xmm7
+       psrlq $26, %xmm7
+       pmuludq 56(%rsp), %xmm9
+       pand %xmm5, %xmm4
+       paddq %xmm7, %xmm2
+       paddq %xmm9, %xmm1
+       paddq %xmm10, %xmm3
+       movdqa %xmm2, %xmm7
+       movdqa %xmm2, %xmm9
+       movdqa %xmm3, %xmm6
+       psrlq $26, %xmm7
+       pand %xmm5, %xmm3
+       psrlq $26, %xmm6
+       paddq %xmm7, %xmm0
+       pand %xmm5, %xmm9
+       paddq %xmm6, %xmm1
+       movdqa %xmm0, %xmm10
+       movdqa %xmm1, %xmm6
+       pand %xmm5, %xmm10
+       pand %xmm5, %xmm1
+       psrlq $26, %xmm6
+       pmuludq 136(%rsp), %xmm6
+       paddq %xmm6, %xmm4
+       movdqa %xmm0, %xmm6
+       psrlq $26, %xmm6
+       movdqa %xmm4, %xmm2
+       movdqa %xmm4, %xmm7
+       paddq %xmm6, %xmm3
+       psrlq $26, %xmm2
+       pand %xmm5, %xmm7
+       movdqa %xmm3, %xmm0
+       paddq %xmm2, %xmm9
+       pand %xmm5, %xmm3
+       psrlq $26, %xmm0
+       paddq %xmm0, %xmm1
+       ja .Lpoly1305_blocks_x86_13
+       leaq -64(%rdx), %rax
+       movdqa %xmm3, %xmm6
+       andl $63, %edx
+       andq $-64, %rax
+       leaq 64(%rsi,%rax), %rsi
+.Lpoly1305_blocks_x86_7:
+       cmpq $31, %rdx
+       jbe .Lpoly1305_blocks_x86_9
+       movdqa -24(%rsp), %xmm13
+       movdqa %xmm6, %xmm0
+       movdqa %xmm6, %xmm3
+       movdqa 40(%rsp), %xmm11
+       movdqa %xmm1, %xmm12
+       testq %rsi, %rsi
+       movdqa -40(%rsp), %xmm2
+       pmuludq %xmm13, %xmm0
+       movdqa %xmm1, %xmm8
+       pmuludq %xmm1, %xmm11
+       movdqa %xmm10, %xmm4
+       movdqa %xmm1, %xmm14
+       pmuludq %xmm2, %xmm3
+       movdqa %xmm6, %xmm15
+       pmuludq %xmm1, %xmm13
+       movdqa %xmm7, %xmm1
+       pmuludq %xmm2, %xmm12
+       paddq %xmm0, %xmm11
+       movdqa -56(%rsp), %xmm0
+       pmuludq %xmm10, %xmm2
+       paddq %xmm3, %xmm13
+       pmuludq %xmm0, %xmm4
+       movdqa %xmm9, %xmm3
+       pmuludq %xmm0, %xmm3
+       paddq %xmm2, %xmm11
+       pmuludq %xmm0, %xmm8
+       movdqa %xmm6, %xmm2
+       pmuludq %xmm0, %xmm2
+       movdqa -8(%rsp), %xmm0
+       paddq %xmm4, %xmm13
+       movdqa 312(%rsp), %xmm4
+       paddq %xmm3, %xmm11
+       pmuludq 312(%rsp), %xmm6
+       movdqa 312(%rsp), %xmm3
+       pmuludq %xmm0, %xmm1
+       paddq %xmm2, %xmm12
+       pmuludq %xmm0, %xmm15
+       movdqa %xmm9, %xmm2
+       pmuludq %xmm0, %xmm2
+       pmuludq %xmm7, %xmm3
+       paddq %xmm1, %xmm11
+       movdqa 232(%rsp), %xmm1
+       pmuludq %xmm0, %xmm14
+       paddq %xmm15, %xmm8
+       pmuludq %xmm10, %xmm0
+       paddq %xmm2, %xmm13
+       movdqa 312(%rsp), %xmm2
+       pmuludq %xmm10, %xmm4
+       paddq %xmm3, %xmm13
+       movdqa 152(%rsp), %xmm3
+       pmuludq %xmm9, %xmm2
+       paddq %xmm6, %xmm14
+       pmuludq 232(%rsp), %xmm10
+       paddq %xmm0, %xmm12
+       pmuludq %xmm9, %xmm1
+       paddq %xmm10, %xmm14
+       movdqa 232(%rsp), %xmm0
+       pmuludq %xmm7, %xmm3
+       paddq %xmm4, %xmm8
+       pmuludq 152(%rsp), %xmm9
+       paddq %xmm2, %xmm12
+       paddq %xmm9, %xmm14
+       pmuludq %xmm7, %xmm0
+       paddq %xmm1, %xmm8
+       pmuludq 56(%rsp), %xmm7
+       paddq %xmm3, %xmm8
+       paddq %xmm7, %xmm14
+       paddq %xmm0, %xmm12
+       je .Lpoly1305_blocks_x86_10
+       movdqu (%rsi), %xmm1
+       pxor %xmm0, %xmm0
+       paddq 168(%rsp), %xmm14
+       movdqu 16(%rsi), %xmm2
+       movdqa %xmm1, %xmm3
+       punpckldq %xmm2, %xmm3
+       punpckhdq %xmm2, %xmm1
+       movdqa %xmm3, %xmm4
+       movdqa %xmm1, %xmm2
+       punpckldq %xmm0, %xmm4
+       punpckhdq %xmm0, %xmm3
+       punpckhdq %xmm0, %xmm1
+       punpckldq %xmm0, %xmm2
+       movdqa %xmm2, %xmm0
+       psllq $6, %xmm3
+       paddq %xmm4, %xmm11
+       psllq $12, %xmm0
+       paddq %xmm3, %xmm13
+       psllq $18, %xmm1
+       paddq %xmm0, %xmm12
+       paddq %xmm1, %xmm8
+.Lpoly1305_blocks_x86_10:
+       movdqa %xmm11, %xmm9
+       movdqa %xmm8, %xmm1
+       movdqa %xmm11, %xmm7
+       psrlq $26, %xmm9
+       movdqa %xmm8, %xmm6
+       pand %xmm5, %xmm7
+       paddq %xmm13, %xmm9
+       psrlq $26, %xmm1
+       pand %xmm5, %xmm6
+       movdqa %xmm9, %xmm10
+       paddq %xmm14, %xmm1
+       pand %xmm5, %xmm9
+       psrlq $26, %xmm10
+       movdqa %xmm1, %xmm0
+       pand %xmm5, %xmm1
+       paddq %xmm12, %xmm10
+       psrlq $26, %xmm0
+       pmuludq 136(%rsp), %xmm0
+       movdqa %xmm10, %xmm2
+       paddq %xmm0, %xmm7
+       psrlq $26, %xmm2
+       movdqa %xmm7, %xmm0
+       pand %xmm5, %xmm10
+       paddq %xmm2, %xmm6
+       psrlq $26, %xmm0
+       pand %xmm5, %xmm7
+       movdqa %xmm6, %xmm2
+       paddq %xmm0, %xmm9
+       pand %xmm5, %xmm6
+       psrlq $26, %xmm2
+       paddq %xmm2, %xmm1
+.Lpoly1305_blocks_x86_9:
+       testq %rsi, %rsi
+       je .Lpoly1305_blocks_x86_11
+       movdqa %xmm7, 0(%rdi)
+       movdqa %xmm9, 16(%rdi)
+       movdqa %xmm10, 32(%rdi)
+       movdqa %xmm6, 48(%rdi)
+       movdqa %xmm1, 64(%rdi)
+       movq -8(%rbp), %rbx
+       leave
+       ret
+.Lpoly1305_blocks_x86_5:
+       movdqa 0(%rdi), %xmm7
+       movdqa 16(%rdi), %xmm9
+       movdqa 32(%rdi), %xmm10
+       movdqa 48(%rdi), %xmm6
+       movdqa 64(%rdi), %xmm1
+       jmp .Lpoly1305_blocks_x86_6
+.Lpoly1305_blocks_x86_11:
+       movdqa %xmm7, %xmm0
+       movdqa %xmm9, %xmm2
+       movdqa %xmm6, %xmm3
+       psrldq $8, %xmm0
+       movabsq $4398046511103, %rbx
+       paddq %xmm0, %xmm7
+       psrldq $8, %xmm2
+       movdqa %xmm10, %xmm0
+       movd %xmm7, %edx
+       paddq %xmm2, %xmm9
+       psrldq $8, %xmm0
+       movl %edx, %ecx
+       movd %xmm9, %eax
+       paddq %xmm0, %xmm10
+       shrl $26, %ecx
+       psrldq $8, %xmm3
+       movdqa %xmm1, %xmm0
+       addl %ecx, %eax
+       movd %xmm10, %ecx
+       paddq %xmm3, %xmm6
+       movl %eax, %r9d
+       shrl $26, %eax
+       psrldq $8, %xmm0
+       addl %ecx, %eax
+       movd %xmm6, %ecx
+       paddq %xmm0, %xmm1
+       movl %eax, %esi
+       andl $67108863, %r9d
+       movd %xmm1, %r10d
+       shrl $26, %esi
+       andl $67108863, %eax
+       andl $67108863, %edx
+       addl %ecx, %esi
+       salq $8, %rax
+       movl %r9d, %ecx
+       shrl $18, %r9d
+       movl %esi, %r8d
+       shrl $26, %esi
+       andl $67108863, %r8d
+       addl %r10d, %esi
+       orq %r9, %rax
+       salq $16, %rsi
+       movq %r8, %r9
+       shrl $10, %r8d
+       salq $26, %rcx
+       orq %r8, %rsi
+       salq $34, %r9
+       orq %rdx, %rcx
+       movq %rsi, %r8
+       shrq $42, %rsi
+       movabsq $17592186044415, %rdx
+       orq %r9, %rax
+       andq %rbx, %r8
+       leaq (%rsi,%rsi,4), %rsi
+       andq %rdx, %rcx
+       andq %rdx, %rax
+       movabsq $-4398046511104, %r10
+       addq %rsi, %rcx
+       movq %rcx, %rsi
+       shrq $44, %rcx
+       addq %rcx, %rax
+       andq %rdx, %rsi
+       movq %rax, %rcx
+       shrq $44, %rax
+       addq %r8, %rax
+       andq %rdx, %rcx
+       andq %rax, %rbx
+       shrq $42, %rax
+       leaq (%rsi,%rax,4), %rsi
+       addq %rbx, %r10
+       addq %rax, %rsi
+       movq %rsi, %r8
+       shrq $44, %rsi
+       andq %rdx, %r8
+       addq %rcx, %rsi
+       leaq 5(%r8), %r9
+       movq %r9, %r11
+       andq %rdx, %r9
+       shrq $44, %r11
+       addq %rsi, %r11
+       movq %r11, %rax
+       andq %r11, %rdx
+       shrq $44, %rax
+       addq %rax, %r10
+       movq %r10, %rax
+       shrq $63, %rax
+       subq $1, %rax
+       movq %rax, %rcx
+       andq %rax, %r9
+       andq %rax, %rdx
+       notq %rcx
+       andq %r10, %rax
+       andq %rcx, %r8
+       andq %rcx, %rsi
+       andq %rbx, %rcx
+       orq %r9, %r8
+       orq %rdx, %rsi
+       orq %rax, %rcx
+       movq %r8, 0(%rdi)
+       movq %rsi, 8(%rdi)
+       movq %rcx, 16(%rdi)
+       movq -8(%rbp), %rbx
+       movq %rbp, %rax
+       subq %rsp, %rax
+       pxor %xmm15, %xmm15
+       pxor %xmm7, %xmm7
+       pxor %xmm14, %xmm14
+       pxor %xmm6, %xmm6
+       pxor %xmm13, %xmm13
+       pxor %xmm5, %xmm5
+       pxor %xmm12, %xmm12
+       pxor %xmm4, %xmm4
+       leave
+       addq $8, %rax
+       pxor %xmm11, %xmm11
+       pxor %xmm3, %xmm3
+       pxor %xmm10, %xmm10
+       pxor %xmm2, %xmm2
+       pxor %xmm9, %xmm9
+       pxor %xmm1, %xmm1
+       pxor %xmm8, %xmm8
+       pxor %xmm0, %xmm0
+       ret
+ELF(.size _gcry_poly1305_amd64_sse2_blocks,.-_gcry_poly1305_amd64_sse2_blocks;)
+
+#endif
diff --git a/cipher/poly1305.c b/cipher/poly1305.c
new file mode 100644 (file)
index 0000000..7ae3592
--- /dev/null
@@ -0,0 +1,627 @@
+/* poly1305.c  -  Poly1305 internals and generic implementation
+ * Copyright (C) 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* The code is based on public-domain Poly1305 implementation by
+ * Andrew Moon at
+ *  https://github.com/floodyberry/poly1305-opt
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "types.h"
+#include "g10lib.h"
+#include "cipher.h"
+#include "bufhelp.h"
+#include "poly1305-internal.h"
+
+
+static const char *selftest (void);
+\f
+
+
+#ifdef POLY1305_USE_SSE2
+
+void _gcry_poly1305_amd64_sse2_init_ext(void *state, const poly1305_key_t *key)
+                                       OPS_FUNC_ABI;
+unsigned int _gcry_poly1305_amd64_sse2_finish_ext(void *state, const byte *m,
+                                                 size_t remaining,
+                                                 byte mac[16]) OPS_FUNC_ABI;
+unsigned int _gcry_poly1305_amd64_sse2_blocks(void *ctx, const byte *m,
+                                             size_t bytes) OPS_FUNC_ABI;
+
+static const poly1305_ops_t poly1305_amd64_sse2_ops = {
+  POLY1305_SSE2_BLOCKSIZE,
+  _gcry_poly1305_amd64_sse2_init_ext,
+  _gcry_poly1305_amd64_sse2_blocks,
+  _gcry_poly1305_amd64_sse2_finish_ext
+};
+
+#endif
+
+
+#ifdef POLY1305_USE_AVX2
+
+void _gcry_poly1305_amd64_avx2_init_ext(void *state, const poly1305_key_t *key)
+                                       OPS_FUNC_ABI;
+unsigned int _gcry_poly1305_amd64_avx2_finish_ext(void *state, const byte *m,
+                                                 size_t remaining,
+                                                 byte mac[16]) OPS_FUNC_ABI;
+unsigned int _gcry_poly1305_amd64_avx2_blocks(void *ctx, const byte *m,
+                                             size_t bytes) OPS_FUNC_ABI;
+
+static const poly1305_ops_t poly1305_amd64_avx2_ops = {
+  POLY1305_AVX2_BLOCKSIZE,
+  _gcry_poly1305_amd64_avx2_init_ext,
+  _gcry_poly1305_amd64_avx2_blocks,
+  _gcry_poly1305_amd64_avx2_finish_ext
+};
+
+#endif
+
+
+#ifdef POLY1305_USE_NEON
+
+void _gcry_poly1305_armv7_neon_init_ext(void *state, const poly1305_key_t *key)
+                                       OPS_FUNC_ABI;
+unsigned int _gcry_poly1305_armv7_neon_finish_ext(void *state, const byte *m,
+                                                 size_t remaining,
+                                                 byte mac[16]) OPS_FUNC_ABI;
+unsigned int _gcry_poly1305_armv7_neon_blocks(void *ctx, const byte *m,
+                                             size_t bytes) OPS_FUNC_ABI;
+
+static const poly1305_ops_t poly1305_armv7_neon_ops = {
+  POLY1305_NEON_BLOCKSIZE,
+  _gcry_poly1305_armv7_neon_init_ext,
+  _gcry_poly1305_armv7_neon_blocks,
+  _gcry_poly1305_armv7_neon_finish_ext
+};
+
+#endif
+
+
+/* Reference unoptimized poly1305 implementation using 32 bit * 32 bit = 64 bit
+ * multiplication and 64 bit addition.
+ */
+
+typedef struct poly1305_state_ref32_s
+{
+  u32 r[5];
+  u32 h[5];
+  u32 pad[4];
+  byte final;
+} poly1305_state_ref32_t;
+
+
+static OPS_FUNC_ABI void
+poly1305_init_ext_ref32 (void *state, const poly1305_key_t * key)
+{
+  poly1305_state_ref32_t *st = (poly1305_state_ref32_t *) state;
+
+  gcry_assert (sizeof (*st) + POLY1305_STATE_ALIGNMENT <=
+              sizeof (((poly1305_context_t *) 0)->state));
+
+  /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
+  st->r[0] = (buf_get_le32 (&key->b[0])) & 0x3ffffff;
+  st->r[1] = (buf_get_le32 (&key->b[3]) >> 2) & 0x3ffff03;
+  st->r[2] = (buf_get_le32 (&key->b[6]) >> 4) & 0x3ffc0ff;
+  st->r[3] = (buf_get_le32 (&key->b[9]) >> 6) & 0x3f03fff;
+  st->r[4] = (buf_get_le32 (&key->b[12]) >> 8) & 0x00fffff;
+
+  /* h = 0 */
+  st->h[0] = 0;
+  st->h[1] = 0;
+  st->h[2] = 0;
+  st->h[3] = 0;
+  st->h[4] = 0;
+
+  /* save pad for later */
+  st->pad[0] = buf_get_le32 (&key->b[16]);
+  st->pad[1] = buf_get_le32 (&key->b[20]);
+  st->pad[2] = buf_get_le32 (&key->b[24]);
+  st->pad[3] = buf_get_le32 (&key->b[28]);
+
+  st->final = 0;
+}
+
+
+static OPS_FUNC_ABI unsigned int
+poly1305_blocks_ref32 (void *state, const byte * m, size_t bytes)
+{
+  poly1305_state_ref32_t *st = (poly1305_state_ref32_t *) state;
+  const u32 hibit = (st->final) ? 0 : (1 << 24);       /* 1 << 128 */
+  u32 r0, r1, r2, r3, r4;
+  u32 s1, s2, s3, s4;
+  u32 h0, h1, h2, h3, h4;
+  u64 d0, d1, d2, d3, d4;
+  u32 c;
+
+  r0 = st->r[0];
+  r1 = st->r[1];
+  r2 = st->r[2];
+  r3 = st->r[3];
+  r4 = st->r[4];
+
+  s1 = r1 * 5;
+  s2 = r2 * 5;
+  s3 = r3 * 5;
+  s4 = r4 * 5;
+
+  h0 = st->h[0];
+  h1 = st->h[1];
+  h2 = st->h[2];
+  h3 = st->h[3];
+  h4 = st->h[4];
+
+  while (bytes >= POLY1305_REF_BLOCKSIZE)
+    {
+      /* h += m[i] */
+      h0 += (buf_get_le32 (m + 0)) & 0x3ffffff;
+      h1 += (buf_get_le32 (m + 3) >> 2) & 0x3ffffff;
+      h2 += (buf_get_le32 (m + 6) >> 4) & 0x3ffffff;
+      h3 += (buf_get_le32 (m + 9) >> 6) & 0x3ffffff;
+      h4 += (buf_get_le32 (m + 12) >> 8) | hibit;
+
+      /* h *= r */
+      d0 =
+       ((u64) h0 * r0) + ((u64) h1 * s4) +
+       ((u64) h2 * s3) + ((u64) h3 * s2) + ((u64) h4 * s1);
+      d1 =
+       ((u64) h0 * r1) + ((u64) h1 * r0) +
+       ((u64) h2 * s4) + ((u64) h3 * s3) + ((u64) h4 * s2);
+      d2 =
+       ((u64) h0 * r2) + ((u64) h1 * r1) +
+       ((u64) h2 * r0) + ((u64) h3 * s4) + ((u64) h4 * s3);
+      d3 =
+       ((u64) h0 * r3) + ((u64) h1 * r2) +
+       ((u64) h2 * r1) + ((u64) h3 * r0) + ((u64) h4 * s4);
+      d4 =
+       ((u64) h0 * r4) + ((u64) h1 * r3) +
+       ((u64) h2 * r2) + ((u64) h3 * r1) + ((u64) h4 * r0);
+
+      /* (partial) h %= p */
+      c = (u32) (d0 >> 26);
+      h0 = (u32) d0 & 0x3ffffff;
+      d1 += c;
+      c = (u32) (d1 >> 26);
+      h1 = (u32) d1 & 0x3ffffff;
+      d2 += c;
+      c = (u32) (d2 >> 26);
+      h2 = (u32) d2 & 0x3ffffff;
+      d3 += c;
+      c = (u32) (d3 >> 26);
+      h3 = (u32) d3 & 0x3ffffff;
+      d4 += c;
+      c = (u32) (d4 >> 26);
+      h4 = (u32) d4 & 0x3ffffff;
+      h0 += c * 5;
+      c = (h0 >> 26);
+      h0 = h0 & 0x3ffffff;
+      h1 += c;
+
+      m += POLY1305_REF_BLOCKSIZE;
+      bytes -= POLY1305_REF_BLOCKSIZE;
+    }
+
+  st->h[0] = h0;
+  st->h[1] = h1;
+  st->h[2] = h2;
+  st->h[3] = h3;
+  st->h[4] = h4;
+
+  return (16 * sizeof (u32) + 5 * sizeof (u64) + 5 * sizeof (void *));
+}
+
+
+static OPS_FUNC_ABI unsigned int
+poly1305_finish_ext_ref32 (void *state, const byte * m,
+                          size_t remaining, byte mac[POLY1305_TAGLEN])
+{
+  poly1305_state_ref32_t *st = (poly1305_state_ref32_t *) state;
+  u32 h0, h1, h2, h3, h4, c;
+  u32 g0, g1, g2, g3, g4;
+  u64 f;
+  u32 mask;
+  unsigned int burn = 0;
+
+  /* process the remaining block */
+  if (remaining)
+    {
+      byte final[POLY1305_REF_BLOCKSIZE] = { 0 };
+      size_t i;
+      for (i = 0; i < remaining; i++)
+       final[i] = m[i];
+      final[remaining] = 1;
+      st->final = 1;
+      burn = poly1305_blocks_ref32 (st, final, POLY1305_REF_BLOCKSIZE);
+    }
+
+  /* fully carry h */
+  h0 = st->h[0];
+  h1 = st->h[1];
+  h2 = st->h[2];
+  h3 = st->h[3];
+  h4 = st->h[4];
+
+  c = h1 >> 26;
+  h1 = h1 & 0x3ffffff;
+  h2 += c;
+  c = h2 >> 26;
+  h2 = h2 & 0x3ffffff;
+  h3 += c;
+  c = h3 >> 26;
+  h3 = h3 & 0x3ffffff;
+  h4 += c;
+  c = h4 >> 26;
+  h4 = h4 & 0x3ffffff;
+  h0 += c * 5;
+  c = h0 >> 26;
+  h0 = h0 & 0x3ffffff;
+  h1 += c;
+
+  /* compute h + -p */
+  g0 = h0 + 5;
+  c = g0 >> 26;
+  g0 &= 0x3ffffff;
+  g1 = h1 + c;
+  c = g1 >> 26;
+  g1 &= 0x3ffffff;
+  g2 = h2 + c;
+  c = g2 >> 26;
+  g2 &= 0x3ffffff;
+  g3 = h3 + c;
+  c = g3 >> 26;
+  g3 &= 0x3ffffff;
+  g4 = h4 + c - (1 << 26);
+
+  /* select h if h < p, or h + -p if h >= p */
+  mask = (g4 >> ((sizeof (u32) * 8) - 1)) - 1;
+  g0 &= mask;
+  g1 &= mask;
+  g2 &= mask;
+  g3 &= mask;
+  g4 &= mask;
+  mask = ~mask;
+  h0 = (h0 & mask) | g0;
+  h1 = (h1 & mask) | g1;
+  h2 = (h2 & mask) | g2;
+  h3 = (h3 & mask) | g3;
+  h4 = (h4 & mask) | g4;
+
+  /* h = h % (2^128) */
+  h0 = ((h0) | (h1 << 26)) & 0xffffffff;
+  h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff;
+  h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff;
+  h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff;
+
+  /* mac = (h + pad) % (2^128) */
+  f = (u64) h0 + st->pad[0];
+  h0 = (u32) f;
+  f = (u64) h1 + st->pad[1] + (f >> 32);
+  h1 = (u32) f;
+  f = (u64) h2 + st->pad[2] + (f >> 32);
+  h2 = (u32) f;
+  f = (u64) h3 + st->pad[3] + (f >> 32);
+  h3 = (u32) f;
+
+  buf_put_le32 (mac + 0, h0);
+  buf_put_le32 (mac + 4, h1);
+  buf_put_le32 (mac + 8, h2);
+  buf_put_le32 (mac + 12, h3);
+
+  /* zero out the state */
+  st->h[0] = 0;
+  st->h[1] = 0;
+  st->h[2] = 0;
+  st->h[3] = 0;
+  st->h[4] = 0;
+  st->r[0] = 0;
+  st->r[1] = 0;
+  st->r[2] = 0;
+  st->r[3] = 0;
+  st->r[4] = 0;
+  st->pad[0] = 0;
+  st->pad[1] = 0;
+  st->pad[2] = 0;
+  st->pad[3] = 0;
+
+  /* burn_stack */
+  return (13 * sizeof (u32) + sizeof (u64) +
+         POLY1305_REF_BLOCKSIZE + 6 * sizeof (void *)) + burn;
+}
+
+
+static const poly1305_ops_t poly1305_default_ops = {
+  POLY1305_REF_BLOCKSIZE,
+  poly1305_init_ext_ref32,
+  poly1305_blocks_ref32,
+  poly1305_finish_ext_ref32
+};
+
+\f
+
+
+static inline void *
+poly1305_get_state (poly1305_context_t * ctx)
+{
+  byte *c = ctx->state;
+  c += POLY1305_STATE_ALIGNMENT - 1;
+  c -= (uintptr_t) c & (POLY1305_STATE_ALIGNMENT - 1);
+  return c;
+}
+
+
+static void
+poly1305_init (poly1305_context_t * ctx, const poly1305_key_t * key)
+{
+  void *state = poly1305_get_state (ctx);
+
+  ctx->leftover = 0;
+
+  ctx->ops->init_ext (state, key);
+}
+
+
+void
+_gcry_poly1305_update (poly1305_context_t * ctx, const byte * m, size_t bytes)
+{
+  void *state = poly1305_get_state (ctx);
+  unsigned int burn = 0;
+  size_t block_size = ctx->ops->block_size;
+
+  /* handle leftover */
+  if (ctx->leftover)
+    {
+      size_t want = (block_size - ctx->leftover);
+      if (want > bytes)
+       want = bytes;
+      buf_cpy (ctx->buffer + ctx->leftover, m, want);
+      bytes -= want;
+      m += want;
+      ctx->leftover += want;
+      if (ctx->leftover < block_size)
+       return;
+      burn = ctx->ops->blocks (state, ctx->buffer, block_size);
+      ctx->leftover = 0;
+    }
+
+  /* process full blocks */
+  if (bytes >= block_size)
+    {
+      size_t want = (bytes & ~(block_size - 1));
+      burn = ctx->ops->blocks (state, m, want);
+      m += want;
+      bytes -= want;
+    }
+
+  /* store leftover */
+  if (bytes)
+    {
+      buf_cpy (ctx->buffer + ctx->leftover, m, bytes);
+      ctx->leftover += bytes;
+    }
+
+  if (burn)
+    _gcry_burn_stack (burn);
+}
+
+
+void
+_gcry_poly1305_finish (poly1305_context_t * ctx, byte mac[POLY1305_TAGLEN])
+{
+  void *state = poly1305_get_state (ctx);
+  unsigned int burn;
+
+  burn = ctx->ops->finish_ext (state, ctx->buffer, ctx->leftover, mac);
+
+  _gcry_burn_stack (burn);
+}
+
+
+gcry_err_code_t
+_gcry_poly1305_init (poly1305_context_t * ctx, const byte * key,
+                    size_t keylen)
+{
+  static int initialized;
+  static const char *selftest_failed;
+  poly1305_key_t keytmp;
+  unsigned int features = _gcry_get_hw_features ();
+
+  if (!initialized)
+    {
+      initialized = 1;
+      selftest_failed = selftest ();
+      if (selftest_failed)
+       log_error ("Poly1305 selftest failed (%s)\n", selftest_failed);
+    }
+
+  if (keylen != POLY1305_KEYLEN)
+    return GPG_ERR_INV_KEYLEN;
+
+  if (selftest_failed)
+    return GPG_ERR_SELFTEST_FAILED;
+
+#ifdef POLY1305_USE_SSE2
+  ctx->ops = &poly1305_amd64_sse2_ops;
+#else
+  ctx->ops = &poly1305_default_ops;
+#endif
+
+#ifdef POLY1305_USE_AVX2
+  if (features & HWF_INTEL_AVX2)
+    ctx->ops = &poly1305_amd64_avx2_ops;
+#endif
+#ifdef POLY1305_USE_NEON
+  if (features & HWF_ARM_NEON)
+    ctx->ops = &poly1305_armv7_neon_ops;
+#endif
+  (void)features;
+
+  buf_cpy (keytmp.b, key, POLY1305_KEYLEN);
+  poly1305_init (ctx, &keytmp);
+
+  wipememory (&keytmp, sizeof (keytmp));
+
+  return 0;
+}
+
+
+static void
+poly1305_auth (byte mac[POLY1305_TAGLEN], const byte * m, size_t bytes,
+              const byte * key)
+{
+  poly1305_context_t ctx;
+
+  memset (&ctx, 0, sizeof (ctx));
+
+  _gcry_poly1305_init (&ctx, key, POLY1305_KEYLEN);
+  _gcry_poly1305_update (&ctx, m, bytes);
+  _gcry_poly1305_finish (&ctx, mac);
+
+  wipememory (&ctx, sizeof (ctx));
+}
+
+
+static const char *
+selftest (void)
+{
+  /* example from nacl */
+  static const byte nacl_key[POLY1305_KEYLEN] = {
+    0xee, 0xa6, 0xa7, 0x25, 0x1c, 0x1e, 0x72, 0x91,
+    0x6d, 0x11, 0xc2, 0xcb, 0x21, 0x4d, 0x3c, 0x25,
+    0x25, 0x39, 0x12, 0x1d, 0x8e, 0x23, 0x4e, 0x65,
+    0x2d, 0x65, 0x1f, 0xa4, 0xc8, 0xcf, 0xf8, 0x80,
+  };
+
+  static const byte nacl_msg[131] = {
+    0x8e, 0x99, 0x3b, 0x9f, 0x48, 0x68, 0x12, 0x73,
+    0xc2, 0x96, 0x50, 0xba, 0x32, 0xfc, 0x76, 0xce,
+    0x48, 0x33, 0x2e, 0xa7, 0x16, 0x4d, 0x96, 0xa4,
+    0x47, 0x6f, 0xb8, 0xc5, 0x31, 0xa1, 0x18, 0x6a,
+    0xc0, 0xdf, 0xc1, 0x7c, 0x98, 0xdc, 0xe8, 0x7b,
+    0x4d, 0xa7, 0xf0, 0x11, 0xec, 0x48, 0xc9, 0x72,
+    0x71, 0xd2, 0xc2, 0x0f, 0x9b, 0x92, 0x8f, 0xe2,
+    0x27, 0x0d, 0x6f, 0xb8, 0x63, 0xd5, 0x17, 0x38,
+    0xb4, 0x8e, 0xee, 0xe3, 0x14, 0xa7, 0xcc, 0x8a,
+    0xb9, 0x32, 0x16, 0x45, 0x48, 0xe5, 0x26, 0xae,
+    0x90, 0x22, 0x43, 0x68, 0x51, 0x7a, 0xcf, 0xea,
+    0xbd, 0x6b, 0xb3, 0x73, 0x2b, 0xc0, 0xe9, 0xda,
+    0x99, 0x83, 0x2b, 0x61, 0xca, 0x01, 0xb6, 0xde,
+    0x56, 0x24, 0x4a, 0x9e, 0x88, 0xd5, 0xf9, 0xb3,
+    0x79, 0x73, 0xf6, 0x22, 0xa4, 0x3d, 0x14, 0xa6,
+    0x59, 0x9b, 0x1f, 0x65, 0x4c, 0xb4, 0x5a, 0x74,
+    0xe3, 0x55, 0xa5
+  };
+
+  static const byte nacl_mac[16] = {
+    0xf3, 0xff, 0xc7, 0x70, 0x3f, 0x94, 0x00, 0xe5,
+    0x2a, 0x7d, 0xfb, 0x4b, 0x3d, 0x33, 0x05, 0xd9
+  };
+
+  /* generates a final value of (2^130 - 2) == 3 */
+  static const byte wrap_key[POLY1305_KEYLEN] = {
+    0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
+
+  static const byte wrap_msg[16] = {
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+  };
+
+  static const byte wrap_mac[16] = {
+    0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
+
+  /* mac of the macs of messages of length 0 to 256, where the key and messages
+   * have all their values set to the length
+   */
+  static const byte total_key[POLY1305_KEYLEN] = {
+    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+  };
+
+  static const byte total_mac[16] = {
+    0x64, 0xaf, 0xe2, 0xe8, 0xd6, 0xad, 0x7b, 0xbd,
+    0xd2, 0x87, 0xf9, 0x7c, 0x44, 0x62, 0x3d, 0x39
+  };
+
+  poly1305_context_t ctx;
+  poly1305_context_t total_ctx;
+  byte all_key[POLY1305_KEYLEN];
+  byte all_msg[256];
+  byte mac[16];
+  size_t i, j;
+
+  memset (&ctx, 0, sizeof (ctx));
+  memset (&total_ctx, 0, sizeof (total_ctx));
+
+  memset (mac, 0, sizeof (mac));
+  poly1305_auth (mac, nacl_msg, sizeof (nacl_msg), nacl_key);
+  if (memcmp (nacl_mac, mac, sizeof (nacl_mac)) != 0)
+    return "Poly1305 test 1 failed.";
+
+  /* SSE2/AVX have a 32 byte block size, but also support 64 byte blocks, so
+   * make sure everything still works varying between them */
+  memset (mac, 0, sizeof (mac));
+  _gcry_poly1305_init (&ctx, nacl_key, POLY1305_KEYLEN);
+  _gcry_poly1305_update (&ctx, nacl_msg + 0, 32);
+  _gcry_poly1305_update (&ctx, nacl_msg + 32, 64);
+  _gcry_poly1305_update (&ctx, nacl_msg + 96, 16);
+  _gcry_poly1305_update (&ctx, nacl_msg + 112, 8);
+  _gcry_poly1305_update (&ctx, nacl_msg + 120, 4);
+  _gcry_poly1305_update (&ctx, nacl_msg + 124, 2);
+  _gcry_poly1305_update (&ctx, nacl_msg + 126, 1);
+  _gcry_poly1305_update (&ctx, nacl_msg + 127, 1);
+  _gcry_poly1305_update (&ctx, nacl_msg + 128, 1);
+  _gcry_poly1305_update (&ctx, nacl_msg + 129, 1);
+  _gcry_poly1305_update (&ctx, nacl_msg + 130, 1);
+  _gcry_poly1305_finish (&ctx, mac);
+  if (memcmp (nacl_mac, mac, sizeof (nacl_mac)) != 0)
+    return "Poly1305 test 2 failed.";
+
+  memset (mac, 0, sizeof (mac));
+  poly1305_auth (mac, wrap_msg, sizeof (wrap_msg), wrap_key);
+  if (memcmp (wrap_mac, mac, sizeof (nacl_mac)) != 0)
+    return "Poly1305 test 3 failed.";
+
+  _gcry_poly1305_init (&total_ctx, total_key, POLY1305_KEYLEN);
+  for (i = 0; i < 256; i++)
+    {
+      /* set key and message to 'i,i,i..' */
+      for (j = 0; j < sizeof (all_key); j++)
+       all_key[j] = i;
+      for (j = 0; j < i; j++)
+       all_msg[j] = i;
+      poly1305_auth (mac, all_msg, i, all_key);
+      _gcry_poly1305_update (&total_ctx, mac, 16);
+    }
+  _gcry_poly1305_finish (&total_ctx, mac);
+  if (memcmp (total_mac, mac, sizeof (total_mac)) != 0)
+    return "Poly1305 test 4 failed.";
+
+  return NULL;
+}
index dd1f2ea..cccda84 100644 (file)
@@ -29,7 +29,6 @@
 #include "g10lib.h"
 #include "mpi.h"
 #include "cipher.h"
-#include "ath.h"
 
 static gcry_mpi_t gen_prime (unsigned int nbits, int secret, int randomlevel,
                              int (*extra_check)(void *, gcry_mpi_t),
@@ -141,18 +140,15 @@ struct primepool_s
 };
 struct primepool_s *primepool;
 /* Mutex used to protect access to the primepool.  */
-static ath_mutex_t primepool_lock;
+GPGRT_LOCK_DEFINE (primepool_lock);
 
 
 gcry_err_code_t
 _gcry_primegen_init (void)
 {
-  gcry_err_code_t ec;
-
-  ec = ath_mutex_init (&primepool_lock);
-  if (ec)
-    return gpg_err_code_from_errno (ec);
-  return ec;
+  /* This function was formerly used to initialize the primepool
+     Mutex. This has been replace by a static initialization.  */
+  return 0;
 }
 
 
@@ -446,12 +442,11 @@ prime_generate_internal (int need_q_factor,
               goto leave;
             }
 
-          if (ath_mutex_lock (&primepool_lock))
-            {
-              err = GPG_ERR_INTERNAL;
-              goto leave;
-            }
+          err = gpgrt_lock_lock (&primepool_lock);
+          if (err)
+            goto leave;
           is_locked = 1;
+
           for (i = 0; i < n; i++)
             {
               perms[i] = 1;
@@ -470,11 +465,9 @@ prime_generate_internal (int need_q_factor,
                   pool[i] = get_pool_prime (fbits, poolrandomlevel);
                   if (!pool[i])
                     {
-                      if (ath_mutex_unlock (&primepool_lock))
-                        {
-                          err = GPG_ERR_INTERNAL;
-                          goto leave;
-                        }
+                      err = gpgrt_lock_unlock (&primepool_lock);
+                      if (err)
+                        goto leave;
                       is_locked = 0;
                     }
                 }
@@ -483,23 +476,20 @@ prime_generate_internal (int need_q_factor,
               pool_in_use[i] = i;
               factors[i] = pool[i];
             }
-          if (is_locked && ath_mutex_unlock (&primepool_lock))
-            {
-              err = GPG_ERR_INTERNAL;
-              goto leave;
-            }
+
+          if (is_locked && (err = gpgrt_lock_unlock (&primepool_lock)))
+            goto leave;
           is_locked = 0;
         }
       else
         {
           /* Get next permutation. */
           m_out_of_n ( (char*)perms, n, m);
-          if (ath_mutex_lock (&primepool_lock))
-            {
-              err = GPG_ERR_INTERNAL;
-              goto leave;
-            }
+
+          if ((err = gpgrt_lock_lock (&primepool_lock)))
+            goto leave;
           is_locked = 1;
+
           for (i = j = 0; (i < m) && (j < n); i++)
             if (perms[i])
               {
@@ -509,11 +499,8 @@ prime_generate_internal (int need_q_factor,
                     pool[i] = get_pool_prime (fbits, poolrandomlevel);
                     if (!pool[i])
                       {
-                        if (ath_mutex_unlock (&primepool_lock))
-                          {
-                            err = GPG_ERR_INTERNAL;
-                            goto leave;
-                          }
+                        if ((err = gpgrt_lock_unlock (&primepool_lock)))
+                          goto leave;
                         is_locked = 0;
                       }
                   }
@@ -522,12 +509,11 @@ prime_generate_internal (int need_q_factor,
                 pool_in_use[j] = i;
                 factors[j++] = pool[i];
               }
-          if (is_locked && ath_mutex_unlock (&primepool_lock))
-            {
-              err = GPG_ERR_INTERNAL;
-              goto leave;
-            }
+
+          if (is_locked && (err = gpgrt_lock_unlock (&primepool_lock)))
+            goto leave;
           is_locked = 0;
+
           if (i == n)
             {
               /* Ran out of permutations: Allocate new primes.  */
@@ -636,47 +622,44 @@ prime_generate_internal (int need_q_factor,
         }
     }
 
-  if (g)
+  if (g && need_q_factor)
+    err = GPG_ERR_NOT_IMPLEMENTED;
+  else if (g)
     {
       /* Create a generator (start with 3).  */
       gcry_mpi_t tmp = mpi_alloc (mpi_get_nlimbs (prime));
       gcry_mpi_t b = mpi_alloc (mpi_get_nlimbs (prime));
       gcry_mpi_t pmin1 = mpi_alloc (mpi_get_nlimbs (prime));
 
-      if (need_q_factor)
-        err = GPG_ERR_NOT_IMPLEMENTED;
-      else
+      factors[n] = q;
+      factors[n + 1] = mpi_alloc_set_ui (2);
+      mpi_sub_ui (pmin1, prime, 1);
+      mpi_set_ui (g, 2);
+      do
         {
-          factors[n] = q;
-          factors[n + 1] = mpi_alloc_set_ui (2);
-          mpi_sub_ui (pmin1, prime, 1);
-          mpi_set_ui (g, 2);
-          do
+          mpi_add_ui (g, g, 1);
+          if (DBG_CIPHER)
+            log_printmpi ("checking g", g);
+          else
+            progress('^');
+          for (i = 0; i < n + 2; i++)
             {
-              mpi_add_ui (g, g, 1);
-              if (DBG_CIPHER)
-                log_printmpi ("checking g", g);
-              else
-                progress('^');
-              for (i = 0; i < n + 2; i++)
-                {
-                  mpi_fdiv_q (tmp, pmin1, factors[i]);
-                  /* No mpi_pow(), but it is okay to use this with mod
-                     prime.  */
-                  mpi_powm (b, g, tmp, prime);
-                  if (! mpi_cmp_ui (b, 1))
-                    break;
-                }
-              if (DBG_CIPHER)
-                progress('\n');
+              mpi_fdiv_q (tmp, pmin1, factors[i]);
+              /* No mpi_pow(), but it is okay to use this with mod
+                 prime.  */
+              mpi_powm (b, g, tmp, prime);
+              if (! mpi_cmp_ui (b, 1))
+                break;
             }
-          while (i < n + 2);
-
-          mpi_free (factors[n+1]);
-          mpi_free (tmp);
-          mpi_free (b);
-          mpi_free (pmin1);
+          if (DBG_CIPHER)
+            progress('\n');
         }
+      while (i < n + 2);
+
+      mpi_free (factors[n+1]);
+      mpi_free (tmp);
+      mpi_free (b);
+      mpi_free (pmin1);
     }
 
   if (! DBG_CIPHER)
@@ -686,7 +669,7 @@ prime_generate_internal (int need_q_factor,
  leave:
   if (pool)
     {
-      is_locked = !ath_mutex_lock (&primepool_lock);
+      is_locked = !gpgrt_lock_lock (&primepool_lock);
       for(i = 0; i < m; i++)
         {
           if (pool[i])
@@ -703,8 +686,8 @@ prime_generate_internal (int need_q_factor,
                 mpi_free (pool[i]);
             }
         }
-      if (is_locked && ath_mutex_unlock (&primepool_lock))
-        err = GPG_ERR_INTERNAL;
+      if (is_locked)
+        err = gpgrt_lock_unlock (&primepool_lock);
       is_locked = 0;
       xfree (pool);
     }
@@ -882,7 +865,7 @@ check_prime( gcry_mpi_t prime, gcry_mpi_t val_2, int rm_rounds,
   for (i=0; (x = small_prime_numbers[i]); i++ )
     {
       if ( mpi_divisible_ui( prime, x ) )
-        return 0;
+        return !mpi_cmp_ui (prime, x);
     }
 
   /* A quick Fermat test. */
@@ -1183,21 +1166,43 @@ _gcry_prime_generate (gcry_mpi_t *prime, unsigned int prime_bits,
 gcry_err_code_t
 _gcry_prime_check (gcry_mpi_t x, unsigned int flags)
 {
-  gcry_err_code_t rc = 0;
-  gcry_mpi_t val_2 = mpi_alloc_set_ui (2); /* Used by the Fermat test. */
-
   (void)flags;
 
+  switch (mpi_cmp_ui (x, 2))
+    {
+    case 0:  return 0;                /* 2 is a prime */
+    case -1: return GPG_ERR_NO_PRIME; /* Only numbers > 1 are primes.  */
+    }
+
   /* We use 64 rounds because the prime we are going to test is not
      guaranteed to be a random one. */
-  if (! check_prime (x, val_2, 64, NULL, NULL))
-    rc = GPG_ERR_NO_PRIME;
+  if (check_prime (x, mpi_const (MPI_C_TWO), 64, NULL, NULL))
+    return 0;
 
-  mpi_free (val_2);
+  return GPG_ERR_NO_PRIME;
+}
 
-  return rc;
+
+/* Check whether the number X is prime according to FIPS 186-4 table C.2.  */
+gcry_err_code_t
+_gcry_fips186_4_prime_check (gcry_mpi_t x, unsigned int bits)
+{
+  gcry_err_code_t ec = GPG_ERR_NO_ERROR;
+
+  switch (mpi_cmp_ui (x, 2))
+    {
+    case 0:  return ec;               /* 2 is a prime */
+    case -1: return GPG_ERR_NO_PRIME; /* Only numbers > 1 are primes.  */
+    }
+
+  /* We use 5 or 4 rounds as specified in table C.2 */
+  if (! check_prime (x, mpi_const (MPI_C_TWO), bits > 1024 ? 4 : 5, NULL, NULL))
+    ec = GPG_ERR_NO_PRIME;
+
+  return ec;
 }
 
+
 /* Find a generator for PRIME where the factorization of (prime-1) is
    in the NULL terminated array FACTORS. Return the generator as a
    newly allocated MPI in R_G.  If START_G is not NULL, use this as s
@@ -1207,22 +1212,25 @@ _gcry_prime_group_generator (gcry_mpi_t *r_g,
                              gcry_mpi_t prime, gcry_mpi_t *factors,
                              gcry_mpi_t start_g)
 {
-  gcry_mpi_t tmp   = mpi_new (0);
-  gcry_mpi_t b     = mpi_new (0);
-  gcry_mpi_t pmin1 = mpi_new (0);
-  gcry_mpi_t g = start_g? mpi_copy (start_g) : mpi_set_ui (NULL, 3);
-  int first = 1;
-  int i, n;
-
-  if (!factors || !r_g || !prime)
+  gcry_mpi_t tmp, b, pmin1, g;
+  int first, i, n;
+
+  if (!r_g)
     return GPG_ERR_INV_ARG;
   *r_g = NULL;
+  if (!factors || !prime)
+    return GPG_ERR_INV_ARG;
 
   for (n=0; factors[n]; n++)
     ;
   if (n < 2)
     return GPG_ERR_INV_ARG;
 
+  tmp   = mpi_new (0);
+  b     = mpi_new (0);
+  pmin1 = mpi_new (0);
+  g     = start_g? mpi_copy (start_g) : mpi_set_ui (NULL, 3);
+
   /* Extra sanity check - usually disabled. */
 /*   mpi_set (tmp, factors[0]); */
 /*   for(i = 1; i < n; i++) */
@@ -1232,6 +1240,7 @@ _gcry_prime_group_generator (gcry_mpi_t *r_g,
 /*     return gpg_error (GPG_ERR_INV_ARG); */
 
   mpi_sub_ui (pmin1, prime, 1);
+  first = 1;
   do
     {
       if (first)
@@ -1624,23 +1633,21 @@ _gcry_generate_fips186_2_prime (unsigned int pbits, unsigned int qbits,
 
 
 \f
-/* WARNING: The code below has not yet been tested!  However, it is
-   not yet used.  We need to wait for FIPS 186-3 final and for test
-   vectors.
-
-   Generate the two prime used for DSA using the algorithm specified
-   in FIPS 186-3, A.1.1.2.  PBITS is the desired length of the prime P
-   and a QBITS the length of the prime Q.  If SEED is not supplied and
-   SEEDLEN is 0 the function generates an appropriate SEED.  On
-   success the generated primes are stored at R_Q and R_P, the counter
-   value is stored at R_COUNTER and the seed actually used for
-   generation is stored at R_SEED and R_SEEDVALUE.  The hash algorithm
-   used is stored at R_HASHALGO.
-
-   Note that this function is very similar to the fips186_2 code.  Due
-   to the minor differences, other buffer sizes and for documentarion,
-   we use a separate function.
-*/
+/* WARNING: The code below has not yet been tested!
+ *
+ * Generate the two prime used for DSA using the algorithm specified
+ * in FIPS 186-3, A.1.1.2.  PBITS is the desired length of the prime P
+ * and a QBITS the length of the prime Q.  If SEED is not supplied and
+ * SEEDLEN is 0 the function generates an appropriate SEED.  On
+ * success the generated primes are stored at R_Q and R_P, the counter
+ * value is stored at R_COUNTER and the seed actually used for
+ * generation is stored at R_SEED and R_SEEDVALUE.  The hash algorithm
+ * used is stored at R_HASHALGO.
+ *
+ * Note that this function is very similar to the fips186_2 code.  Due
+ * to the minor differences, other buffer sizes and for documentarion,
+ * we use a separate function.
+ */
 gpg_err_code_t
 _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits,
                                 const void *seed, size_t seedlen,
@@ -1652,7 +1659,7 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits,
   gpg_err_code_t ec;
   unsigned char seed_help_buffer[256/8];  /* Used to hold a generated SEED. */
   unsigned char *seed_plus;     /* Malloced buffer to hold SEED+x.  */
-  unsigned char digest[256/8];  /* Helper buffer for SHA-1 digest.  */
+  unsigned char digest[256/8];  /* Helper buffer for SHA-2 digest.  */
   gcry_mpi_t val_2 = NULL;      /* Helper for the prime test.  */
   gcry_mpi_t tmpval = NULL;     /* Helper variable.  */
   int hashalgo;                 /* The id of the Approved Hash Function.  */
@@ -1671,9 +1678,7 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits,
 
   /* Step 1:  Check the requested prime lengths.  */
   /* Note that due to the size of our buffers QBITS is limited to 256.  */
-  if (pbits == 1024 && qbits == 160)
-    hashalgo = GCRY_MD_SHA1;
-  else if (pbits == 2048 && qbits == 224)
+  if (pbits == 2048 && qbits == 224)
     hashalgo = GCRY_MD_SHA224;
   else if (pbits == 2048 && qbits == 256)
     hashalgo = GCRY_MD_SHA256;
@@ -1742,7 +1747,7 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits,
         }
       _gcry_mpi_release (prime_q); prime_q = NULL;
       ec = _gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG,
-                           value_u, sizeof value_u, NULL);
+                           value_u, qbits/8, NULL);
       if (ec)
         goto leave;
       mpi_set_highbit (prime_q, qbits-1 );
@@ -1787,11 +1792,11 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits,
               if (seed_plus[i])
                 break;
             }
-          _gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen);
+          _gcry_md_hash_buffer (hashalgo, digest, seed_plus, seedlen);
 
           _gcry_mpi_release (tmpval); tmpval = NULL;
           ec = _gcry_mpi_scan (&tmpval, GCRYMPI_FMT_USG,
-                               digest, sizeof digest, NULL);
+                               digest, qbits/8, NULL);
           if (ec)
             goto leave;
           if (value_j == value_n)
@@ -1827,11 +1832,12 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits,
     }
 
   /* Step 12:  Save p, q, counter and seed.  */
-  log_debug ("fips186-3 pbits p=%u q=%u counter=%d\n",
-             mpi_get_nbits (prime_p), mpi_get_nbits (prime_q), counter);
-  log_printhex ("fips186-3 seed", seed, seedlen);
-  log_printmpi ("fips186-3    p", prime_p);
-  log_printmpi ("fips186-3    q", prime_q);
+  /* log_debug ("fips186-3 pbits p=%u q=%u counter=%d\n", */
+  /*            mpi_get_nbits (prime_p), mpi_get_nbits (prime_q), counter); */
+  /* log_printhex ("fips186-3 seed", seed, seedlen); */
+  /* log_printmpi ("fips186-3    p", prime_p); */
+  /* log_printmpi ("fips186-3    q", prime_q); */
+
   if (r_q)
     {
       *r_q = prime_q;
index 193248c..b8167c7 100644 (file)
@@ -56,6 +56,10 @@ gpg_err_code_t
 _gcry_rsa_pkcs1_decode_for_enc (unsigned char **r_result, size_t *r_resultlen,
                                 unsigned int nbits, gcry_mpi_t value);
 gpg_err_code_t
+_gcry_rsa_pkcs1_encode_raw_for_sig (gcry_mpi_t *r_result, unsigned int nbits,
+                                const unsigned char *value, size_t valuelen);
+
+gpg_err_code_t
 _gcry_rsa_pkcs1_encode_for_sig (gcry_mpi_t *r_result, unsigned int nbits,
                                 const unsigned char *value, size_t valuelen,
                                 int algo);
index 616b499..c40ef97 100644 (file)
@@ -1,7 +1,7 @@
 /* pubkey-util.c - Supporting functions for all pubkey modules.
  * Copyright (C) 1998, 1999, 2000, 2002, 2003, 2005,
  *               2007, 2008, 2011 Free Software Foundation, Inc.
- * Copyright (C) 2013  g10 Code GmbH
+ * Copyright (C) 2013, 2015 g10 Code GmbH
  *
  * This file is part of Libgcrypt.
  *
@@ -107,6 +107,7 @@ _gcry_pk_util_parse_flaglist (gcry_sexp_t list,
             {
               encoding = PUBKEY_ENC_RAW;
               flags |= PUBKEY_FLAG_EDDSA;
+              flags |= PUBKEY_FLAG_DJB_TWEAK;
             }
           else if (!memcmp (s, "pkcs1", 5) && encoding == PUBKEY_ENC_UNKNOWN)
             {
@@ -142,9 +143,28 @@ _gcry_pk_util_parse_flaglist (gcry_sexp_t list,
             rc = GPG_ERR_INV_FLAG;
           break;
 
+        case 9:
+          if (!memcmp (s, "pkcs1-raw", 9) && encoding == PUBKEY_ENC_UNKNOWN)
+            {
+              encoding = PUBKEY_ENC_PKCS1_RAW;
+              flags |= PUBKEY_FLAG_FIXEDLEN;
+            }
+          else if (!memcmp (s, "djb-tweak", 9))
+            {
+              encoding = PUBKEY_ENC_RAW;
+              flags |= PUBKEY_FLAG_DJB_TWEAK;
+            }
+          else if (!igninvflag)
+            rc = GPG_ERR_INV_FLAG;
+          break;
+
         case 10:
           if (!memcmp (s, "igninvflag", 10))
             igninvflag = 1;
+          else if (!memcmp (s, "no-keytest", 10))
+            flags |= PUBKEY_FLAG_NO_KEYTEST;
+          else if (!igninvflag)
+            rc = GPG_ERR_INV_FLAG;
           break;
 
         case 11:
@@ -197,6 +217,10 @@ get_hash_algo (const char *s, size_t n)
     { "md4",    GCRY_MD_MD4 },
     { "tiger",  GCRY_MD_TIGER },
     { "haval",  GCRY_MD_HAVAL },
+    { "sha3-224", GCRY_MD_SHA3_224 },
+    { "sha3-256", GCRY_MD_SHA3_256 },
+    { "sha3-384", GCRY_MD_SHA3_384 },
+    { "sha3-512", GCRY_MD_SHA3_512 },
     { NULL, 0 }
   };
   int algo;
@@ -593,7 +617,14 @@ _gcry_pk_util_init_encoding_ctx (struct pk_encoding_ctx *ctx,
   ctx->nbits = nbits;
   ctx->encoding = PUBKEY_ENC_UNKNOWN;
   ctx->flags = 0;
-  ctx->hash_algo = GCRY_MD_SHA1;
+  if (fips_mode ())
+    {
+      ctx->hash_algo = GCRY_MD_SHA256;
+    }
+  else
+    {
+      ctx->hash_algo = GCRY_MD_SHA1;
+    }
   ctx->label = NULL;
   ctx->labellen = 0;
   ctx->saltlen = 20;
@@ -634,7 +665,7 @@ _gcry_pk_util_free_encoding_ctx (struct pk_encoding_ctx *ctx)
 
    LABEL is specific to OAEP.
 
-   SALT-LENGTH is for PSS.
+   SALT-LENGTH is for PSS it is limited to 16384 bytes.
 
    RANDOM-OVERRIDE is used to replace random nonces for regression
    testing.  */
@@ -850,6 +881,21 @@ _gcry_pk_util_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi,
                                                  ctx->hash_algo);
         }
     }
+  else if (ctx->encoding == PUBKEY_ENC_PKCS1_RAW && lvalue
+          && (ctx->op == PUBKEY_OP_SIGN || ctx->op == PUBKEY_OP_VERIFY))
+    {
+      const void * value;
+      size_t valuelen;
+
+      if (sexp_length (lvalue) != 2)
+        rc = GPG_ERR_INV_OBJ;
+      else if ( !(value=sexp_nth_data (lvalue, 1, &valuelen))
+                || !valuelen )
+        rc = GPG_ERR_INV_OBJ;
+      else
+        rc = _gcry_rsa_pkcs1_encode_raw_for_sig (ret_mpi, ctx->nbits,
+                                                 value, valuelen);
+    }
   else if (ctx->encoding == PUBKEY_ENC_OAEP && lvalue
           && ctx->op == PUBKEY_OP_ENCRYPT)
     {
@@ -1022,6 +1068,31 @@ _gcry_pk_util_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi,
             rc = GPG_ERR_DIGEST_ALGO;
          else
            {
+             gcry_sexp_t list;
+             /* Get SALT-LENGTH. */
+             list = sexp_find_token (ldata, "salt-length", 0);
+             if (list)
+               {
+                  unsigned long ul;
+
+                 s = sexp_nth_data (list, 1, &n);
+                 if (!s)
+                   {
+                     rc = GPG_ERR_NO_OBJ;
+                      sexp_release (list);
+                     goto leave;
+                   }
+                 ul = strtoul (s, NULL, 10);
+                  if (ul > 16384)
+                    {
+                      rc = GPG_ERR_TOO_LARGE;
+                      sexp_release (list);
+                      goto leave;
+                    }
+                  ctx->saltlen = ul;
+                 sexp_release (list);
+               }
+
              *ret_mpi = sexp_nth_mpi (lhash, 2, GCRYMPI_FMT_USG);
              if (!*ret_mpi)
                rc = GPG_ERR_INV_OBJ;
index b31e9df..8ec15fd 100644 (file)
@@ -28,7 +28,6 @@
 #include "g10lib.h"
 #include "mpi.h"
 #include "cipher.h"
-#include "ath.h"
 #include "context.h"
 #include "pubkey-internal.h"
 
@@ -115,7 +114,7 @@ spec_from_name (const char *name)
  * set the function will only succeed if a private key has been given.
  * On success the spec is stored at R_SPEC.  On error NULL is stored
  * at R_SPEC and an error code returned.  If R_PARMS is not NULL and
- * the fucntion returns success, the parameter list below
+ * the function returns success, the parameter list below
  * "private-key" or "public-key" is stored there and the caller must
  * call gcry_sexp_release on it.
  */
@@ -927,6 +926,17 @@ _gcry_pubkey_get_sexp (gcry_sexp_t *r_sexp, int mode, gcry_ctx_t ctx)
 gcry_err_code_t
 _gcry_pk_init (void)
 {
+  if (fips_mode())
+    {
+      /* disable algorithms that are disallowed in fips */
+      int idx;
+      gcry_pk_spec_t *spec;
+
+      for (idx = 0; (spec = pubkey_list[idx]); idx++)
+        if (!spec->flags.fips)
+          spec->flags.disabled = 1;
+    }
+
   return 0;
 }
 
@@ -946,7 +956,7 @@ _gcry_pk_selftest (int algo, int extended, selftest_report_func_t report)
   else
     {
       ec = GPG_ERR_PUBKEY_ALGO;
-      /* Fixme: We need to change the report fucntion to allow passing
+      /* Fixme: We need to change the report function to allow passing
          of an encryption mode (e.g. pkcs1, ecdsa, or ecdh).  */
       if (report)
         report ("pubkey", algo, "module",
diff --git a/cipher/rijndael-aesni.c b/cipher/rijndael-aesni.c
new file mode 100644 (file)
index 0000000..97e0ad0
--- /dev/null
@@ -0,0 +1,1892 @@
+/* AES-NI accelerated AES for Libgcrypt
+ * Copyright (C) 2000, 2001, 2002, 2003, 2007,
+ *               2008, 2011, 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* for memcmp() */
+
+#include "types.h"  /* for byte and u32 typedefs */
+#include "g10lib.h"
+#include "cipher.h"
+#include "bufhelp.h"
+#include "cipher-selftest.h"
+#include "rijndael-internal.h"
+#include "./cipher-internal.h"
+
+
+#ifdef USE_AESNI
+
+
+#if _GCRY_GCC_VERSION >= 40400 /* 4.4 */
+/* Prevent compiler from issuing SSE instructions between asm blocks. */
+#  pragma GCC target("no-sse")
+#endif
+
+
+typedef struct u128_s { u32 a, b, c, d; } u128_t;
+
+
+/* Two macros to be called prior and after the use of AESNI
+   instructions.  There should be no external function calls between
+   the use of these macros.  There purpose is to make sure that the
+   SSE regsiters are cleared and won't reveal any information about
+   the key or the data.  */
+#ifdef __WIN64__
+/* XMM6-XMM15 are callee-saved registers on WIN64. */
+# define aesni_prepare_2_6_variable char win64tmp[16]
+# define aesni_prepare() do { } while (0)
+# define aesni_prepare_2_6()                                            \
+   do { asm volatile ("movdqu %%xmm6, %0\n\t"                           \
+                      : "=m" (*win64tmp)                                \
+                      :                                                 \
+                      : "memory");                                      \
+   } while (0)
+# define aesni_cleanup()                                                \
+   do { asm volatile ("pxor %%xmm0, %%xmm0\n\t"                         \
+                      "pxor %%xmm1, %%xmm1\n" :: );                     \
+   } while (0)
+# define aesni_cleanup_2_6()                                            \
+   do { asm volatile ("movdqu %0,   %%xmm6\n\t"                         \
+                      "pxor %%xmm2, %%xmm2\n"                           \
+                      "pxor %%xmm3, %%xmm3\n"                           \
+                      "pxor %%xmm4, %%xmm4\n"                           \
+                      "pxor %%xmm5, %%xmm5\n"                           \
+                      :                                                 \
+                      : "m" (*win64tmp)                                 \
+                      : "memory");                                      \
+   } while (0)
+#else
+# define aesni_prepare_2_6_variable
+# define aesni_prepare() do { } while (0)
+# define aesni_prepare_2_6() do { } while (0)
+# define aesni_cleanup()                                                \
+   do { asm volatile ("pxor %%xmm0, %%xmm0\n\t"                         \
+                      "pxor %%xmm1, %%xmm1\n" :: );                     \
+   } while (0)
+# define aesni_cleanup_2_6()                                            \
+   do { asm volatile ("pxor %%xmm2, %%xmm2\n\t"                         \
+                      "pxor %%xmm3, %%xmm3\n"                           \
+                      "pxor %%xmm4, %%xmm4\n"                           \
+                      "pxor %%xmm5, %%xmm5\n"                           \
+                      "pxor %%xmm6, %%xmm6\n":: );                      \
+   } while (0)
+#endif
+
+void
+_gcry_aes_aesni_do_setkey (RIJNDAEL_context *ctx, const byte *key)
+{
+  aesni_prepare_2_6_variable;
+
+  aesni_prepare();
+  aesni_prepare_2_6();
+
+  if (ctx->rounds < 12)
+    {
+      /* 128-bit key */
+#define AESKEYGENASSIST_xmm1_xmm2(imm8) \
+       ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd1, " #imm8 " \n\t"
+#define AESKEY_EXPAND128 \
+       "pshufd $0xff, %%xmm2, %%xmm2\n\t" \
+       "movdqa %%xmm1, %%xmm3\n\t" \
+       "pslldq $4, %%xmm3\n\t" \
+       "pxor   %%xmm3, %%xmm1\n\t" \
+       "pslldq $4, %%xmm3\n\t" \
+       "pxor   %%xmm3, %%xmm1\n\t" \
+       "pslldq $4, %%xmm3\n\t" \
+       "pxor   %%xmm3, %%xmm2\n\t" \
+       "pxor   %%xmm2, %%xmm1\n\t"
+
+      asm volatile ("movdqu (%[key]), %%xmm1\n\t"     /* xmm1 := key   */
+                    "movdqa %%xmm1, (%[ksch])\n\t"     /* ksch[0] := xmm1  */
+                    AESKEYGENASSIST_xmm1_xmm2(0x01)
+                    AESKEY_EXPAND128
+                    "movdqa %%xmm1, 0x10(%[ksch])\n\t" /* ksch[1] := xmm1  */
+                    AESKEYGENASSIST_xmm1_xmm2(0x02)
+                    AESKEY_EXPAND128
+                    "movdqa %%xmm1, 0x20(%[ksch])\n\t" /* ksch[2] := xmm1  */
+                    AESKEYGENASSIST_xmm1_xmm2(0x04)
+                    AESKEY_EXPAND128
+                    "movdqa %%xmm1, 0x30(%[ksch])\n\t" /* ksch[3] := xmm1  */
+                    AESKEYGENASSIST_xmm1_xmm2(0x08)
+                    AESKEY_EXPAND128
+                    "movdqa %%xmm1, 0x40(%[ksch])\n\t" /* ksch[4] := xmm1  */
+                    AESKEYGENASSIST_xmm1_xmm2(0x10)
+                    AESKEY_EXPAND128
+                    "movdqa %%xmm1, 0x50(%[ksch])\n\t" /* ksch[5] := xmm1  */
+                    AESKEYGENASSIST_xmm1_xmm2(0x20)
+                    AESKEY_EXPAND128
+                    "movdqa %%xmm1, 0x60(%[ksch])\n\t" /* ksch[6] := xmm1  */
+                    AESKEYGENASSIST_xmm1_xmm2(0x40)
+                    AESKEY_EXPAND128
+                    "movdqa %%xmm1, 0x70(%[ksch])\n\t" /* ksch[7] := xmm1  */
+                    AESKEYGENASSIST_xmm1_xmm2(0x80)
+                    AESKEY_EXPAND128
+                    "movdqa %%xmm1, 0x80(%[ksch])\n\t" /* ksch[8] := xmm1  */
+                    AESKEYGENASSIST_xmm1_xmm2(0x1b)
+                    AESKEY_EXPAND128
+                    "movdqa %%xmm1, 0x90(%[ksch])\n\t" /* ksch[9] := xmm1  */
+                    AESKEYGENASSIST_xmm1_xmm2(0x36)
+                    AESKEY_EXPAND128
+                    "movdqa %%xmm1, 0xa0(%[ksch])\n\t" /* ksch[10] := xmm1  */
+                    :
+                    : [key] "r" (key), [ksch] "r" (ctx->keyschenc)
+                    : "cc", "memory" );
+#undef AESKEYGENASSIST_xmm1_xmm2
+#undef AESKEY_EXPAND128
+    }
+  else if (ctx->rounds == 12)
+    {
+      /* 192-bit key */
+#define AESKEYGENASSIST_xmm3_xmm2(imm8) \
+       ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd3, " #imm8 " \n\t"
+#define AESKEY_EXPAND192 \
+       "pshufd $0x55, %%xmm2, %%xmm2\n\t" \
+       "movdqu %%xmm1, %%xmm4\n\t" \
+       "pslldq $4, %%xmm4\n\t" \
+       "pxor %%xmm4, %%xmm1\n\t" \
+       "pslldq $4, %%xmm4\n\t" \
+       "pxor %%xmm4, %%xmm1\n\t" \
+       "pslldq $4, %%xmm4\n\t" \
+       "pxor %%xmm4, %%xmm1\n\t" \
+       "pxor %%xmm2, %%xmm1\n\t" \
+       "pshufd $0xff, %%xmm1, %%xmm2\n\t" \
+       "movdqu %%xmm3, %%xmm4\n\t" \
+       "pslldq $4, %%xmm4\n\t" \
+       "pxor %%xmm4, %%xmm3\n\t" \
+       "pxor %%xmm2, %%xmm3\n\t"
+
+      asm volatile ("movdqu (%[key]), %%xmm1\n\t"     /* xmm1 := key[0..15]   */
+                    "movq 16(%[key]), %%xmm3\n\t"     /* xmm3 := key[16..23]  */
+                    "movdqa %%xmm1, (%[ksch])\n\t"    /* ksch[0] := xmm1  */
+                    "movdqa %%xmm3, %%xmm5\n\t"
+
+                    AESKEYGENASSIST_xmm3_xmm2(0x01)
+                    AESKEY_EXPAND192
+                    "shufpd $0, %%xmm1, %%xmm5\n\t"
+                    "movdqa %%xmm5, 0x10(%[ksch])\n\t" /* ksch[1] := xmm5  */
+                    "movdqa %%xmm1, %%xmm6\n\t"
+                    "shufpd $1, %%xmm3, %%xmm6\n\t"
+                    "movdqa %%xmm6, 0x20(%[ksch])\n\t" /* ksch[2] := xmm6  */
+                    AESKEYGENASSIST_xmm3_xmm2(0x02)
+                    AESKEY_EXPAND192
+                    "movdqa %%xmm1, 0x30(%[ksch])\n\t" /* ksch[3] := xmm1  */
+                    "movdqa %%xmm3, %%xmm5\n\t"
+
+                    AESKEYGENASSIST_xmm3_xmm2(0x04)
+                    AESKEY_EXPAND192
+                    "shufpd $0, %%xmm1, %%xmm5\n\t"
+                    "movdqa %%xmm5, 0x40(%[ksch])\n\t" /* ksch[4] := xmm5  */
+                    "movdqa %%xmm1, %%xmm6\n\t"
+                    "shufpd $1, %%xmm3, %%xmm6\n\t"
+                    "movdqa %%xmm6, 0x50(%[ksch])\n\t" /* ksch[5] := xmm6  */
+                    AESKEYGENASSIST_xmm3_xmm2(0x08)
+                    AESKEY_EXPAND192
+                    "movdqa %%xmm1, 0x60(%[ksch])\n\t" /* ksch[6] := xmm1  */
+                    "movdqa %%xmm3, %%xmm5\n\t"
+
+                    AESKEYGENASSIST_xmm3_xmm2(0x10)
+                    AESKEY_EXPAND192
+                    "shufpd $0, %%xmm1, %%xmm5\n\t"
+                    "movdqa %%xmm5, 0x70(%[ksch])\n\t" /* ksch[7] := xmm5  */
+                    "movdqa %%xmm1, %%xmm6\n\t"
+                    "shufpd $1, %%xmm3, %%xmm6\n\t"
+                    "movdqa %%xmm6, 0x80(%[ksch])\n\t" /* ksch[8] := xmm6  */
+                    AESKEYGENASSIST_xmm3_xmm2(0x20)
+                    AESKEY_EXPAND192
+                    "movdqa %%xmm1, 0x90(%[ksch])\n\t" /* ksch[9] := xmm1  */
+                    "movdqa %%xmm3, %%xmm5\n\t"
+
+                    AESKEYGENASSIST_xmm3_xmm2(0x40)
+                    AESKEY_EXPAND192
+                    "shufpd $0, %%xmm1, %%xmm5\n\t"
+                    "movdqa %%xmm5, 0xa0(%[ksch])\n\t" /* ksch[10] := xmm5  */
+                    "movdqa %%xmm1, %%xmm6\n\t"
+                    "shufpd $1, %%xmm3, %%xmm6\n\t"
+                    "movdqa %%xmm6, 0xb0(%[ksch])\n\t" /* ksch[11] := xmm6  */
+                    AESKEYGENASSIST_xmm3_xmm2(0x80)
+                    AESKEY_EXPAND192
+                    "movdqa %%xmm1, 0xc0(%[ksch])\n\t" /* ksch[12] := xmm1  */
+                    :
+                    : [key] "r" (key), [ksch] "r" (ctx->keyschenc)
+                    : "cc", "memory" );
+#undef AESKEYGENASSIST_xmm3_xmm2
+#undef AESKEY_EXPAND192
+    }
+  else if (ctx->rounds > 12)
+    {
+      /* 256-bit key */
+#define AESKEYGENASSIST_xmm1_xmm2(imm8) \
+       ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd1, " #imm8 " \n\t"
+#define AESKEYGENASSIST_xmm3_xmm2(imm8) \
+       ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd3, " #imm8 " \n\t"
+#define AESKEY_EXPAND256_A \
+       "pshufd $0xff, %%xmm2, %%xmm2\n\t" \
+       "movdqa %%xmm1, %%xmm4\n\t" \
+       "pslldq $4, %%xmm4\n\t" \
+       "pxor %%xmm4, %%xmm1\n\t" \
+       "pslldq $4, %%xmm4\n\t" \
+       "pxor %%xmm4, %%xmm1\n\t" \
+       "pslldq $4, %%xmm4\n\t" \
+       "pxor %%xmm4, %%xmm1\n\t" \
+       "pxor %%xmm2, %%xmm1\n\t"
+#define AESKEY_EXPAND256_B \
+       "pshufd $0xaa, %%xmm2, %%xmm2\n\t" \
+       "movdqa %%xmm3, %%xmm4\n\t" \
+       "pslldq $4, %%xmm4\n\t" \
+       "pxor %%xmm4, %%xmm3\n\t" \
+       "pslldq $4, %%xmm4\n\t" \
+       "pxor %%xmm4, %%xmm3\n\t" \
+       "pslldq $4, %%xmm4\n\t" \
+       "pxor %%xmm4, %%xmm3\n\t" \
+       "pxor %%xmm2, %%xmm3\n\t"
+
+      asm volatile ("movdqu (%[key]), %%xmm1\n\t"     /* xmm1 := key[0..15]   */
+                    "movdqu 16(%[key]), %%xmm3\n\t"   /* xmm3 := key[16..31]  */
+                    "movdqa %%xmm1, (%[ksch])\n\t"     /* ksch[0] := xmm1  */
+                    "movdqa %%xmm3, 0x10(%[ksch])\n\t" /* ksch[1] := xmm3  */
+
+                    AESKEYGENASSIST_xmm3_xmm2(0x01)
+                    AESKEY_EXPAND256_A
+                    "movdqa %%xmm1, 0x20(%[ksch])\n\t" /* ksch[2] := xmm1  */
+                    AESKEYGENASSIST_xmm1_xmm2(0x00)
+                    AESKEY_EXPAND256_B
+                    "movdqa %%xmm3, 0x30(%[ksch])\n\t" /* ksch[3] := xmm3  */
+
+                    AESKEYGENASSIST_xmm3_xmm2(0x02)
+                    AESKEY_EXPAND256_A
+                    "movdqa %%xmm1, 0x40(%[ksch])\n\t" /* ksch[4] := xmm1  */
+                    AESKEYGENASSIST_xmm1_xmm2(0x00)
+                    AESKEY_EXPAND256_B
+                    "movdqa %%xmm3, 0x50(%[ksch])\n\t" /* ksch[5] := xmm3  */
+
+                    AESKEYGENASSIST_xmm3_xmm2(0x04)
+                    AESKEY_EXPAND256_A
+                    "movdqa %%xmm1, 0x60(%[ksch])\n\t" /* ksch[6] := xmm1  */
+                    AESKEYGENASSIST_xmm1_xmm2(0x00)
+                    AESKEY_EXPAND256_B
+                    "movdqa %%xmm3, 0x70(%[ksch])\n\t" /* ksch[7] := xmm3  */
+
+                    AESKEYGENASSIST_xmm3_xmm2(0x08)
+                    AESKEY_EXPAND256_A
+                    "movdqa %%xmm1, 0x80(%[ksch])\n\t" /* ksch[8] := xmm1  */
+                    AESKEYGENASSIST_xmm1_xmm2(0x00)
+                    AESKEY_EXPAND256_B
+                    "movdqa %%xmm3, 0x90(%[ksch])\n\t" /* ksch[9] := xmm3  */
+
+                    AESKEYGENASSIST_xmm3_xmm2(0x10)
+                    AESKEY_EXPAND256_A
+                    "movdqa %%xmm1, 0xa0(%[ksch])\n\t" /* ksch[10] := xmm1  */
+                    AESKEYGENASSIST_xmm1_xmm2(0x00)
+                    AESKEY_EXPAND256_B
+                    "movdqa %%xmm3, 0xb0(%[ksch])\n\t" /* ksch[11] := xmm3  */
+
+                    AESKEYGENASSIST_xmm3_xmm2(0x20)
+                    AESKEY_EXPAND256_A
+                    "movdqa %%xmm1, 0xc0(%[ksch])\n\t" /* ksch[12] := xmm1  */
+                    AESKEYGENASSIST_xmm1_xmm2(0x00)
+                    AESKEY_EXPAND256_B
+                    "movdqa %%xmm3, 0xd0(%[ksch])\n\t" /* ksch[13] := xmm3  */
+
+                    AESKEYGENASSIST_xmm3_xmm2(0x40)
+                    AESKEY_EXPAND256_A
+                    "movdqa %%xmm1, 0xe0(%[ksch])\n\t" /* ksch[14] := xmm1  */
+
+                    :
+                    : [key] "r" (key), [ksch] "r" (ctx->keyschenc)
+                    : "cc", "memory" );
+#undef AESKEYGENASSIST_xmm1_xmm2
+#undef AESKEYGENASSIST_xmm3_xmm2
+#undef AESKEY_EXPAND256_A
+#undef AESKEY_EXPAND256_B
+    }
+
+  aesni_cleanup();
+  aesni_cleanup_2_6();
+}
+
+
+/* Make a decryption key from an encryption key. */
+void
+_gcry_aes_aesni_prepare_decryption (RIJNDAEL_context *ctx)
+{
+  /* The AES-NI decrypt instructions use the Equivalent Inverse
+     Cipher, thus we can't use the the standard decrypt key
+     preparation.  */
+  u128_t *ekey = (u128_t *)ctx->keyschenc;
+  u128_t *dkey = (u128_t *)ctx->keyschdec;
+  int rr;
+  int r;
+
+  aesni_prepare();
+
+#define DO_AESNI_AESIMC() \
+  asm volatile ("movdqa %[ekey], %%xmm1\n\t" \
+                /*"aesimc %%xmm1, %%xmm1\n\t"*/ \
+                ".byte 0x66, 0x0f, 0x38, 0xdb, 0xc9\n\t" \
+                "movdqa %%xmm1, %[dkey]" \
+                : [dkey] "=m" (dkey[r]) \
+                : [ekey] "m" (ekey[rr]) \
+                : "memory")
+
+  dkey[0] = ekey[ctx->rounds];
+  r=1;
+  rr=ctx->rounds-1;
+  DO_AESNI_AESIMC(); r++; rr--; /* round 1 */
+  DO_AESNI_AESIMC(); r++; rr--; /* round 2 */
+  DO_AESNI_AESIMC(); r++; rr--; /* round 3 */
+  DO_AESNI_AESIMC(); r++; rr--; /* round 4 */
+  DO_AESNI_AESIMC(); r++; rr--; /* round 5 */
+  DO_AESNI_AESIMC(); r++; rr--; /* round 6 */
+  DO_AESNI_AESIMC(); r++; rr--; /* round 7 */
+  DO_AESNI_AESIMC(); r++; rr--; /* round 8 */
+  DO_AESNI_AESIMC(); r++; rr--; /* round 9 */
+  if (ctx->rounds > 10)
+    {
+      DO_AESNI_AESIMC(); r++; rr--; /* round 10 */
+      DO_AESNI_AESIMC(); r++; rr--; /* round 11 */
+      if (ctx->rounds > 12)
+        {
+          DO_AESNI_AESIMC(); r++; rr--; /* round 12 */
+          DO_AESNI_AESIMC(); r++; rr--; /* round 13 */
+        }
+    }
+
+  dkey[r] = ekey[0];
+
+#undef DO_AESNI_AESIMC
+
+  aesni_cleanup();
+}
+
+
+/* Encrypt one block using the Intel AES-NI instructions.  Block is input
+ * and output through SSE register xmm0. */
+static inline void
+do_aesni_enc (const RIJNDAEL_context *ctx)
+{
+#define aesenc_xmm1_xmm0      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t"
+#define aesenclast_xmm1_xmm0  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t"
+  asm volatile ("movdqa (%[key]), %%xmm1\n\t"    /* xmm1 := key[0] */
+                "pxor   %%xmm1, %%xmm0\n\t"     /* xmm0 ^= key[0] */
+                "movdqa 0x10(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                "movdqa 0x20(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                "movdqa 0x30(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                "movdqa 0x40(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                "movdqa 0x50(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                "movdqa 0x60(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                "movdqa 0x70(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                "movdqa 0x80(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                "movdqa 0x90(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                "movdqa 0xa0(%[key]), %%xmm1\n\t"
+                "cmpl $10, %[rounds]\n\t"
+                "jz .Lenclast%=\n\t"
+                aesenc_xmm1_xmm0
+                "movdqa 0xb0(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                "movdqa 0xc0(%[key]), %%xmm1\n\t"
+                "cmpl $12, %[rounds]\n\t"
+                "jz .Lenclast%=\n\t"
+                aesenc_xmm1_xmm0
+                "movdqa 0xd0(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                "movdqa 0xe0(%[key]), %%xmm1\n"
+
+                ".Lenclast%=:\n\t"
+                aesenclast_xmm1_xmm0
+                "\n"
+                :
+                : [key] "r" (ctx->keyschenc),
+                  [rounds] "r" (ctx->rounds)
+                : "cc", "memory");
+#undef aesenc_xmm1_xmm0
+#undef aesenclast_xmm1_xmm0
+}
+
+
+/* Decrypt one block using the Intel AES-NI instructions.  Block is input
+ * and output through SSE register xmm0. */
+static inline void
+do_aesni_dec (const RIJNDAEL_context *ctx)
+{
+#define aesdec_xmm1_xmm0      ".byte 0x66, 0x0f, 0x38, 0xde, 0xc1\n\t"
+#define aesdeclast_xmm1_xmm0  ".byte 0x66, 0x0f, 0x38, 0xdf, 0xc1\n\t"
+  asm volatile ("movdqa (%[key]), %%xmm1\n\t"
+                "pxor   %%xmm1, %%xmm0\n\t"     /* xmm0 ^= key[0] */
+                "movdqa 0x10(%[key]), %%xmm1\n\t"
+                aesdec_xmm1_xmm0
+                "movdqa 0x20(%[key]), %%xmm1\n\t"
+                aesdec_xmm1_xmm0
+                "movdqa 0x30(%[key]), %%xmm1\n\t"
+                aesdec_xmm1_xmm0
+                "movdqa 0x40(%[key]), %%xmm1\n\t"
+                aesdec_xmm1_xmm0
+                "movdqa 0x50(%[key]), %%xmm1\n\t"
+                aesdec_xmm1_xmm0
+                "movdqa 0x60(%[key]), %%xmm1\n\t"
+                aesdec_xmm1_xmm0
+                "movdqa 0x70(%[key]), %%xmm1\n\t"
+                aesdec_xmm1_xmm0
+                "movdqa 0x80(%[key]), %%xmm1\n\t"
+                aesdec_xmm1_xmm0
+                "movdqa 0x90(%[key]), %%xmm1\n\t"
+                aesdec_xmm1_xmm0
+                "movdqa 0xa0(%[key]), %%xmm1\n\t"
+                "cmpl $10, %[rounds]\n\t"
+                "jz .Ldeclast%=\n\t"
+                aesdec_xmm1_xmm0
+                "movdqa 0xb0(%[key]), %%xmm1\n\t"
+                aesdec_xmm1_xmm0
+                "movdqa 0xc0(%[key]), %%xmm1\n\t"
+                "cmpl $12, %[rounds]\n\t"
+                "jz .Ldeclast%=\n\t"
+                aesdec_xmm1_xmm0
+                "movdqa 0xd0(%[key]), %%xmm1\n\t"
+                aesdec_xmm1_xmm0
+                "movdqa 0xe0(%[key]), %%xmm1\n"
+
+                ".Ldeclast%=:\n\t"
+                aesdeclast_xmm1_xmm0
+                "\n"
+                :
+                : [key] "r" (ctx->keyschdec),
+                  [rounds] "r" (ctx->rounds)
+                : "cc", "memory");
+#undef aesdec_xmm1_xmm0
+#undef aesdeclast_xmm1_xmm0
+}
+
+
+/* Encrypt four blocks using the Intel AES-NI instructions.  Blocks are input
+ * and output through SSE registers xmm1 to xmm4.  */
+static inline void
+do_aesni_enc_vec4 (const RIJNDAEL_context *ctx)
+{
+#define aesenc_xmm0_xmm1      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc8\n\t"
+#define aesenc_xmm0_xmm2      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd0\n\t"
+#define aesenc_xmm0_xmm3      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd8\n\t"
+#define aesenc_xmm0_xmm4      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xe0\n\t"
+#define aesenclast_xmm0_xmm1  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc8\n\t"
+#define aesenclast_xmm0_xmm2  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd0\n\t"
+#define aesenclast_xmm0_xmm3  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd8\n\t"
+#define aesenclast_xmm0_xmm4  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xe0\n\t"
+  asm volatile ("movdqa (%[key]), %%xmm0\n\t"
+                "pxor   %%xmm0, %%xmm1\n\t"     /* xmm1 ^= key[0] */
+                "pxor   %%xmm0, %%xmm2\n\t"     /* xmm2 ^= key[0] */
+                "pxor   %%xmm0, %%xmm3\n\t"     /* xmm3 ^= key[0] */
+                "pxor   %%xmm0, %%xmm4\n\t"     /* xmm4 ^= key[0] */
+                "movdqa 0x10(%[key]), %%xmm0\n\t"
+                aesenc_xmm0_xmm1
+                aesenc_xmm0_xmm2
+                aesenc_xmm0_xmm3
+                aesenc_xmm0_xmm4
+                "movdqa 0x20(%[key]), %%xmm0\n\t"
+                aesenc_xmm0_xmm1
+                aesenc_xmm0_xmm2
+                aesenc_xmm0_xmm3
+                aesenc_xmm0_xmm4
+                "movdqa 0x30(%[key]), %%xmm0\n\t"
+                aesenc_xmm0_xmm1
+                aesenc_xmm0_xmm2
+                aesenc_xmm0_xmm3
+                aesenc_xmm0_xmm4
+                "movdqa 0x40(%[key]), %%xmm0\n\t"
+                aesenc_xmm0_xmm1
+                aesenc_xmm0_xmm2
+                aesenc_xmm0_xmm3
+                aesenc_xmm0_xmm4
+                "movdqa 0x50(%[key]), %%xmm0\n\t"
+                aesenc_xmm0_xmm1
+                aesenc_xmm0_xmm2
+                aesenc_xmm0_xmm3
+                aesenc_xmm0_xmm4
+                "movdqa 0x60(%[key]), %%xmm0\n\t"
+                aesenc_xmm0_xmm1
+                aesenc_xmm0_xmm2
+                aesenc_xmm0_xmm3
+                aesenc_xmm0_xmm4
+                "movdqa 0x70(%[key]), %%xmm0\n\t"
+                aesenc_xmm0_xmm1
+                aesenc_xmm0_xmm2
+                aesenc_xmm0_xmm3
+                aesenc_xmm0_xmm4
+                "movdqa 0x80(%[key]), %%xmm0\n\t"
+                aesenc_xmm0_xmm1
+                aesenc_xmm0_xmm2
+                aesenc_xmm0_xmm3
+                aesenc_xmm0_xmm4
+                "movdqa 0x90(%[key]), %%xmm0\n\t"
+                aesenc_xmm0_xmm1
+                aesenc_xmm0_xmm2
+                aesenc_xmm0_xmm3
+                aesenc_xmm0_xmm4
+                "movdqa 0xa0(%[key]), %%xmm0\n\t"
+                "cmpl $10, %[rounds]\n\t"
+                "jz .Ldeclast%=\n\t"
+                aesenc_xmm0_xmm1
+                aesenc_xmm0_xmm2
+                aesenc_xmm0_xmm3
+                aesenc_xmm0_xmm4
+                "movdqa 0xb0(%[key]), %%xmm0\n\t"
+                aesenc_xmm0_xmm1
+                aesenc_xmm0_xmm2
+                aesenc_xmm0_xmm3
+                aesenc_xmm0_xmm4
+                "movdqa 0xc0(%[key]), %%xmm0\n\t"
+                "cmpl $12, %[rounds]\n\t"
+                "jz .Ldeclast%=\n\t"
+                aesenc_xmm0_xmm1
+                aesenc_xmm0_xmm2
+                aesenc_xmm0_xmm3
+                aesenc_xmm0_xmm4
+                "movdqa 0xd0(%[key]), %%xmm0\n\t"
+                aesenc_xmm0_xmm1
+                aesenc_xmm0_xmm2
+                aesenc_xmm0_xmm3
+                aesenc_xmm0_xmm4
+                "movdqa 0xe0(%[key]), %%xmm0\n"
+
+                ".Ldeclast%=:\n\t"
+                aesenclast_xmm0_xmm1
+                aesenclast_xmm0_xmm2
+                aesenclast_xmm0_xmm3
+                aesenclast_xmm0_xmm4
+                : /* no output */
+                : [key] "r" (ctx->keyschenc),
+                  [rounds] "r" (ctx->rounds)
+                : "cc", "memory");
+#undef aesenc_xmm0_xmm1
+#undef aesenc_xmm0_xmm2
+#undef aesenc_xmm0_xmm3
+#undef aesenc_xmm0_xmm4
+#undef aesenclast_xmm0_xmm1
+#undef aesenclast_xmm0_xmm2
+#undef aesenclast_xmm0_xmm3
+#undef aesenclast_xmm0_xmm4
+}
+
+
+/* Decrypt four blocks using the Intel AES-NI instructions.  Blocks are input
+ * and output through SSE registers xmm1 to xmm4.  */
+static inline void
+do_aesni_dec_vec4 (const RIJNDAEL_context *ctx)
+{
+#define aesdec_xmm0_xmm1 ".byte 0x66, 0x0f, 0x38, 0xde, 0xc8\n\t"
+#define aesdec_xmm0_xmm2 ".byte 0x66, 0x0f, 0x38, 0xde, 0xd0\n\t"
+#define aesdec_xmm0_xmm3 ".byte 0x66, 0x0f, 0x38, 0xde, 0xd8\n\t"
+#define aesdec_xmm0_xmm4 ".byte 0x66, 0x0f, 0x38, 0xde, 0xe0\n\t"
+#define aesdeclast_xmm0_xmm1 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xc8\n\t"
+#define aesdeclast_xmm0_xmm2 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xd0\n\t"
+#define aesdeclast_xmm0_xmm3 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xd8\n\t"
+#define aesdeclast_xmm0_xmm4 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xe0\n\t"
+  asm volatile ("movdqa (%[key]), %%xmm0\n\t"
+                "pxor   %%xmm0, %%xmm1\n\t"     /* xmm1 ^= key[0] */
+                "pxor   %%xmm0, %%xmm2\n\t"     /* xmm2 ^= key[0] */
+                "pxor   %%xmm0, %%xmm3\n\t"     /* xmm3 ^= key[0] */
+                "pxor   %%xmm0, %%xmm4\n\t"     /* xmm4 ^= key[0] */
+                "movdqa 0x10(%[key]), %%xmm0\n\t"
+                aesdec_xmm0_xmm1
+                aesdec_xmm0_xmm2
+                aesdec_xmm0_xmm3
+                aesdec_xmm0_xmm4
+                "movdqa 0x20(%[key]), %%xmm0\n\t"
+                aesdec_xmm0_xmm1
+                aesdec_xmm0_xmm2
+                aesdec_xmm0_xmm3
+                aesdec_xmm0_xmm4
+                "movdqa 0x30(%[key]), %%xmm0\n\t"
+                aesdec_xmm0_xmm1
+                aesdec_xmm0_xmm2
+                aesdec_xmm0_xmm3
+                aesdec_xmm0_xmm4
+                "movdqa 0x40(%[key]), %%xmm0\n\t"
+                aesdec_xmm0_xmm1
+                aesdec_xmm0_xmm2
+                aesdec_xmm0_xmm3
+                aesdec_xmm0_xmm4
+                "movdqa 0x50(%[key]), %%xmm0\n\t"
+                aesdec_xmm0_xmm1
+                aesdec_xmm0_xmm2
+                aesdec_xmm0_xmm3
+                aesdec_xmm0_xmm4
+                "movdqa 0x60(%[key]), %%xmm0\n\t"
+                aesdec_xmm0_xmm1
+                aesdec_xmm0_xmm2
+                aesdec_xmm0_xmm3
+                aesdec_xmm0_xmm4
+                "movdqa 0x70(%[key]), %%xmm0\n\t"
+                aesdec_xmm0_xmm1
+                aesdec_xmm0_xmm2
+                aesdec_xmm0_xmm3
+                aesdec_xmm0_xmm4
+                "movdqa 0x80(%[key]), %%xmm0\n\t"
+                aesdec_xmm0_xmm1
+                aesdec_xmm0_xmm2
+                aesdec_xmm0_xmm3
+                aesdec_xmm0_xmm4
+                "movdqa 0x90(%[key]), %%xmm0\n\t"
+                aesdec_xmm0_xmm1
+                aesdec_xmm0_xmm2
+                aesdec_xmm0_xmm3
+                aesdec_xmm0_xmm4
+                "movdqa 0xa0(%[key]), %%xmm0\n\t"
+                "cmpl $10, %[rounds]\n\t"
+                "jz .Ldeclast%=\n\t"
+                aesdec_xmm0_xmm1
+                aesdec_xmm0_xmm2
+                aesdec_xmm0_xmm3
+                aesdec_xmm0_xmm4
+                "movdqa 0xb0(%[key]), %%xmm0\n\t"
+                aesdec_xmm0_xmm1
+                aesdec_xmm0_xmm2
+                aesdec_xmm0_xmm3
+                aesdec_xmm0_xmm4
+                "movdqa 0xc0(%[key]), %%xmm0\n\t"
+                "cmpl $12, %[rounds]\n\t"
+                "jz .Ldeclast%=\n\t"
+                aesdec_xmm0_xmm1
+                aesdec_xmm0_xmm2
+                aesdec_xmm0_xmm3
+                aesdec_xmm0_xmm4
+                "movdqa 0xd0(%[key]), %%xmm0\n\t"
+                aesdec_xmm0_xmm1
+                aesdec_xmm0_xmm2
+                aesdec_xmm0_xmm3
+                aesdec_xmm0_xmm4
+                "movdqa 0xe0(%[key]), %%xmm0\n"
+
+                ".Ldeclast%=:\n\t"
+                aesdeclast_xmm0_xmm1
+                aesdeclast_xmm0_xmm2
+                aesdeclast_xmm0_xmm3
+                aesdeclast_xmm0_xmm4
+                : /* no output */
+                : [key] "r" (ctx->keyschdec),
+                  [rounds] "r" (ctx->rounds)
+                : "cc", "memory");
+#undef aesdec_xmm0_xmm1
+#undef aesdec_xmm0_xmm2
+#undef aesdec_xmm0_xmm3
+#undef aesdec_xmm0_xmm4
+#undef aesdeclast_xmm0_xmm1
+#undef aesdeclast_xmm0_xmm2
+#undef aesdeclast_xmm0_xmm3
+#undef aesdeclast_xmm0_xmm4
+}
+
+
+/* Perform a CTR encryption round using the counter CTR and the input
+   block A.  Write the result to the output block B and update CTR.
+   CTR needs to be a 16 byte aligned little-endian value.  */
+static void
+do_aesni_ctr (const RIJNDAEL_context *ctx,
+              unsigned char *ctr, unsigned char *b, const unsigned char *a)
+{
+#define aesenc_xmm1_xmm0      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t"
+#define aesenclast_xmm1_xmm0  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t"
+
+  asm volatile ("movdqa %%xmm5, %%xmm0\n\t"     /* xmm0 := CTR (xmm5)  */
+                "pcmpeqd %%xmm1, %%xmm1\n\t"
+                "psrldq $8, %%xmm1\n\t"         /* xmm1 = -1 */
+
+                "pshufb %%xmm6, %%xmm5\n\t"
+                "psubq  %%xmm1, %%xmm5\n\t"     /* xmm5++ (big endian) */
+
+                /* detect if 64-bit carry handling is needed */
+                "cmpl   $0xffffffff, 8(%[ctr])\n\t"
+                "jne    .Lno_carry%=\n\t"
+                "cmpl   $0xffffffff, 12(%[ctr])\n\t"
+                "jne    .Lno_carry%=\n\t"
+
+                "pslldq $8, %%xmm1\n\t"         /* move lower 64-bit to high */
+                "psubq   %%xmm1, %%xmm5\n\t"    /* add carry to upper 64bits */
+
+                ".Lno_carry%=:\n\t"
+
+                "pshufb %%xmm6, %%xmm5\n\t"
+                "movdqa %%xmm5, (%[ctr])\n\t"   /* Update CTR (mem).       */
+
+                "pxor (%[key]), %%xmm0\n\t"     /* xmm1 ^= key[0]    */
+                "movdqa 0x10(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                "movdqa 0x20(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                "movdqa 0x30(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                "movdqa 0x40(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                "movdqa 0x50(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                "movdqa 0x60(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                "movdqa 0x70(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                "movdqa 0x80(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                "movdqa 0x90(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                "movdqa 0xa0(%[key]), %%xmm1\n\t"
+                "cmpl $10, %[rounds]\n\t"
+                "jz .Lenclast%=\n\t"
+                aesenc_xmm1_xmm0
+                "movdqa 0xb0(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                "movdqa 0xc0(%[key]), %%xmm1\n\t"
+                "cmpl $12, %[rounds]\n\t"
+                "jz .Lenclast%=\n\t"
+                aesenc_xmm1_xmm0
+                "movdqa 0xd0(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                "movdqa 0xe0(%[key]), %%xmm1\n"
+
+                ".Lenclast%=:\n\t"
+                aesenclast_xmm1_xmm0
+                "movdqu %[src], %%xmm1\n\t"      /* xmm1 := input   */
+                "pxor %%xmm1, %%xmm0\n\t"        /* EncCTR ^= input  */
+                "movdqu %%xmm0, %[dst]"          /* Store EncCTR.    */
+
+                : [dst] "=m" (*b)
+                : [src] "m" (*a),
+                  [ctr] "r" (ctr),
+                  [key] "r" (ctx->keyschenc),
+                  [rounds] "g" (ctx->rounds)
+                : "cc", "memory");
+#undef aesenc_xmm1_xmm0
+#undef aesenclast_xmm1_xmm0
+}
+
+
+/* Four blocks at a time variant of do_aesni_ctr.  */
+static void
+do_aesni_ctr_4 (const RIJNDAEL_context *ctx,
+                unsigned char *ctr, unsigned char *b, const unsigned char *a)
+{
+  static const byte bige_addb_const[4][16] __attribute__ ((aligned (16))) =
+    {
+      { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+      { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 },
+      { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3 },
+      { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4 }
+    };
+#define aesenc_xmm1_xmm0      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t"
+#define aesenc_xmm1_xmm2      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd1\n\t"
+#define aesenc_xmm1_xmm3      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd9\n\t"
+#define aesenc_xmm1_xmm4      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xe1\n\t"
+#define aesenclast_xmm1_xmm0  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t"
+#define aesenclast_xmm1_xmm2  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd1\n\t"
+#define aesenclast_xmm1_xmm3  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd9\n\t"
+#define aesenclast_xmm1_xmm4  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xe1\n\t"
+
+  /* Register usage:
+      esi   keyschedule
+      xmm0  CTR-0
+      xmm1  temp / round key
+      xmm2  CTR-1
+      xmm3  CTR-2
+      xmm4  CTR-3
+      xmm5  copy of *ctr
+      xmm6  endian swapping mask
+   */
+
+  asm volatile (/* detect if 8-bit carry handling is needed */
+                "cmpb   $0xfb, 15(%[ctr])\n\t"
+                "ja     .Ladd32bit%=\n\t"
+
+                "movdqa %%xmm5, %%xmm0\n\t"     /* xmm0 := CTR (xmm5) */
+                "movdqa %[addb_1], %%xmm2\n\t"  /* xmm2 := be(1) */
+                "movdqa %[addb_2], %%xmm3\n\t"  /* xmm3 := be(2) */
+                "movdqa %[addb_3], %%xmm4\n\t"  /* xmm4 := be(3) */
+                "movdqa %[addb_4], %%xmm5\n\t"  /* xmm5 := be(4) */
+                "paddb  %%xmm0, %%xmm2\n\t"     /* xmm2 := be(1) + CTR (xmm0) */
+                "paddb  %%xmm0, %%xmm3\n\t"     /* xmm3 := be(2) + CTR (xmm0) */
+                "paddb  %%xmm0, %%xmm4\n\t"     /* xmm4 := be(3) + CTR (xmm0) */
+                "paddb  %%xmm0, %%xmm5\n\t"     /* xmm5 := be(4) + CTR (xmm0) */
+                "movdqa (%[key]), %%xmm1\n\t"   /* xmm1 := key[0] */
+                "movl   %[rounds], %%esi\n\t"
+                "jmp    .Lstore_ctr%=\n\t"
+
+                ".Ladd32bit%=:\n\t"
+                "movdqa %%xmm5, %%xmm0\n\t"     /* xmm0, xmm2 := CTR (xmm5) */
+                "movdqa %%xmm0, %%xmm2\n\t"
+                "pcmpeqd %%xmm1, %%xmm1\n\t"
+                "psrldq $8, %%xmm1\n\t"         /* xmm1 = -1 */
+
+                "pshufb %%xmm6, %%xmm2\n\t"     /* xmm2 := le(xmm2) */
+                "psubq  %%xmm1, %%xmm2\n\t"     /* xmm2++           */
+                "movdqa %%xmm2, %%xmm3\n\t"     /* xmm3 := xmm2     */
+                "psubq  %%xmm1, %%xmm3\n\t"     /* xmm3++           */
+                "movdqa %%xmm3, %%xmm4\n\t"     /* xmm4 := xmm3     */
+                "psubq  %%xmm1, %%xmm4\n\t"     /* xmm4++           */
+                "movdqa %%xmm4, %%xmm5\n\t"     /* xmm5 := xmm4     */
+                "psubq  %%xmm1, %%xmm5\n\t"     /* xmm5++           */
+
+                /* detect if 64-bit carry handling is needed */
+                "cmpl   $0xffffffff, 8(%[ctr])\n\t"
+                "jne    .Lno_carry%=\n\t"
+                "movl   12(%[ctr]), %%esi\n\t"
+                "bswapl %%esi\n\t"
+                "cmpl   $0xfffffffc, %%esi\n\t"
+                "jb     .Lno_carry%=\n\t"       /* no carry */
+
+                "pslldq $8, %%xmm1\n\t"         /* move lower 64-bit to high */
+                "je     .Lcarry_xmm5%=\n\t"     /* esi == 0xfffffffc */
+                "cmpl   $0xfffffffe, %%esi\n\t"
+                "jb     .Lcarry_xmm4%=\n\t"     /* esi == 0xfffffffd */
+                "je     .Lcarry_xmm3%=\n\t"     /* esi == 0xfffffffe */
+                /* esi == 0xffffffff */
+
+                "psubq   %%xmm1, %%xmm2\n\t"
+                ".Lcarry_xmm3%=:\n\t"
+                "psubq   %%xmm1, %%xmm3\n\t"
+                ".Lcarry_xmm4%=:\n\t"
+                "psubq   %%xmm1, %%xmm4\n\t"
+                ".Lcarry_xmm5%=:\n\t"
+                "psubq   %%xmm1, %%xmm5\n\t"
+
+                ".Lno_carry%=:\n\t"
+                "movdqa (%[key]), %%xmm1\n\t"   /* xmm1 := key[0]    */
+                "movl %[rounds], %%esi\n\t"
+
+                "pshufb %%xmm6, %%xmm2\n\t"     /* xmm2 := be(xmm2) */
+                "pshufb %%xmm6, %%xmm3\n\t"     /* xmm3 := be(xmm3) */
+                "pshufb %%xmm6, %%xmm4\n\t"     /* xmm4 := be(xmm4) */
+                "pshufb %%xmm6, %%xmm5\n\t"     /* xmm5 := be(xmm5) */
+
+                ".Lstore_ctr%=:\n\t"
+                "movdqa %%xmm5, (%[ctr])\n\t"   /* Update CTR (mem).  */
+
+                "pxor   %%xmm1, %%xmm0\n\t"     /* xmm0 ^= key[0]    */
+                "pxor   %%xmm1, %%xmm2\n\t"     /* xmm2 ^= key[0]    */
+                "pxor   %%xmm1, %%xmm3\n\t"     /* xmm3 ^= key[0]    */
+                "pxor   %%xmm1, %%xmm4\n\t"     /* xmm4 ^= key[0]    */
+                "movdqa 0x10(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                aesenc_xmm1_xmm2
+                aesenc_xmm1_xmm3
+                aesenc_xmm1_xmm4
+                "movdqa 0x20(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                aesenc_xmm1_xmm2
+                aesenc_xmm1_xmm3
+                aesenc_xmm1_xmm4
+                "movdqa 0x30(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                aesenc_xmm1_xmm2
+                aesenc_xmm1_xmm3
+                aesenc_xmm1_xmm4
+                "movdqa 0x40(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                aesenc_xmm1_xmm2
+                aesenc_xmm1_xmm3
+                aesenc_xmm1_xmm4
+                "movdqa 0x50(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                aesenc_xmm1_xmm2
+                aesenc_xmm1_xmm3
+                aesenc_xmm1_xmm4
+                "movdqa 0x60(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                aesenc_xmm1_xmm2
+                aesenc_xmm1_xmm3
+                aesenc_xmm1_xmm4
+                "movdqa 0x70(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                aesenc_xmm1_xmm2
+                aesenc_xmm1_xmm3
+                aesenc_xmm1_xmm4
+                "movdqa 0x80(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                aesenc_xmm1_xmm2
+                aesenc_xmm1_xmm3
+                aesenc_xmm1_xmm4
+                "movdqa 0x90(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                aesenc_xmm1_xmm2
+                aesenc_xmm1_xmm3
+                aesenc_xmm1_xmm4
+                "movdqa 0xa0(%[key]), %%xmm1\n\t"
+                "cmpl $10, %%esi\n\t"
+                "jz .Lenclast%=\n\t"
+                aesenc_xmm1_xmm0
+                aesenc_xmm1_xmm2
+                aesenc_xmm1_xmm3
+                aesenc_xmm1_xmm4
+                "movdqa 0xb0(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                aesenc_xmm1_xmm2
+                aesenc_xmm1_xmm3
+                aesenc_xmm1_xmm4
+                "movdqa 0xc0(%[key]), %%xmm1\n\t"
+                "cmpl $12, %%esi\n\t"
+                "jz .Lenclast%=\n\t"
+                aesenc_xmm1_xmm0
+                aesenc_xmm1_xmm2
+                aesenc_xmm1_xmm3
+                aesenc_xmm1_xmm4
+                "movdqa 0xd0(%[key]), %%xmm1\n\t"
+                aesenc_xmm1_xmm0
+                aesenc_xmm1_xmm2
+                aesenc_xmm1_xmm3
+                aesenc_xmm1_xmm4
+                "movdqa 0xe0(%[key]), %%xmm1\n"
+
+                ".Lenclast%=:\n\t"
+                aesenclast_xmm1_xmm0
+                aesenclast_xmm1_xmm2
+                aesenclast_xmm1_xmm3
+                aesenclast_xmm1_xmm4
+                :
+                : [ctr] "r" (ctr),
+                  [key] "r" (ctx->keyschenc),
+                  [rounds] "g" (ctx->rounds),
+                  [addb_1] "m" (bige_addb_const[0][0]),
+                  [addb_2] "m" (bige_addb_const[1][0]),
+                  [addb_3] "m" (bige_addb_const[2][0]),
+                  [addb_4] "m" (bige_addb_const[3][0])
+                : "%esi", "cc", "memory");
+
+  asm volatile ("movdqu (%[src]), %%xmm1\n\t"    /* Get block 1.      */
+                "pxor %%xmm1, %%xmm0\n\t"        /* EncCTR-1 ^= input */
+                "movdqu %%xmm0, (%[dst])\n\t"    /* Store block 1     */
+
+                "movdqu 16(%[src]), %%xmm1\n\t"  /* Get block 2.      */
+                "pxor %%xmm1, %%xmm2\n\t"        /* EncCTR-2 ^= input */
+                "movdqu %%xmm2, 16(%[dst])\n\t"  /* Store block 2.    */
+
+                "movdqu 32(%[src]), %%xmm1\n\t"  /* Get block 3.      */
+                "pxor %%xmm1, %%xmm3\n\t"        /* EncCTR-3 ^= input */
+                "movdqu %%xmm3, 32(%[dst])\n\t"  /* Store block 3.    */
+
+                "movdqu 48(%[src]), %%xmm1\n\t"  /* Get block 4.      */
+                "pxor %%xmm1, %%xmm4\n\t"        /* EncCTR-4 ^= input */
+                "movdqu %%xmm4, 48(%[dst])"      /* Store block 4.   */
+                :
+                : [src] "r" (a),
+                  [dst] "r" (b)
+                : "memory");
+#undef aesenc_xmm1_xmm0
+#undef aesenc_xmm1_xmm2
+#undef aesenc_xmm1_xmm3
+#undef aesenc_xmm1_xmm4
+#undef aesenclast_xmm1_xmm0
+#undef aesenclast_xmm1_xmm2
+#undef aesenclast_xmm1_xmm3
+#undef aesenclast_xmm1_xmm4
+}
+
+
+unsigned int
+_gcry_aes_aesni_encrypt (const RIJNDAEL_context *ctx, unsigned char *dst,
+                         const unsigned char *src)
+{
+  aesni_prepare ();
+  asm volatile ("movdqu %[src], %%xmm0\n\t"
+                :
+                : [src] "m" (*src)
+                : "memory" );
+  do_aesni_enc (ctx);
+  asm volatile ("movdqu %%xmm0, %[dst]\n\t"
+                : [dst] "=m" (*dst)
+                :
+                : "memory" );
+  aesni_cleanup ();
+  return 0;
+}
+
+
+void
+_gcry_aes_aesni_cfb_enc (RIJNDAEL_context *ctx, unsigned char *outbuf,
+                         const unsigned char *inbuf, unsigned char *iv,
+                         size_t nblocks)
+{
+  aesni_prepare ();
+
+  asm volatile ("movdqu %[iv], %%xmm0\n\t"
+                : /* No output */
+                : [iv] "m" (*iv)
+                : "memory" );
+
+  for ( ;nblocks; nblocks-- )
+    {
+      do_aesni_enc (ctx);
+
+      asm volatile ("movdqu %[inbuf], %%xmm1\n\t"
+                    "pxor %%xmm1, %%xmm0\n\t"
+                    "movdqu %%xmm0, %[outbuf]\n\t"
+                    : [outbuf] "=m" (*outbuf)
+                    : [inbuf] "m" (*inbuf)
+                    : "memory" );
+
+      outbuf += BLOCKSIZE;
+      inbuf  += BLOCKSIZE;
+    }
+
+  asm volatile ("movdqu %%xmm0, %[iv]\n\t"
+                : [iv] "=m" (*iv)
+                :
+                : "memory" );
+
+  aesni_cleanup ();
+}
+
+
+void
+_gcry_aes_aesni_cbc_enc (RIJNDAEL_context *ctx, unsigned char *outbuf,
+                         const unsigned char *inbuf, unsigned char *iv,
+                         size_t nblocks, int cbc_mac)
+{
+  aesni_prepare_2_6_variable;
+
+  aesni_prepare ();
+  aesni_prepare_2_6();
+
+  asm volatile ("movdqu %[iv], %%xmm5\n\t"
+                : /* No output */
+                : [iv] "m" (*iv)
+                : "memory" );
+
+  for ( ;nblocks; nblocks-- )
+    {
+      asm volatile ("movdqu %[inbuf], %%xmm0\n\t"
+                    "pxor %%xmm5, %%xmm0\n\t"
+                    : /* No output */
+                    : [inbuf] "m" (*inbuf)
+                    : "memory" );
+
+      do_aesni_enc (ctx);
+
+      asm volatile ("movdqa %%xmm0, %%xmm5\n\t"
+                    "movdqu %%xmm0, %[outbuf]\n\t"
+                    : [outbuf] "=m" (*outbuf)
+                    :
+                    : "memory" );
+
+      inbuf += BLOCKSIZE;
+      if (!cbc_mac)
+        outbuf += BLOCKSIZE;
+    }
+
+  asm volatile ("movdqu %%xmm5, %[iv]\n\t"
+                : [iv] "=m" (*iv)
+                :
+                : "memory" );
+
+  aesni_cleanup ();
+  aesni_cleanup_2_6 ();
+}
+
+
+void
+_gcry_aes_aesni_ctr_enc (RIJNDAEL_context *ctx, unsigned char *outbuf,
+                         const unsigned char *inbuf, unsigned char *ctr,
+                         size_t nblocks)
+{
+  static const unsigned char be_mask[16] __attribute__ ((aligned (16))) =
+    { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
+  aesni_prepare_2_6_variable;
+
+  aesni_prepare ();
+  aesni_prepare_2_6();
+
+  asm volatile ("movdqa %[mask], %%xmm6\n\t" /* Preload mask */
+                "movdqa %[ctr], %%xmm5\n\t"  /* Preload CTR */
+                : /* No output */
+                : [mask] "m" (*be_mask),
+                  [ctr] "m" (*ctr)
+                : "memory");
+
+  for ( ;nblocks > 3 ; nblocks -= 4 )
+    {
+      do_aesni_ctr_4 (ctx, ctr, outbuf, inbuf);
+      outbuf += 4*BLOCKSIZE;
+      inbuf  += 4*BLOCKSIZE;
+    }
+  for ( ;nblocks; nblocks-- )
+    {
+      do_aesni_ctr (ctx, ctr, outbuf, inbuf);
+      outbuf += BLOCKSIZE;
+      inbuf  += BLOCKSIZE;
+    }
+  aesni_cleanup ();
+  aesni_cleanup_2_6 ();
+}
+
+
+unsigned int
+_gcry_aes_aesni_decrypt (const RIJNDAEL_context *ctx, unsigned char *dst,
+                         const unsigned char *src)
+{
+  aesni_prepare ();
+  asm volatile ("movdqu %[src], %%xmm0\n\t"
+                :
+                : [src] "m" (*src)
+                : "memory" );
+  do_aesni_dec (ctx);
+  asm volatile ("movdqu %%xmm0, %[dst]\n\t"
+                : [dst] "=m" (*dst)
+                :
+                : "memory" );
+  aesni_cleanup ();
+  return 0;
+}
+
+
+void
+_gcry_aes_aesni_cfb_dec (RIJNDAEL_context *ctx, unsigned char *outbuf,
+                         const unsigned char *inbuf, unsigned char *iv,
+                         size_t nblocks)
+{
+  aesni_prepare_2_6_variable;
+
+  aesni_prepare ();
+  aesni_prepare_2_6();
+
+  asm volatile ("movdqu %[iv], %%xmm6\n\t"
+                : /* No output */
+                : [iv] "m" (*iv)
+                : "memory" );
+
+  /* CFB decryption can be parallelized */
+  for ( ;nblocks >= 4; nblocks -= 4)
+    {
+      asm volatile
+        ("movdqu %%xmm6,         %%xmm1\n\t" /* load input blocks */
+         "movdqu 0*16(%[inbuf]), %%xmm2\n\t"
+         "movdqu 1*16(%[inbuf]), %%xmm3\n\t"
+         "movdqu 2*16(%[inbuf]), %%xmm4\n\t"
+
+         "movdqu 3*16(%[inbuf]), %%xmm6\n\t" /* update IV */
+         : /* No output */
+         : [inbuf] "r" (inbuf)
+         : "memory");
+
+      do_aesni_enc_vec4 (ctx);
+
+      asm volatile
+        ("movdqu 0*16(%[inbuf]), %%xmm5\n\t"
+         "pxor %%xmm5, %%xmm1\n\t"
+         "movdqu %%xmm1, 0*16(%[outbuf])\n\t"
+
+         "movdqu 1*16(%[inbuf]), %%xmm5\n\t"
+         "pxor %%xmm5, %%xmm2\n\t"
+         "movdqu %%xmm2, 1*16(%[outbuf])\n\t"
+
+         "movdqu 2*16(%[inbuf]), %%xmm5\n\t"
+         "pxor %%xmm5, %%xmm3\n\t"
+         "movdqu %%xmm3, 2*16(%[outbuf])\n\t"
+
+         "movdqu 3*16(%[inbuf]), %%xmm5\n\t"
+         "pxor %%xmm5, %%xmm4\n\t"
+         "movdqu %%xmm4, 3*16(%[outbuf])\n\t"
+
+         : /* No output */
+         : [inbuf] "r" (inbuf),
+           [outbuf] "r" (outbuf)
+         : "memory");
+
+      outbuf += 4*BLOCKSIZE;
+      inbuf  += 4*BLOCKSIZE;
+    }
+
+  asm volatile ("movdqu %%xmm6, %%xmm0\n\t" ::: "cc");
+
+  for ( ;nblocks; nblocks-- )
+    {
+      do_aesni_enc (ctx);
+
+      asm volatile ("movdqa %%xmm0, %%xmm6\n\t"
+                    "movdqu %[inbuf], %%xmm0\n\t"
+                    "pxor %%xmm0, %%xmm6\n\t"
+                    "movdqu %%xmm6, %[outbuf]\n\t"
+                    : [outbuf] "=m" (*outbuf)
+                    : [inbuf] "m" (*inbuf)
+                    : "memory" );
+
+      outbuf += BLOCKSIZE;
+      inbuf  += BLOCKSIZE;
+    }
+
+  asm volatile ("movdqu %%xmm0, %[iv]\n\t"
+                : [iv] "=m" (*iv)
+                :
+                : "memory" );
+
+  aesni_cleanup ();
+  aesni_cleanup_2_6 ();
+}
+
+
+void
+_gcry_aes_aesni_cbc_dec (RIJNDAEL_context *ctx, unsigned char *outbuf,
+                        const unsigned char *inbuf, unsigned char *iv,
+                        size_t nblocks)
+{
+  aesni_prepare_2_6_variable;
+
+  aesni_prepare ();
+  aesni_prepare_2_6();
+
+  asm volatile
+    ("movdqu %[iv], %%xmm5\n\t"        /* use xmm5 as fast IV storage */
+     : /* No output */
+     : [iv] "m" (*iv)
+     : "memory");
+
+  for ( ;nblocks > 3 ; nblocks -= 4 )
+    {
+      asm volatile
+        ("movdqu 0*16(%[inbuf]), %%xmm1\n\t"   /* load input blocks */
+         "movdqu 1*16(%[inbuf]), %%xmm2\n\t"
+         "movdqu 2*16(%[inbuf]), %%xmm3\n\t"
+         "movdqu 3*16(%[inbuf]), %%xmm4\n\t"
+         : /* No output */
+         : [inbuf] "r" (inbuf)
+         : "memory");
+
+      do_aesni_dec_vec4 (ctx);
+
+      asm volatile
+        ("pxor %%xmm5, %%xmm1\n\t"             /* xor IV with output */
+         "movdqu 0*16(%[inbuf]), %%xmm5\n\t"   /* load new IV */
+         "movdqu %%xmm1, 0*16(%[outbuf])\n\t"
+
+         "pxor %%xmm5, %%xmm2\n\t"             /* xor IV with output */
+         "movdqu 1*16(%[inbuf]), %%xmm5\n\t"   /* load new IV */
+         "movdqu %%xmm2, 1*16(%[outbuf])\n\t"
+
+         "pxor %%xmm5, %%xmm3\n\t"             /* xor IV with output */
+         "movdqu 2*16(%[inbuf]), %%xmm5\n\t"   /* load new IV */
+         "movdqu %%xmm3, 2*16(%[outbuf])\n\t"
+
+         "pxor %%xmm5, %%xmm4\n\t"             /* xor IV with output */
+         "movdqu 3*16(%[inbuf]), %%xmm5\n\t"   /* load new IV */
+         "movdqu %%xmm4, 3*16(%[outbuf])\n\t"
+
+         : /* No output */
+         : [inbuf] "r" (inbuf),
+           [outbuf] "r" (outbuf)
+         : "memory");
+
+      outbuf += 4*BLOCKSIZE;
+      inbuf  += 4*BLOCKSIZE;
+    }
+
+  for ( ;nblocks; nblocks-- )
+    {
+      asm volatile
+        ("movdqu %[inbuf], %%xmm0\n\t"
+         "movdqa %%xmm0, %%xmm2\n\t"    /* use xmm2 as savebuf */
+         : /* No output */
+         : [inbuf] "m" (*inbuf)
+         : "memory");
+
+      /* uses only xmm0 and xmm1 */
+      do_aesni_dec (ctx);
+
+      asm volatile
+        ("pxor %%xmm5, %%xmm0\n\t"     /* xor IV with output */
+         "movdqu %%xmm0, %[outbuf]\n\t"
+         "movdqu %%xmm2, %%xmm5\n\t"   /* store savebuf as new IV */
+         : [outbuf] "=m" (*outbuf)
+         :
+         : "memory");
+
+      outbuf += BLOCKSIZE;
+      inbuf  += BLOCKSIZE;
+    }
+
+  asm volatile
+    ("movdqu %%xmm5, %[iv]\n\t"        /* store IV */
+     : /* No output */
+     : [iv] "m" (*iv)
+     : "memory");
+
+  aesni_cleanup ();
+  aesni_cleanup_2_6 ();
+}
+
+
+static inline const unsigned char *
+get_l (gcry_cipher_hd_t c, unsigned char *l_tmp, u64 i, unsigned char *iv,
+       unsigned char *ctr)
+{
+  const unsigned char *l;
+  unsigned int ntz;
+
+  if (i & 0xffffffffU)
+    {
+      asm ("rep;bsf %k[low], %k[ntz]\n\t"
+           : [ntz] "=r" (ntz)
+           : [low] "r" (i & 0xffffffffU)
+           : "cc");
+    }
+  else
+    {
+      if (OCB_L_TABLE_SIZE < 32)
+        {
+          ntz = 32;
+        }
+      else if (i)
+        {
+          asm ("rep;bsf %k[high], %k[ntz]\n\t"
+               : [ntz] "=r" (ntz)
+               : [high] "r" (i >> 32)
+               : "cc");
+          ntz += 32;
+        }
+      else
+        {
+          ntz = 64;
+        }
+    }
+
+  if (ntz < OCB_L_TABLE_SIZE)
+    {
+      l = c->u_mode.ocb.L[ntz];
+    }
+  else
+    {
+      /* Store Offset & Checksum before calling external function */
+      asm volatile ("movdqu %%xmm5, %[iv]\n\t"
+                    "movdqu %%xmm6, %[ctr]\n\t"
+                    : [iv] "=m" (*iv),
+                      [ctr] "=m" (*ctr)
+                    :
+                    : "memory" );
+
+      l = _gcry_cipher_ocb_get_l (c, l_tmp, i);
+
+      /* Restore Offset & Checksum */
+      asm volatile ("movdqu %[iv], %%xmm5\n\t"
+                    "movdqu %[ctr], %%xmm6\n\t"
+                    : /* No output */
+                    : [iv] "m" (*iv),
+                      [ctr] "m" (*ctr)
+                    : "memory" );
+    }
+
+  return l;
+}
+
+
+static void
+aesni_ocb_enc (gcry_cipher_hd_t c, void *outbuf_arg,
+               const void *inbuf_arg, size_t nblocks)
+{
+  union { unsigned char x1[16] ATTR_ALIGNED_16; u32 x32[4]; } l_tmp;
+  RIJNDAEL_context *ctx = (void *)&c->context.c;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  u64 n = c->u_mode.ocb.data_nblocks;
+  const unsigned char *l;
+  aesni_prepare_2_6_variable;
+
+  aesni_prepare ();
+  aesni_prepare_2_6 ();
+
+  /* Preload Offset and Checksum */
+  asm volatile ("movdqu %[iv], %%xmm5\n\t"
+                "movdqu %[ctr], %%xmm6\n\t"
+                : /* No output */
+                : [iv] "m" (*c->u_iv.iv),
+                  [ctr] "m" (*c->u_ctr.ctr)
+                : "memory" );
+
+
+  for ( ;nblocks && n % 4; nblocks-- )
+    {
+      l = get_l(c, l_tmp.x1, ++n, c->u_iv.iv, c->u_ctr.ctr);
+
+      /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+      /* Checksum_i = Checksum_{i-1} xor P_i  */
+      /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)  */
+      asm volatile ("movdqu %[l],     %%xmm1\n\t"
+                    "movdqu %[inbuf], %%xmm0\n\t"
+                    "pxor   %%xmm1,   %%xmm5\n\t"
+                    "pxor   %%xmm0,   %%xmm6\n\t"
+                    "pxor   %%xmm5,   %%xmm0\n\t"
+                    :
+                    : [l] "m" (*l),
+                      [inbuf] "m" (*inbuf)
+                    : "memory" );
+
+      do_aesni_enc (ctx);
+
+      asm volatile ("pxor   %%xmm5, %%xmm0\n\t"
+                    "movdqu %%xmm0, %[outbuf]\n\t"
+                    : [outbuf] "=m" (*outbuf)
+                    :
+                    : "memory" );
+
+      inbuf += BLOCKSIZE;
+      outbuf += BLOCKSIZE;
+    }
+
+  for ( ;nblocks > 3 ; nblocks -= 4 )
+    {
+      /* l_tmp will be used only every 65536-th block. */
+      n += 4;
+      l = get_l(c, l_tmp.x1, n, c->u_iv.iv, c->u_ctr.ctr);
+
+      /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+      /* Checksum_i = Checksum_{i-1} xor P_i  */
+      /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)  */
+      asm volatile ("movdqu %[l0],     %%xmm0\n\t"
+                   "movdqu %[inbuf0], %%xmm1\n\t"
+                   "pxor   %%xmm0,    %%xmm5\n\t"
+                   "pxor   %%xmm1,    %%xmm6\n\t"
+                   "pxor   %%xmm5,    %%xmm1\n\t"
+                   "movdqu %%xmm5,    %[outbuf0]\n\t"
+                   : [outbuf0] "=m" (*(outbuf + 0 * BLOCKSIZE))
+                   : [l0] "m" (*c->u_mode.ocb.L[0]),
+                     [inbuf0] "m" (*(inbuf + 0 * BLOCKSIZE))
+                   : "memory" );
+      asm volatile ("movdqu %[l1],     %%xmm0\n\t"
+                   "movdqu %[inbuf1], %%xmm2\n\t"
+                   "pxor   %%xmm0,    %%xmm5\n\t"
+                   "pxor   %%xmm2,    %%xmm6\n\t"
+                   "pxor   %%xmm5,    %%xmm2\n\t"
+                   "movdqu %%xmm5,    %[outbuf1]\n\t"
+                   : [outbuf1] "=m" (*(outbuf + 1 * BLOCKSIZE))
+                   : [l1] "m" (*c->u_mode.ocb.L[1]),
+                     [inbuf1] "m" (*(inbuf + 1 * BLOCKSIZE))
+                   : "memory" );
+      asm volatile ("movdqu %[l2],     %%xmm0\n\t"
+                   "movdqu %[inbuf2], %%xmm3\n\t"
+                   "pxor   %%xmm0,    %%xmm5\n\t"
+                   "pxor   %%xmm3,    %%xmm6\n\t"
+                   "pxor   %%xmm5,    %%xmm3\n\t"
+                   "movdqu %%xmm5,    %[outbuf2]\n\t"
+                   : [outbuf2] "=m" (*(outbuf + 2 * BLOCKSIZE))
+                   : [l2] "m" (*c->u_mode.ocb.L[0]),
+                     [inbuf2] "m" (*(inbuf + 2 * BLOCKSIZE))
+                   : "memory" );
+      asm volatile ("movdqu %[l3],     %%xmm0\n\t"
+                   "movdqu %[inbuf3], %%xmm4\n\t"
+                   "pxor   %%xmm0,    %%xmm5\n\t"
+                   "pxor   %%xmm4,    %%xmm6\n\t"
+                   "pxor   %%xmm5,    %%xmm4\n\t"
+                   :
+                   : [l3] "m" (*l),
+                     [inbuf3] "m" (*(inbuf + 3 * BLOCKSIZE))
+                   : "memory" );
+
+      do_aesni_enc_vec4 (ctx);
+
+      asm volatile ("movdqu %[outbuf0],%%xmm0\n\t"
+                   "pxor   %%xmm0,    %%xmm1\n\t"
+                   "movdqu %%xmm1,    %[outbuf0]\n\t"
+                   "movdqu %[outbuf1],%%xmm0\n\t"
+                   "pxor   %%xmm0,    %%xmm2\n\t"
+                   "movdqu %%xmm2,    %[outbuf1]\n\t"
+                   "movdqu %[outbuf2],%%xmm0\n\t"
+                   "pxor   %%xmm0,    %%xmm3\n\t"
+                   "movdqu %%xmm3,    %[outbuf2]\n\t"
+                   "pxor   %%xmm5,    %%xmm4\n\t"
+                   "movdqu %%xmm4,    %[outbuf3]\n\t"
+                   : [outbuf0] "+m" (*(outbuf + 0 * BLOCKSIZE)),
+                     [outbuf1] "+m" (*(outbuf + 1 * BLOCKSIZE)),
+                     [outbuf2] "+m" (*(outbuf + 2 * BLOCKSIZE)),
+                     [outbuf3] "=m" (*(outbuf + 3 * BLOCKSIZE))
+                   :
+                   : "memory" );
+
+      outbuf += 4*BLOCKSIZE;
+      inbuf  += 4*BLOCKSIZE;
+    }
+
+  for ( ;nblocks; nblocks-- )
+    {
+      l = get_l(c, l_tmp.x1, ++n, c->u_iv.iv, c->u_ctr.ctr);
+
+      /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+      /* Checksum_i = Checksum_{i-1} xor P_i  */
+      /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)  */
+      asm volatile ("movdqu %[l],     %%xmm1\n\t"
+                    "movdqu %[inbuf], %%xmm0\n\t"
+                    "pxor   %%xmm1,   %%xmm5\n\t"
+                    "pxor   %%xmm0,   %%xmm6\n\t"
+                    "pxor   %%xmm5,   %%xmm0\n\t"
+                    :
+                    : [l] "m" (*l),
+                      [inbuf] "m" (*inbuf)
+                    : "memory" );
+
+      do_aesni_enc (ctx);
+
+      asm volatile ("pxor   %%xmm5, %%xmm0\n\t"
+                    "movdqu %%xmm0, %[outbuf]\n\t"
+                    : [outbuf] "=m" (*outbuf)
+                    :
+                    : "memory" );
+
+      inbuf += BLOCKSIZE;
+      outbuf += BLOCKSIZE;
+    }
+
+  c->u_mode.ocb.data_nblocks = n;
+  asm volatile ("movdqu %%xmm5, %[iv]\n\t"
+                "movdqu %%xmm6, %[ctr]\n\t"
+                : [iv] "=m" (*c->u_iv.iv),
+                  [ctr] "=m" (*c->u_ctr.ctr)
+                :
+                : "memory" );
+
+  aesni_cleanup ();
+  aesni_cleanup_2_6 ();
+
+  wipememory(&l_tmp, sizeof(l_tmp));
+}
+
+
+static void
+aesni_ocb_dec (gcry_cipher_hd_t c, void *outbuf_arg,
+               const void *inbuf_arg, size_t nblocks)
+{
+  union { unsigned char x1[16] ATTR_ALIGNED_16; u32 x32[4]; } l_tmp;
+  RIJNDAEL_context *ctx = (void *)&c->context.c;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  u64 n = c->u_mode.ocb.data_nblocks;
+  const unsigned char *l;
+  aesni_prepare_2_6_variable;
+
+  aesni_prepare ();
+  aesni_prepare_2_6 ();
+
+  /* Preload Offset and Checksum */
+  asm volatile ("movdqu %[iv], %%xmm5\n\t"
+                "movdqu %[ctr], %%xmm6\n\t"
+                : /* No output */
+                : [iv] "m" (*c->u_iv.iv),
+                  [ctr] "m" (*c->u_ctr.ctr)
+                : "memory" );
+
+  for ( ;nblocks && n % 4; nblocks-- )
+    {
+      l = get_l(c, l_tmp.x1, ++n, c->u_iv.iv, c->u_ctr.ctr);
+
+      /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+      /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i)  */
+      /* Checksum_i = Checksum_{i-1} xor P_i  */
+      asm volatile ("movdqu %[l],     %%xmm1\n\t"
+                    "movdqu %[inbuf], %%xmm0\n\t"
+                    "pxor   %%xmm1,   %%xmm5\n\t"
+                    "pxor   %%xmm5,   %%xmm0\n\t"
+                    :
+                    : [l] "m" (*l),
+                      [inbuf] "m" (*inbuf)
+                    : "memory" );
+
+      do_aesni_dec (ctx);
+
+      asm volatile ("pxor   %%xmm5, %%xmm0\n\t"
+                    "pxor   %%xmm0, %%xmm6\n\t"
+                    "movdqu %%xmm0, %[outbuf]\n\t"
+                    : [outbuf] "=m" (*outbuf)
+                    :
+                    : "memory" );
+
+      inbuf += BLOCKSIZE;
+      outbuf += BLOCKSIZE;
+    }
+
+  for ( ;nblocks > 3 ; nblocks -= 4 )
+    {
+      /* l_tmp will be used only every 65536-th block. */
+      n += 4;
+      l = get_l(c, l_tmp.x1, n, c->u_iv.iv, c->u_ctr.ctr);
+
+      /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+      /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i)  */
+      /* Checksum_i = Checksum_{i-1} xor P_i  */
+      asm volatile ("movdqu %[l0],     %%xmm0\n\t"
+                   "movdqu %[inbuf0], %%xmm1\n\t"
+                   "pxor   %%xmm0,    %%xmm5\n\t"
+                   "pxor   %%xmm5,    %%xmm1\n\t"
+                   "movdqu %%xmm5,    %[outbuf0]\n\t"
+                   : [outbuf0] "=m" (*(outbuf + 0 * BLOCKSIZE))
+                   : [l0] "m" (*c->u_mode.ocb.L[0]),
+                     [inbuf0] "m" (*(inbuf + 0 * BLOCKSIZE))
+                   : "memory" );
+      asm volatile ("movdqu %[l1],     %%xmm0\n\t"
+                   "movdqu %[inbuf1], %%xmm2\n\t"
+                   "pxor   %%xmm0,    %%xmm5\n\t"
+                   "pxor   %%xmm5,    %%xmm2\n\t"
+                   "movdqu %%xmm5,    %[outbuf1]\n\t"
+                   : [outbuf1] "=m" (*(outbuf + 1 * BLOCKSIZE))
+                   : [l1] "m" (*c->u_mode.ocb.L[1]),
+                     [inbuf1] "m" (*(inbuf + 1 * BLOCKSIZE))
+                   : "memory" );
+      asm volatile ("movdqu %[l2],     %%xmm0\n\t"
+                   "movdqu %[inbuf2], %%xmm3\n\t"
+                   "pxor   %%xmm0,    %%xmm5\n\t"
+                   "pxor   %%xmm5,    %%xmm3\n\t"
+                   "movdqu %%xmm5,    %[outbuf2]\n\t"
+                   : [outbuf2] "=m" (*(outbuf + 2 * BLOCKSIZE))
+                   : [l2] "m" (*c->u_mode.ocb.L[0]),
+                     [inbuf2] "m" (*(inbuf + 2 * BLOCKSIZE))
+                   : "memory" );
+      asm volatile ("movdqu %[l3],     %%xmm0\n\t"
+                   "movdqu %[inbuf3], %%xmm4\n\t"
+                   "pxor   %%xmm0,    %%xmm5\n\t"
+                   "pxor   %%xmm5,    %%xmm4\n\t"
+                   :
+                   : [l3] "m" (*l),
+                     [inbuf3] "m" (*(inbuf + 3 * BLOCKSIZE))
+                   : "memory" );
+
+      do_aesni_dec_vec4 (ctx);
+
+      asm volatile ("movdqu %[outbuf0],%%xmm0\n\t"
+                   "pxor   %%xmm0,    %%xmm1\n\t"
+                   "movdqu %%xmm1,    %[outbuf0]\n\t"
+                   "movdqu %[outbuf1],%%xmm0\n\t"
+                   "pxor   %%xmm0,    %%xmm2\n\t"
+                   "movdqu %%xmm2,    %[outbuf1]\n\t"
+                   "movdqu %[outbuf2],%%xmm0\n\t"
+                   "pxor   %%xmm0,    %%xmm3\n\t"
+                   "movdqu %%xmm3,    %[outbuf2]\n\t"
+                   "pxor   %%xmm5,    %%xmm4\n\t"
+                   "movdqu %%xmm4,    %[outbuf3]\n\t"
+                   "pxor   %%xmm1,    %%xmm6\n\t"
+                   "pxor   %%xmm2,    %%xmm6\n\t"
+                   "pxor   %%xmm3,    %%xmm6\n\t"
+                   "pxor   %%xmm4,    %%xmm6\n\t"
+                   : [outbuf0] "+m" (*(outbuf + 0 * BLOCKSIZE)),
+                     [outbuf1] "+m" (*(outbuf + 1 * BLOCKSIZE)),
+                     [outbuf2] "+m" (*(outbuf + 2 * BLOCKSIZE)),
+                     [outbuf3] "=m" (*(outbuf + 3 * BLOCKSIZE))
+                   :
+                   : "memory" );
+
+      outbuf += 4*BLOCKSIZE;
+      inbuf  += 4*BLOCKSIZE;
+    }
+
+  for ( ;nblocks; nblocks-- )
+    {
+      l = get_l(c, l_tmp.x1, ++n, c->u_iv.iv, c->u_ctr.ctr);
+
+      /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+      /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i)  */
+      /* Checksum_i = Checksum_{i-1} xor P_i  */
+      asm volatile ("movdqu %[l],     %%xmm1\n\t"
+                    "movdqu %[inbuf], %%xmm0\n\t"
+                    "pxor   %%xmm1,   %%xmm5\n\t"
+                    "pxor   %%xmm5,   %%xmm0\n\t"
+                    :
+                    : [l] "m" (*l),
+                      [inbuf] "m" (*inbuf)
+                    : "memory" );
+
+      do_aesni_dec (ctx);
+
+      asm volatile ("pxor   %%xmm5, %%xmm0\n\t"
+                    "pxor   %%xmm0, %%xmm6\n\t"
+                    "movdqu %%xmm0, %[outbuf]\n\t"
+                    : [outbuf] "=m" (*outbuf)
+                    :
+                    : "memory" );
+
+      inbuf += BLOCKSIZE;
+      outbuf += BLOCKSIZE;
+    }
+
+  c->u_mode.ocb.data_nblocks = n;
+  asm volatile ("movdqu %%xmm5, %[iv]\n\t"
+                "movdqu %%xmm6, %[ctr]\n\t"
+                : [iv] "=m" (*c->u_iv.iv),
+                  [ctr] "=m" (*c->u_ctr.ctr)
+                :
+                : "memory" );
+
+  aesni_cleanup ();
+  aesni_cleanup_2_6 ();
+
+  wipememory(&l_tmp, sizeof(l_tmp));
+}
+
+
+void
+_gcry_aes_aesni_ocb_crypt(gcry_cipher_hd_t c, void *outbuf_arg,
+                          const void *inbuf_arg, size_t nblocks, int encrypt)
+{
+  if (encrypt)
+    aesni_ocb_enc(c, outbuf_arg, inbuf_arg, nblocks);
+  else
+    aesni_ocb_dec(c, outbuf_arg, inbuf_arg, nblocks);
+}
+
+
+void
+_gcry_aes_aesni_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
+                          size_t nblocks)
+{
+  union { unsigned char x1[16] ATTR_ALIGNED_16; u32 x32[4]; } l_tmp;
+  RIJNDAEL_context *ctx = (void *)&c->context.c;
+  const unsigned char *abuf = abuf_arg;
+  u64 n = c->u_mode.ocb.aad_nblocks;
+  const unsigned char *l;
+  aesni_prepare_2_6_variable;
+
+  aesni_prepare ();
+  aesni_prepare_2_6 ();
+
+  /* Preload Offset and Sum */
+  asm volatile ("movdqu %[iv], %%xmm5\n\t"
+                "movdqu %[ctr], %%xmm6\n\t"
+                : /* No output */
+                : [iv] "m" (*c->u_mode.ocb.aad_offset),
+                  [ctr] "m" (*c->u_mode.ocb.aad_sum)
+                : "memory" );
+
+  for ( ;nblocks && n % 4; nblocks-- )
+    {
+      l = get_l(c, l_tmp.x1, ++n, c->u_mode.ocb.aad_offset,
+                c->u_mode.ocb.aad_sum);
+
+      /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+      /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i)  */
+      asm volatile ("movdqu %[l],     %%xmm1\n\t"
+                    "movdqu %[abuf],  %%xmm0\n\t"
+                    "pxor   %%xmm1,   %%xmm5\n\t"
+                    "pxor   %%xmm5,   %%xmm0\n\t"
+                    :
+                    : [l] "m" (*l),
+                      [abuf] "m" (*abuf)
+                    : "memory" );
+
+      do_aesni_enc (ctx);
+
+      asm volatile ("pxor   %%xmm0,   %%xmm6\n\t"
+                    :
+                    :
+                    : "memory" );
+
+      abuf += BLOCKSIZE;
+    }
+
+  for ( ;nblocks > 3 ; nblocks -= 4 )
+    {
+      /* l_tmp will be used only every 65536-th block. */
+      n += 4;
+      l = get_l(c, l_tmp.x1, n, c->u_mode.ocb.aad_offset,
+               c->u_mode.ocb.aad_sum);
+
+      /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+      /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i)  */
+      asm volatile ("movdqu %[l0],     %%xmm0\n\t"
+                   "movdqu %[abuf0],  %%xmm1\n\t"
+                   "pxor   %%xmm0,    %%xmm5\n\t"
+                   "pxor   %%xmm5,    %%xmm1\n\t"
+                   :
+                   : [l0] "m" (*c->u_mode.ocb.L[0]),
+                     [abuf0] "m" (*(abuf + 0 * BLOCKSIZE))
+                   : "memory" );
+      asm volatile ("movdqu %[l1],     %%xmm0\n\t"
+                   "movdqu %[abuf1],  %%xmm2\n\t"
+                   "pxor   %%xmm0,    %%xmm5\n\t"
+                   "pxor   %%xmm5,    %%xmm2\n\t"
+                   :
+                   : [l1] "m" (*c->u_mode.ocb.L[1]),
+                     [abuf1] "m" (*(abuf + 1 * BLOCKSIZE))
+                   : "memory" );
+      asm volatile ("movdqu %[l2],     %%xmm0\n\t"
+                   "movdqu %[abuf2],  %%xmm3\n\t"
+                   "pxor   %%xmm0,    %%xmm5\n\t"
+                   "pxor   %%xmm5,    %%xmm3\n\t"
+                   :
+                   : [l2] "m" (*c->u_mode.ocb.L[0]),
+                     [abuf2] "m" (*(abuf + 2 * BLOCKSIZE))
+                   : "memory" );
+      asm volatile ("movdqu %[l3],     %%xmm0\n\t"
+                   "movdqu %[abuf3],  %%xmm4\n\t"
+                   "pxor   %%xmm0,    %%xmm5\n\t"
+                   "pxor   %%xmm5,    %%xmm4\n\t"
+                   :
+                   : [l3] "m" (*l),
+                     [abuf3] "m" (*(abuf + 3 * BLOCKSIZE))
+                   : "memory" );
+
+      do_aesni_enc_vec4 (ctx);
+
+      asm volatile ("pxor   %%xmm1,   %%xmm6\n\t"
+                   "pxor   %%xmm2,   %%xmm6\n\t"
+                   "pxor   %%xmm3,   %%xmm6\n\t"
+                   "pxor   %%xmm4,   %%xmm6\n\t"
+                   :
+                   :
+                   : "memory" );
+
+      abuf += 4*BLOCKSIZE;
+    }
+
+  for ( ;nblocks; nblocks-- )
+    {
+      l = get_l(c, l_tmp.x1, ++n, c->u_mode.ocb.aad_offset,
+                c->u_mode.ocb.aad_sum);
+
+      /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+      /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i)  */
+      asm volatile ("movdqu %[l],     %%xmm1\n\t"
+                    "movdqu %[abuf],  %%xmm0\n\t"
+                    "pxor   %%xmm1,   %%xmm5\n\t"
+                    "pxor   %%xmm5,   %%xmm0\n\t"
+                    :
+                    : [l] "m" (*l),
+                      [abuf] "m" (*abuf)
+                    : "memory" );
+
+      do_aesni_enc (ctx);
+
+      asm volatile ("pxor   %%xmm0,   %%xmm6\n\t"
+                    :
+                    :
+                    : "memory" );
+
+      abuf += BLOCKSIZE;
+    }
+
+  c->u_mode.ocb.aad_nblocks = n;
+  asm volatile ("movdqu %%xmm5, %[iv]\n\t"
+                "movdqu %%xmm6, %[ctr]\n\t"
+                : [iv] "=m" (*c->u_mode.ocb.aad_offset),
+                  [ctr] "=m" (*c->u_mode.ocb.aad_sum)
+                :
+                : "memory" );
+
+  aesni_cleanup ();
+  aesni_cleanup_2_6 ();
+
+  wipememory(&l_tmp, sizeof(l_tmp));
+}
+
+
+#endif /* USE_AESNI */
index 35a9d26..b149e94 100644 (file)
@@ -1,6 +1,6 @@
 /* rinjdael-amd64.S  -  AMD64 assembly implementation of AES cipher
  *
- * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
@@ -20,7 +20,8 @@
 
 #ifdef __x86_64
 #include <config.h>
-#if defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && defined(USE_AES)
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && defined(USE_AES)
 
 #ifdef __PIC__
 #  define RIP (%rip)
 #  define RIP
 #endif
 
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
+
 .text
 
 /* table macros */
-#define E0     (.LtableE0-.LtableE0)
-#define E1     (.LtableE1-.LtableE0)
-#define E2     (.LtableE2-.LtableE0)
-#define E3     (.LtableE3-.LtableE0)
-#define Es0    (.LtableEs0-.LtableE0)
-#define Es1    (.LtableEs1-.LtableE0)
-#define Es2    (.LtableEs2-.LtableE0)
-#define Es3    (.LtableEs3-.LtableE0)
-#define Esize  8
+#define E0     (0)
+#define Es0    (1)
+#define Esize  4
+#define Essize 4
 
-#define D0     (.LtableD0-.LtableD0)
-#define D1     (.LtableD1-.LtableD0)
-#define D2     (.LtableD2-.LtableD0)
-#define D3     (.LtableD3-.LtableD0)
-#define Ds0    (.LtableDs0-.LtableD0)
-#define Ds1    (.LtableDs1-.LtableD0)
-#define Ds2    (.LtableDs2-.LtableD0)
-#define Ds3    (.LtableDs3-.LtableD0)
-#define Dsize  8
+#define D0     (0)
+#define Ds0    (4 * 256)
+#define Dsize  4
+#define Dssize 1
 
 /* register macros */
 #define CTX    %rdi
@@ -93,8 +90,8 @@
 
 /* helper macros */
 #define do16bit(op, source, tablemul, table1, dest1, table2, dest2, t0, t1) \
-       movzbl source ## bh,                    t1 ## d; \
        movzbl source ## bl,                    t0 ## d; \
+       movzbl source ## bh,                    t1 ## d; \
        op ## l table1(RTAB,t0,tablemul),       dest1 ## d; \
        op ## l table2(RTAB,t1,tablemul),       dest2 ## d;
 
        op ## l table1(RTAB,t0,tablemul),       dest1 ## d; \
        op ## l table2(RTAB,t1,tablemul),       dest2 ## d;
 
+#define last_do16bit(op, source, tablemul, table1, dest1, table2, dest2, t0, t1) \
+       movzbl source ## bl,                    t0 ## d; \
+       movzbl source ## bh,                    t1 ## d; \
+       movzbl table1(RTAB,t0,tablemul),        t0 ## d; \
+       movzbl table2(RTAB,t1,tablemul),        t1 ## d; \
+       op ## l t0 ## d,                        dest1 ## d; \
+       op ## l t1 ## d,                        dest2 ## d;
+
+#define last_do16bit_shr(shf, op, source, tablemul, table1, dest1, table2, dest2, t0, t1) \
+       movzbl source ## bl,                    t0 ## d; \
+       movzbl source ## bh,                    t1 ## d; \
+       shrl $(shf),                            source ## d; \
+       movzbl table1(RTAB,t0,tablemul),        t0 ## d; \
+       movzbl table2(RTAB,t1,tablemul),        t1 ## d; \
+       op ## l t0 ## d,                        dest1 ## d; \
+       op ## l t1 ## d,                        dest2 ## d;
+
 /***********************************************************************
  * AMD64 assembly implementation of the AES cipher
  ***********************************************************************/
        xorl (((round) * 16) + 3 * 4)(CTX), rd ## d;
 
 #define do_encround(next_r) \
-       do16bit_shr(16, mov, RA, Esize, E0, RNA, E1, RND, RT0, RT1); \
-       do16bit(        mov, RA, Esize, E2, RNC, E3, RNB, RT0, RT1); \
+       do16bit_shr(16, mov, RA, Esize, E0, RNA, E0, RND, RT0, RT1); \
+       do16bit(        mov, RA, Esize, E0, RNC, E0, RNB, RT0, RT1); \
        movl (((next_r) * 16) + 0 * 4)(CTX), RAd; \
+       roll $8, RNDd; \
        xorl RNAd, RAd; \
+       roll $8, RNCd; \
+       roll $8, RNBd; \
+       roll $8, RAd; \
        \
-       do16bit_shr(16, xor, RD, Esize, E0, RND, E1, RNC, RT0, RT1); \
-       do16bit(        xor, RD, Esize, E2, RNB, E3, RA,  RT0, RT1); \
+       do16bit_shr(16, xor, RD, Esize, E0, RND, E0, RNC, RT0, RT1); \
+       do16bit(        xor, RD, Esize, E0, RNB, E0, RA,  RT0, RT1); \
        movl (((next_r) * 16) + 3 * 4)(CTX), RDd; \
+       roll $8, RNCd; \
        xorl RNDd, RDd; \
+       roll $8, RNBd; \
+       roll $8, RAd; \
+       roll $8, RDd; \
        \
-       do16bit_shr(16, xor, RC, Esize, E0, RNC, E1, RNB, RT0, RT1); \
-       do16bit(        xor, RC, Esize, E2, RA,  E3, RD,  RT0, RT1); \
+       do16bit_shr(16, xor, RC, Esize, E0, RNC, E0, RNB, RT0, RT1); \
+       do16bit(        xor, RC, Esize, E0, RA,  E0, RD,  RT0, RT1); \
        movl (((next_r) * 16) + 2 * 4)(CTX), RCd; \
+       roll $8, RNBd; \
        xorl RNCd, RCd; \
+       roll $8, RAd; \
+       roll $8, RDd; \
+       roll $8, RCd; \
        \
-       do16bit_shr(16, xor, RB, Esize, E0, RNB, E1, RA,  RT0, RT1); \
-       do16bit(        xor, RB, Esize, E2, RD,  E3, RC,  RT0, RT1); \
+       do16bit_shr(16, xor, RB, Esize, E0, RNB, E0, RA,  RT0, RT1); \
+       do16bit(        xor, RB, Esize, E0, RD,  E0, RC,  RT0, RT1); \
        movl (((next_r) * 16) + 1 * 4)(CTX), RBd; \
-       xorl RNBd, RBd;
+       roll $8, RAd; \
+       xorl RNBd, RBd; \
+       roll $16, RDd; \
+       roll $24, RCd;
 
 #define do_lastencround(next_r) \
-       do16bit_shr(16, mov, RA, Esize, Es0, RNA, Es1, RND, RT0, RT1); \
-       do16bit(        mov, RA, Esize, Es2, RNC, Es3, RNB, RT0, RT1); \
+       do16bit_shr(16, movzb, RA, Essize, Es0, RNA, Es0, RND, RT0, RT1); \
+       do16bit(        movzb, RA, Essize, Es0, RNC, Es0, RNB, RT0, RT1); \
+       movl (((next_r) * 16) + 0 * 4)(CTX), RAd; \
+       roll $8, RNDd; \
+       xorl RNAd, RAd; \
+       roll $8, RNCd; \
+       roll $8, RNBd; \
+       roll $8, RAd; \
        \
-       do16bit_shr(16,  or, RB, Esize, Es0, RNB, Es1, RNA, RT0, RT1); \
-       do16bit(         or, RB, Esize, Es2, RND, Es3, RNC, RT0, RT1); \
+       last_do16bit_shr(16, xor, RD, Essize, Es0, RND, Es0, RNC, RT0, RT1); \
+       last_do16bit(        xor, RD, Essize, Es0, RNB, Es0, RA,  RT0, RT1); \
+       movl (((next_r) * 16) + 3 * 4)(CTX), RDd; \
+       roll $8, RNCd; \
+       xorl RNDd, RDd; \
+       roll $8, RNBd; \
+       roll $8, RAd; \
+       roll $8, RDd; \
        \
-       do16bit_shr(16,  or, RC, Esize, Es0, RNC, Es1, RNB, RT0, RT1); \
-       do16bit(         or, RC, Esize, Es2, RNA, Es3, RND, RT0, RT1); \
+       last_do16bit_shr(16, xor, RC, Essize, Es0, RNC, Es0, RNB, RT0, RT1); \
+       last_do16bit(        xor, RC, Essize, Es0, RA,  Es0, RD,  RT0, RT1); \
+       movl (((next_r) * 16) + 2 * 4)(CTX), RCd; \
+       roll $8, RNBd; \
+       xorl RNCd, RCd; \
+       roll $8, RAd; \
+       roll $8, RDd; \
+       roll $8, RCd; \
        \
-       do16bit_shr(16,  or, RD, Esize, Es0, RND, Es1, RNC, RT0, RT1); \
-       do16bit(         or, RD, Esize, Es2, RNB, Es3, RNA, RT0, RT1);
+       last_do16bit_shr(16, xor, RB, Essize, Es0, RNB, Es0, RA,  RT0, RT1); \
+       last_do16bit(        xor, RB, Essize, Es0, RD,  Es0, RC,  RT0, RT1); \
+       movl (((next_r) * 16) + 1 * 4)(CTX), RBd; \
+       roll $8, RAd; \
+       xorl RNBd, RBd; \
+       roll $16, RDd; \
+       roll $24, RCd;
 
 #define firstencround(round) \
        addroundkey(round, RA, RB, RC, RD); \
        do_encround((round) + 1);
 
 #define lastencround(round) \
-       do_lastencround(); \
-       addroundkey((round) + 1, RNA, RNB, RNC, RND);
+       do_lastencround((round) + 1);
 
 .align 8
 .globl _gcry_aes_amd64_encrypt_block
-.type   _gcry_aes_amd64_encrypt_block,@function;
+ELF(.type   _gcry_aes_amd64_encrypt_block,@function;)
 
 _gcry_aes_amd64_encrypt_block:
        /* input:
@@ -169,6 +220,7 @@ _gcry_aes_amd64_encrypt_block:
         *      %rsi: dst
         *      %rdx: src
         *      %ecx: number of rounds.. 10, 12 or 14
+        *      %r8:  encryption tables
         */
        subq $(5 * 8), %rsp;
        movq %rsi, (0 * 8)(%rsp);
@@ -177,7 +229,7 @@ _gcry_aes_amd64_encrypt_block:
        movq %rbx, (3 * 8)(%rsp);
        movq %r12, (4 * 8)(%rsp);
 
-       leaq .LtableE0 RIP, RTAB;
+       leaq (%r8), RTAB;
 
        /* read input block */
        movl 0 * 4(%rdx), RAd;
@@ -202,16 +254,17 @@ _gcry_aes_amd64_encrypt_block:
 .Lenc_done:
        /* write output block */
        movq (0 * 8)(%rsp), %rsi;
-       movl RNAd, 0 * 4(%rsi);
-       movl RNBd, 1 * 4(%rsi);
-       movl RNCd, 2 * 4(%rsi);
-       movl RNDd, 3 * 4(%rsi);
+       movl RAd, 0 * 4(%rsi);
+       movl RBd, 1 * 4(%rsi);
+       movl RCd, 2 * 4(%rsi);
+       movl RDd, 3 * 4(%rsi);
 
        movq (4 * 8)(%rsp), %r12;
        movq (3 * 8)(%rsp), %rbx;
        movq (2 * 8)(%rsp), %rbp;
        addq $(5 * 8), %rsp;
 
+       movl $(6 * 8), %eax;
        ret;
 
 .align 4
@@ -233,41 +286,79 @@ _gcry_aes_amd64_encrypt_block:
        lastencround(11);
 
        jmp .Lenc_done;
-.size _gcry_aes_amd64_encrypt_block,.-_gcry_aes_amd64_encrypt_block;
+ELF(.size _gcry_aes_amd64_encrypt_block,.-_gcry_aes_amd64_encrypt_block;)
 
 #define do_decround(next_r) \
-       do16bit_shr(16, mov, RA, Dsize, D0, RNA, D1, RNB, RT0, RT1); \
-       do16bit(        mov, RA, Dsize, D2, RNC, D3, RND, RT0, RT1); \
+       do16bit_shr(16, mov, RA, Dsize, D0, RNA, D0, RNB, RT0, RT1); \
+       do16bit(        mov, RA, Dsize, D0, RNC, D0, RND, RT0, RT1); \
        movl (((next_r) * 16) + 0 * 4)(CTX), RAd; \
+       roll $8, RNBd; \
        xorl RNAd, RAd; \
+       roll $8, RNCd; \
+       roll $8, RNDd; \
+       roll $8, RAd; \
        \
-       do16bit_shr(16, xor, RB, Dsize, D0, RNB, D1, RNC, RT0, RT1); \
-       do16bit(        xor, RB, Dsize, D2, RND, D3, RA,  RT0, RT1); \
+       do16bit_shr(16, xor, RB, Dsize, D0, RNB, D0, RNC, RT0, RT1); \
+       do16bit(        xor, RB, Dsize, D0, RND, D0, RA,  RT0, RT1); \
        movl (((next_r) * 16) + 1 * 4)(CTX), RBd; \
+       roll $8, RNCd; \
        xorl RNBd, RBd; \
+       roll $8, RNDd; \
+       roll $8, RAd; \
+       roll $8, RBd; \
        \
-       do16bit_shr(16, xor, RC, Dsize, D0, RNC, D1, RND, RT0, RT1); \
-       do16bit(        xor, RC, Dsize, D2, RA,  D3, RB,  RT0, RT1); \
+       do16bit_shr(16, xor, RC, Dsize, D0, RNC, D0, RND, RT0, RT1); \
+       do16bit(        xor, RC, Dsize, D0, RA,  D0, RB,  RT0, RT1); \
        movl (((next_r) * 16) + 2 * 4)(CTX), RCd; \
+       roll $8, RNDd; \
        xorl RNCd, RCd; \
+       roll $8, RAd; \
+       roll $8, RBd; \
+       roll $8, RCd; \
        \
-       do16bit_shr(16, xor, RD, Dsize, D0, RND, D1, RA,  RT0, RT1); \
-       do16bit(        xor, RD, Dsize, D2, RB,  D3, RC,  RT0, RT1); \
+       do16bit_shr(16, xor, RD, Dsize, D0, RND, D0, RA,  RT0, RT1); \
+       do16bit(        xor, RD, Dsize, D0, RB,  D0, RC,  RT0, RT1); \
        movl (((next_r) * 16) + 3 * 4)(CTX), RDd; \
+       roll $8, RAd; \
        xorl RNDd, RDd; \
+       roll $16, RBd; \
+       roll $24, RCd;
 
-#define do_lastdecround() \
-       do16bit_shr(16, mov, RA, Dsize, Ds0, RNA, Ds1, RNB, RT0, RT1); \
-       do16bit(        mov, RA, Dsize, Ds2, RNC, Ds3, RND, RT0, RT1); \
+#define do_lastdecround(next_r) \
+       do16bit_shr(16, movzb, RA, Dssize, Ds0, RNA, Ds0, RNB, RT0, RT1); \
+       do16bit(        movzb, RA, Dssize, Ds0, RNC, Ds0, RND, RT0, RT1); \
+       movl (((next_r) * 16) + 0 * 4)(CTX), RAd; \
+       roll $8, RNBd; \
+       xorl RNAd, RAd; \
+       roll $8, RNCd; \
+       roll $8, RNDd; \
+       roll $8, RAd; \
        \
-       do16bit_shr(16,  or, RB, Dsize, Ds0, RNB, Ds1, RNC, RT0, RT1); \
-       do16bit(         or, RB, Dsize, Ds2, RND, Ds3, RNA, RT0, RT1); \
+       last_do16bit_shr(16, xor, RB, Dssize, Ds0, RNB, Ds0, RNC, RT0, RT1); \
+       last_do16bit(        xor, RB, Dssize, Ds0, RND, Ds0, RA,  RT0, RT1); \
+       movl (((next_r) * 16) + 1 * 4)(CTX), RBd; \
+       roll $8, RNCd; \
+       xorl RNBd, RBd; \
+       roll $8, RNDd; \
+       roll $8, RAd; \
+       roll $8, RBd; \
        \
-       do16bit_shr(16,  or, RC, Dsize, Ds0, RNC, Ds1, RND, RT0, RT1); \
-       do16bit(         or, RC, Dsize, Ds2, RNA, Ds3, RNB, RT0, RT1); \
+       last_do16bit_shr(16, xor, RC, Dssize, Ds0, RNC, Ds0, RND, RT0, RT1); \
+       last_do16bit(        xor, RC, Dssize, Ds0, RA,  Ds0, RB,  RT0, RT1); \
+       movl (((next_r) * 16) + 2 * 4)(CTX), RCd; \
+       roll $8, RNDd; \
+       xorl RNCd, RCd; \
+       roll $8, RAd; \
+       roll $8, RBd; \
+       roll $8, RCd; \
        \
-       do16bit_shr(16,  or, RD, Dsize, Ds0, RND, Ds1, RNA, RT0, RT1); \
-       do16bit(         or, RD, Dsize, Ds2, RNB, Ds3, RNC, RT0, RT1);
+       last_do16bit_shr(16, xor, RD, Dssize, Ds0, RND, Ds0, RA,  RT0, RT1); \
+       last_do16bit(        xor, RD, Dssize, Ds0, RB,  Ds0, RC,  RT0, RT1); \
+       movl (((next_r) * 16) + 3 * 4)(CTX), RDd; \
+       roll $8, RAd; \
+       xorl RNDd, RDd; \
+       roll $16, RBd; \
+       roll $24, RCd;
 
 #define firstdecround(round) \
        addroundkey((round + 1), RA, RB, RC, RD); \
@@ -277,12 +368,11 @@ _gcry_aes_amd64_encrypt_block:
        do_decround(round);
 
 #define lastdecround(round) \
-       do_lastdecround(); \
-       addroundkey(round, RNA, RNB, RNC, RND);
+       do_lastdecround(round);
 
 .align 8
 .globl _gcry_aes_amd64_decrypt_block
-.type   _gcry_aes_amd64_decrypt_block,@function;
+ELF(.type   _gcry_aes_amd64_decrypt_block,@function;)
 
 _gcry_aes_amd64_decrypt_block:
        /* input:
@@ -290,6 +380,7 @@ _gcry_aes_amd64_decrypt_block:
         *      %rsi: dst
         *      %rdx: src
         *      %ecx: number of rounds.. 10, 12 or 14
+        *      %r8:  decryption tables
         */
        subq $(5 * 8), %rsp;
        movq %rsi, (0 * 8)(%rsp);
@@ -298,7 +389,7 @@ _gcry_aes_amd64_decrypt_block:
        movq %rbx, (3 * 8)(%rsp);
        movq %r12, (4 * 8)(%rsp);
 
-       leaq .LtableD0 RIP, RTAB;
+       leaq (%r8), RTAB;
 
        /* read input block */
        movl 0 * 4(%rdx), RAd;
@@ -324,16 +415,17 @@ _gcry_aes_amd64_decrypt_block:
 
        /* write output block */
        movq (0 * 8)(%rsp), %rsi;
-       movl RNAd, 0 * 4(%rsi);
-       movl RNBd, 1 * 4(%rsi);
-       movl RNCd, 2 * 4(%rsi);
-       movl RNDd, 3 * 4(%rsi);
+       movl RAd, 0 * 4(%rsi);
+       movl RBd, 1 * 4(%rsi);
+       movl RCd, 2 * 4(%rsi);
+       movl RDd, 3 * 4(%rsi);
 
        movq (4 * 8)(%rsp), %r12;
        movq (3 * 8)(%rsp), %rbx;
        movq (2 * 8)(%rsp), %rbp;
        addq $(5 * 8), %rsp;
 
+       movl $(6 * 8), %eax;
        ret;
 
 .align 4
@@ -355,1062 +447,7 @@ _gcry_aes_amd64_decrypt_block:
        decround(9);
 
        jmp .Ldec_tail;
-.size _gcry_aes_amd64_decrypt_block,.-_gcry_aes_amd64_decrypt_block;
-
-.data
-.align 16
-
-/* Encryption tables */
-.LtableE0:
-.long 0xa56363c6
-.LtableEs0:
-.long             0x00000063, 0x847c7cf8, 0x0000007c
-.long 0x997777ee, 0x00000077, 0x8d7b7bf6, 0x0000007b
-.long 0x0df2f2ff, 0x000000f2, 0xbd6b6bd6, 0x0000006b
-.long 0xb16f6fde, 0x0000006f, 0x54c5c591, 0x000000c5
-.long 0x50303060, 0x00000030, 0x03010102, 0x00000001
-.long 0xa96767ce, 0x00000067, 0x7d2b2b56, 0x0000002b
-.long 0x19fefee7, 0x000000fe, 0x62d7d7b5, 0x000000d7
-.long 0xe6abab4d, 0x000000ab, 0x9a7676ec, 0x00000076
-.long 0x45caca8f, 0x000000ca, 0x9d82821f, 0x00000082
-.long 0x40c9c989, 0x000000c9, 0x877d7dfa, 0x0000007d
-.long 0x15fafaef, 0x000000fa, 0xeb5959b2, 0x00000059
-.long 0xc947478e, 0x00000047, 0x0bf0f0fb, 0x000000f0
-.long 0xecadad41, 0x000000ad, 0x67d4d4b3, 0x000000d4
-.long 0xfda2a25f, 0x000000a2, 0xeaafaf45, 0x000000af
-.long 0xbf9c9c23, 0x0000009c, 0xf7a4a453, 0x000000a4
-.long 0x967272e4, 0x00000072, 0x5bc0c09b, 0x000000c0
-.long 0xc2b7b775, 0x000000b7, 0x1cfdfde1, 0x000000fd
-.long 0xae93933d, 0x00000093, 0x6a26264c, 0x00000026
-.long 0x5a36366c, 0x00000036, 0x413f3f7e, 0x0000003f
-.long 0x02f7f7f5, 0x000000f7, 0x4fcccc83, 0x000000cc
-.long 0x5c343468, 0x00000034, 0xf4a5a551, 0x000000a5
-.long 0x34e5e5d1, 0x000000e5, 0x08f1f1f9, 0x000000f1
-.long 0x937171e2, 0x00000071, 0x73d8d8ab, 0x000000d8
-.long 0x53313162, 0x00000031, 0x3f15152a, 0x00000015
-.long 0x0c040408, 0x00000004, 0x52c7c795, 0x000000c7
-.long 0x65232346, 0x00000023, 0x5ec3c39d, 0x000000c3
-.long 0x28181830, 0x00000018, 0xa1969637, 0x00000096
-.long 0x0f05050a, 0x00000005, 0xb59a9a2f, 0x0000009a
-.long 0x0907070e, 0x00000007, 0x36121224, 0x00000012
-.long 0x9b80801b, 0x00000080, 0x3de2e2df, 0x000000e2
-.long 0x26ebebcd, 0x000000eb, 0x6927274e, 0x00000027
-.long 0xcdb2b27f, 0x000000b2, 0x9f7575ea, 0x00000075
-.long 0x1b090912, 0x00000009, 0x9e83831d, 0x00000083
-.long 0x742c2c58, 0x0000002c, 0x2e1a1a34, 0x0000001a
-.long 0x2d1b1b36, 0x0000001b, 0xb26e6edc, 0x0000006e
-.long 0xee5a5ab4, 0x0000005a, 0xfba0a05b, 0x000000a0
-.long 0xf65252a4, 0x00000052, 0x4d3b3b76, 0x0000003b
-.long 0x61d6d6b7, 0x000000d6, 0xceb3b37d, 0x000000b3
-.long 0x7b292952, 0x00000029, 0x3ee3e3dd, 0x000000e3
-.long 0x712f2f5e, 0x0000002f, 0x97848413, 0x00000084
-.long 0xf55353a6, 0x00000053, 0x68d1d1b9, 0x000000d1
-.long 0x00000000, 0x00000000, 0x2cededc1, 0x000000ed
-.long 0x60202040, 0x00000020, 0x1ffcfce3, 0x000000fc
-.long 0xc8b1b179, 0x000000b1, 0xed5b5bb6, 0x0000005b
-.long 0xbe6a6ad4, 0x0000006a, 0x46cbcb8d, 0x000000cb
-.long 0xd9bebe67, 0x000000be, 0x4b393972, 0x00000039
-.long 0xde4a4a94, 0x0000004a, 0xd44c4c98, 0x0000004c
-.long 0xe85858b0, 0x00000058, 0x4acfcf85, 0x000000cf
-.long 0x6bd0d0bb, 0x000000d0, 0x2aefefc5, 0x000000ef
-.long 0xe5aaaa4f, 0x000000aa, 0x16fbfbed, 0x000000fb
-.long 0xc5434386, 0x00000043, 0xd74d4d9a, 0x0000004d
-.long 0x55333366, 0x00000033, 0x94858511, 0x00000085
-.long 0xcf45458a, 0x00000045, 0x10f9f9e9, 0x000000f9
-.long 0x06020204, 0x00000002, 0x817f7ffe, 0x0000007f
-.long 0xf05050a0, 0x00000050, 0x443c3c78, 0x0000003c
-.long 0xba9f9f25, 0x0000009f, 0xe3a8a84b, 0x000000a8
-.long 0xf35151a2, 0x00000051, 0xfea3a35d, 0x000000a3
-.long 0xc0404080, 0x00000040, 0x8a8f8f05, 0x0000008f
-.long 0xad92923f, 0x00000092, 0xbc9d9d21, 0x0000009d
-.long 0x48383870, 0x00000038, 0x04f5f5f1, 0x000000f5
-.long 0xdfbcbc63, 0x000000bc, 0xc1b6b677, 0x000000b6
-.long 0x75dadaaf, 0x000000da, 0x63212142, 0x00000021
-.long 0x30101020, 0x00000010, 0x1affffe5, 0x000000ff
-.long 0x0ef3f3fd, 0x000000f3, 0x6dd2d2bf, 0x000000d2
-.long 0x4ccdcd81, 0x000000cd, 0x140c0c18, 0x0000000c
-.long 0x35131326, 0x00000013, 0x2fececc3, 0x000000ec
-.long 0xe15f5fbe, 0x0000005f, 0xa2979735, 0x00000097
-.long 0xcc444488, 0x00000044, 0x3917172e, 0x00000017
-.long 0x57c4c493, 0x000000c4, 0xf2a7a755, 0x000000a7
-.long 0x827e7efc, 0x0000007e, 0x473d3d7a, 0x0000003d
-.long 0xac6464c8, 0x00000064, 0xe75d5dba, 0x0000005d
-.long 0x2b191932, 0x00000019, 0x957373e6, 0x00000073
-.long 0xa06060c0, 0x00000060, 0x98818119, 0x00000081
-.long 0xd14f4f9e, 0x0000004f, 0x7fdcdca3, 0x000000dc
-.long 0x66222244, 0x00000022, 0x7e2a2a54, 0x0000002a
-.long 0xab90903b, 0x00000090, 0x8388880b, 0x00000088
-.long 0xca46468c, 0x00000046, 0x29eeeec7, 0x000000ee
-.long 0xd3b8b86b, 0x000000b8, 0x3c141428, 0x00000014
-.long 0x79dedea7, 0x000000de, 0xe25e5ebc, 0x0000005e
-.long 0x1d0b0b16, 0x0000000b, 0x76dbdbad, 0x000000db
-.long 0x3be0e0db, 0x000000e0, 0x56323264, 0x00000032
-.long 0x4e3a3a74, 0x0000003a, 0x1e0a0a14, 0x0000000a
-.long 0xdb494992, 0x00000049, 0x0a06060c, 0x00000006
-.long 0x6c242448, 0x00000024, 0xe45c5cb8, 0x0000005c
-.long 0x5dc2c29f, 0x000000c2, 0x6ed3d3bd, 0x000000d3
-.long 0xefacac43, 0x000000ac, 0xa66262c4, 0x00000062
-.long 0xa8919139, 0x00000091, 0xa4959531, 0x00000095
-.long 0x37e4e4d3, 0x000000e4, 0x8b7979f2, 0x00000079
-.long 0x32e7e7d5, 0x000000e7, 0x43c8c88b, 0x000000c8
-.long 0x5937376e, 0x00000037, 0xb76d6dda, 0x0000006d
-.long 0x8c8d8d01, 0x0000008d, 0x64d5d5b1, 0x000000d5
-.long 0xd24e4e9c, 0x0000004e, 0xe0a9a949, 0x000000a9
-.long 0xb46c6cd8, 0x0000006c, 0xfa5656ac, 0x00000056
-.long 0x07f4f4f3, 0x000000f4, 0x25eaeacf, 0x000000ea
-.long 0xaf6565ca, 0x00000065, 0x8e7a7af4, 0x0000007a
-.long 0xe9aeae47, 0x000000ae, 0x18080810, 0x00000008
-.long 0xd5baba6f, 0x000000ba, 0x887878f0, 0x00000078
-.long 0x6f25254a, 0x00000025, 0x722e2e5c, 0x0000002e
-.long 0x241c1c38, 0x0000001c, 0xf1a6a657, 0x000000a6
-.long 0xc7b4b473, 0x000000b4, 0x51c6c697, 0x000000c6
-.long 0x23e8e8cb, 0x000000e8, 0x7cdddda1, 0x000000dd
-.long 0x9c7474e8, 0x00000074, 0x211f1f3e, 0x0000001f
-.long 0xdd4b4b96, 0x0000004b, 0xdcbdbd61, 0x000000bd
-.long 0x868b8b0d, 0x0000008b, 0x858a8a0f, 0x0000008a
-.long 0x907070e0, 0x00000070, 0x423e3e7c, 0x0000003e
-.long 0xc4b5b571, 0x000000b5, 0xaa6666cc, 0x00000066
-.long 0xd8484890, 0x00000048, 0x05030306, 0x00000003
-.long 0x01f6f6f7, 0x000000f6, 0x120e0e1c, 0x0000000e
-.long 0xa36161c2, 0x00000061, 0x5f35356a, 0x00000035
-.long 0xf95757ae, 0x00000057, 0xd0b9b969, 0x000000b9
-.long 0x91868617, 0x00000086, 0x58c1c199, 0x000000c1
-.long 0x271d1d3a, 0x0000001d, 0xb99e9e27, 0x0000009e
-.long 0x38e1e1d9, 0x000000e1, 0x13f8f8eb, 0x000000f8
-.long 0xb398982b, 0x00000098, 0x33111122, 0x00000011
-.long 0xbb6969d2, 0x00000069, 0x70d9d9a9, 0x000000d9
-.long 0x898e8e07, 0x0000008e, 0xa7949433, 0x00000094
-.long 0xb69b9b2d, 0x0000009b, 0x221e1e3c, 0x0000001e
-.long 0x92878715, 0x00000087, 0x20e9e9c9, 0x000000e9
-.long 0x49cece87, 0x000000ce, 0xff5555aa, 0x00000055
-.long 0x78282850, 0x00000028, 0x7adfdfa5, 0x000000df
-.long 0x8f8c8c03, 0x0000008c, 0xf8a1a159, 0x000000a1
-.long 0x80898909, 0x00000089, 0x170d0d1a, 0x0000000d
-.long 0xdabfbf65, 0x000000bf, 0x31e6e6d7, 0x000000e6
-.long 0xc6424284, 0x00000042, 0xb86868d0, 0x00000068
-.long 0xc3414182, 0x00000041, 0xb0999929, 0x00000099
-.long 0x772d2d5a, 0x0000002d, 0x110f0f1e, 0x0000000f
-.long 0xcbb0b07b, 0x000000b0, 0xfc5454a8, 0x00000054
-.long 0xd6bbbb6d, 0x000000bb, 0x3a16162c, 0x00000016
-.LtableE1:
-.long 0x6363c6a5
-.LtableEs1:
-.long             0x00006300, 0x7c7cf884, 0x00007c00
-.long 0x7777ee99, 0x00007700, 0x7b7bf68d, 0x00007b00
-.long 0xf2f2ff0d, 0x0000f200, 0x6b6bd6bd, 0x00006b00
-.long 0x6f6fdeb1, 0x00006f00, 0xc5c59154, 0x0000c500
-.long 0x30306050, 0x00003000, 0x01010203, 0x00000100
-.long 0x6767cea9, 0x00006700, 0x2b2b567d, 0x00002b00
-.long 0xfefee719, 0x0000fe00, 0xd7d7b562, 0x0000d700
-.long 0xabab4de6, 0x0000ab00, 0x7676ec9a, 0x00007600
-.long 0xcaca8f45, 0x0000ca00, 0x82821f9d, 0x00008200
-.long 0xc9c98940, 0x0000c900, 0x7d7dfa87, 0x00007d00
-.long 0xfafaef15, 0x0000fa00, 0x5959b2eb, 0x00005900
-.long 0x47478ec9, 0x00004700, 0xf0f0fb0b, 0x0000f000
-.long 0xadad41ec, 0x0000ad00, 0xd4d4b367, 0x0000d400
-.long 0xa2a25ffd, 0x0000a200, 0xafaf45ea, 0x0000af00
-.long 0x9c9c23bf, 0x00009c00, 0xa4a453f7, 0x0000a400
-.long 0x7272e496, 0x00007200, 0xc0c09b5b, 0x0000c000
-.long 0xb7b775c2, 0x0000b700, 0xfdfde11c, 0x0000fd00
-.long 0x93933dae, 0x00009300, 0x26264c6a, 0x00002600
-.long 0x36366c5a, 0x00003600, 0x3f3f7e41, 0x00003f00
-.long 0xf7f7f502, 0x0000f700, 0xcccc834f, 0x0000cc00
-.long 0x3434685c, 0x00003400, 0xa5a551f4, 0x0000a500
-.long 0xe5e5d134, 0x0000e500, 0xf1f1f908, 0x0000f100
-.long 0x7171e293, 0x00007100, 0xd8d8ab73, 0x0000d800
-.long 0x31316253, 0x00003100, 0x15152a3f, 0x00001500
-.long 0x0404080c, 0x00000400, 0xc7c79552, 0x0000c700
-.long 0x23234665, 0x00002300, 0xc3c39d5e, 0x0000c300
-.long 0x18183028, 0x00001800, 0x969637a1, 0x00009600
-.long 0x05050a0f, 0x00000500, 0x9a9a2fb5, 0x00009a00
-.long 0x07070e09, 0x00000700, 0x12122436, 0x00001200
-.long 0x80801b9b, 0x00008000, 0xe2e2df3d, 0x0000e200
-.long 0xebebcd26, 0x0000eb00, 0x27274e69, 0x00002700
-.long 0xb2b27fcd, 0x0000b200, 0x7575ea9f, 0x00007500
-.long 0x0909121b, 0x00000900, 0x83831d9e, 0x00008300
-.long 0x2c2c5874, 0x00002c00, 0x1a1a342e, 0x00001a00
-.long 0x1b1b362d, 0x00001b00, 0x6e6edcb2, 0x00006e00
-.long 0x5a5ab4ee, 0x00005a00, 0xa0a05bfb, 0x0000a000
-.long 0x5252a4f6, 0x00005200, 0x3b3b764d, 0x00003b00
-.long 0xd6d6b761, 0x0000d600, 0xb3b37dce, 0x0000b300
-.long 0x2929527b, 0x00002900, 0xe3e3dd3e, 0x0000e300
-.long 0x2f2f5e71, 0x00002f00, 0x84841397, 0x00008400
-.long 0x5353a6f5, 0x00005300, 0xd1d1b968, 0x0000d100
-.long 0x00000000, 0x00000000, 0xededc12c, 0x0000ed00
-.long 0x20204060, 0x00002000, 0xfcfce31f, 0x0000fc00
-.long 0xb1b179c8, 0x0000b100, 0x5b5bb6ed, 0x00005b00
-.long 0x6a6ad4be, 0x00006a00, 0xcbcb8d46, 0x0000cb00
-.long 0xbebe67d9, 0x0000be00, 0x3939724b, 0x00003900
-.long 0x4a4a94de, 0x00004a00, 0x4c4c98d4, 0x00004c00
-.long 0x5858b0e8, 0x00005800, 0xcfcf854a, 0x0000cf00
-.long 0xd0d0bb6b, 0x0000d000, 0xefefc52a, 0x0000ef00
-.long 0xaaaa4fe5, 0x0000aa00, 0xfbfbed16, 0x0000fb00
-.long 0x434386c5, 0x00004300, 0x4d4d9ad7, 0x00004d00
-.long 0x33336655, 0x00003300, 0x85851194, 0x00008500
-.long 0x45458acf, 0x00004500, 0xf9f9e910, 0x0000f900
-.long 0x02020406, 0x00000200, 0x7f7ffe81, 0x00007f00
-.long 0x5050a0f0, 0x00005000, 0x3c3c7844, 0x00003c00
-.long 0x9f9f25ba, 0x00009f00, 0xa8a84be3, 0x0000a800
-.long 0x5151a2f3, 0x00005100, 0xa3a35dfe, 0x0000a300
-.long 0x404080c0, 0x00004000, 0x8f8f058a, 0x00008f00
-.long 0x92923fad, 0x00009200, 0x9d9d21bc, 0x00009d00
-.long 0x38387048, 0x00003800, 0xf5f5f104, 0x0000f500
-.long 0xbcbc63df, 0x0000bc00, 0xb6b677c1, 0x0000b600
-.long 0xdadaaf75, 0x0000da00, 0x21214263, 0x00002100
-.long 0x10102030, 0x00001000, 0xffffe51a, 0x0000ff00
-.long 0xf3f3fd0e, 0x0000f300, 0xd2d2bf6d, 0x0000d200
-.long 0xcdcd814c, 0x0000cd00, 0x0c0c1814, 0x00000c00
-.long 0x13132635, 0x00001300, 0xececc32f, 0x0000ec00
-.long 0x5f5fbee1, 0x00005f00, 0x979735a2, 0x00009700
-.long 0x444488cc, 0x00004400, 0x17172e39, 0x00001700
-.long 0xc4c49357, 0x0000c400, 0xa7a755f2, 0x0000a700
-.long 0x7e7efc82, 0x00007e00, 0x3d3d7a47, 0x00003d00
-.long 0x6464c8ac, 0x00006400, 0x5d5dbae7, 0x00005d00
-.long 0x1919322b, 0x00001900, 0x7373e695, 0x00007300
-.long 0x6060c0a0, 0x00006000, 0x81811998, 0x00008100
-.long 0x4f4f9ed1, 0x00004f00, 0xdcdca37f, 0x0000dc00
-.long 0x22224466, 0x00002200, 0x2a2a547e, 0x00002a00
-.long 0x90903bab, 0x00009000, 0x88880b83, 0x00008800
-.long 0x46468cca, 0x00004600, 0xeeeec729, 0x0000ee00
-.long 0xb8b86bd3, 0x0000b800, 0x1414283c, 0x00001400
-.long 0xdedea779, 0x0000de00, 0x5e5ebce2, 0x00005e00
-.long 0x0b0b161d, 0x00000b00, 0xdbdbad76, 0x0000db00
-.long 0xe0e0db3b, 0x0000e000, 0x32326456, 0x00003200
-.long 0x3a3a744e, 0x00003a00, 0x0a0a141e, 0x00000a00
-.long 0x494992db, 0x00004900, 0x06060c0a, 0x00000600
-.long 0x2424486c, 0x00002400, 0x5c5cb8e4, 0x00005c00
-.long 0xc2c29f5d, 0x0000c200, 0xd3d3bd6e, 0x0000d300
-.long 0xacac43ef, 0x0000ac00, 0x6262c4a6, 0x00006200
-.long 0x919139a8, 0x00009100, 0x959531a4, 0x00009500
-.long 0xe4e4d337, 0x0000e400, 0x7979f28b, 0x00007900
-.long 0xe7e7d532, 0x0000e700, 0xc8c88b43, 0x0000c800
-.long 0x37376e59, 0x00003700, 0x6d6ddab7, 0x00006d00
-.long 0x8d8d018c, 0x00008d00, 0xd5d5b164, 0x0000d500
-.long 0x4e4e9cd2, 0x00004e00, 0xa9a949e0, 0x0000a900
-.long 0x6c6cd8b4, 0x00006c00, 0x5656acfa, 0x00005600
-.long 0xf4f4f307, 0x0000f400, 0xeaeacf25, 0x0000ea00
-.long 0x6565caaf, 0x00006500, 0x7a7af48e, 0x00007a00
-.long 0xaeae47e9, 0x0000ae00, 0x08081018, 0x00000800
-.long 0xbaba6fd5, 0x0000ba00, 0x7878f088, 0x00007800
-.long 0x25254a6f, 0x00002500, 0x2e2e5c72, 0x00002e00
-.long 0x1c1c3824, 0x00001c00, 0xa6a657f1, 0x0000a600
-.long 0xb4b473c7, 0x0000b400, 0xc6c69751, 0x0000c600
-.long 0xe8e8cb23, 0x0000e800, 0xdddda17c, 0x0000dd00
-.long 0x7474e89c, 0x00007400, 0x1f1f3e21, 0x00001f00
-.long 0x4b4b96dd, 0x00004b00, 0xbdbd61dc, 0x0000bd00
-.long 0x8b8b0d86, 0x00008b00, 0x8a8a0f85, 0x00008a00
-.long 0x7070e090, 0x00007000, 0x3e3e7c42, 0x00003e00
-.long 0xb5b571c4, 0x0000b500, 0x6666ccaa, 0x00006600
-.long 0x484890d8, 0x00004800, 0x03030605, 0x00000300
-.long 0xf6f6f701, 0x0000f600, 0x0e0e1c12, 0x00000e00
-.long 0x6161c2a3, 0x00006100, 0x35356a5f, 0x00003500
-.long 0x5757aef9, 0x00005700, 0xb9b969d0, 0x0000b900
-.long 0x86861791, 0x00008600, 0xc1c19958, 0x0000c100
-.long 0x1d1d3a27, 0x00001d00, 0x9e9e27b9, 0x00009e00
-.long 0xe1e1d938, 0x0000e100, 0xf8f8eb13, 0x0000f800
-.long 0x98982bb3, 0x00009800, 0x11112233, 0x00001100
-.long 0x6969d2bb, 0x00006900, 0xd9d9a970, 0x0000d900
-.long 0x8e8e0789, 0x00008e00, 0x949433a7, 0x00009400
-.long 0x9b9b2db6, 0x00009b00, 0x1e1e3c22, 0x00001e00
-.long 0x87871592, 0x00008700, 0xe9e9c920, 0x0000e900
-.long 0xcece8749, 0x0000ce00, 0x5555aaff, 0x00005500
-.long 0x28285078, 0x00002800, 0xdfdfa57a, 0x0000df00
-.long 0x8c8c038f, 0x00008c00, 0xa1a159f8, 0x0000a100
-.long 0x89890980, 0x00008900, 0x0d0d1a17, 0x00000d00
-.long 0xbfbf65da, 0x0000bf00, 0xe6e6d731, 0x0000e600
-.long 0x424284c6, 0x00004200, 0x6868d0b8, 0x00006800
-.long 0x414182c3, 0x00004100, 0x999929b0, 0x00009900
-.long 0x2d2d5a77, 0x00002d00, 0x0f0f1e11, 0x00000f00
-.long 0xb0b07bcb, 0x0000b000, 0x5454a8fc, 0x00005400
-.long 0xbbbb6dd6, 0x0000bb00, 0x16162c3a, 0x00001600
-.LtableE2:
-.long 0x63c6a563
-.LtableEs2:
-.long             0x00630000, 0x7cf8847c, 0x007c0000
-.long 0x77ee9977, 0x00770000, 0x7bf68d7b, 0x007b0000
-.long 0xf2ff0df2, 0x00f20000, 0x6bd6bd6b, 0x006b0000
-.long 0x6fdeb16f, 0x006f0000, 0xc59154c5, 0x00c50000
-.long 0x30605030, 0x00300000, 0x01020301, 0x00010000
-.long 0x67cea967, 0x00670000, 0x2b567d2b, 0x002b0000
-.long 0xfee719fe, 0x00fe0000, 0xd7b562d7, 0x00d70000
-.long 0xab4de6ab, 0x00ab0000, 0x76ec9a76, 0x00760000
-.long 0xca8f45ca, 0x00ca0000, 0x821f9d82, 0x00820000
-.long 0xc98940c9, 0x00c90000, 0x7dfa877d, 0x007d0000
-.long 0xfaef15fa, 0x00fa0000, 0x59b2eb59, 0x00590000
-.long 0x478ec947, 0x00470000, 0xf0fb0bf0, 0x00f00000
-.long 0xad41ecad, 0x00ad0000, 0xd4b367d4, 0x00d40000
-.long 0xa25ffda2, 0x00a20000, 0xaf45eaaf, 0x00af0000
-.long 0x9c23bf9c, 0x009c0000, 0xa453f7a4, 0x00a40000
-.long 0x72e49672, 0x00720000, 0xc09b5bc0, 0x00c00000
-.long 0xb775c2b7, 0x00b70000, 0xfde11cfd, 0x00fd0000
-.long 0x933dae93, 0x00930000, 0x264c6a26, 0x00260000
-.long 0x366c5a36, 0x00360000, 0x3f7e413f, 0x003f0000
-.long 0xf7f502f7, 0x00f70000, 0xcc834fcc, 0x00cc0000
-.long 0x34685c34, 0x00340000, 0xa551f4a5, 0x00a50000
-.long 0xe5d134e5, 0x00e50000, 0xf1f908f1, 0x00f10000
-.long 0x71e29371, 0x00710000, 0xd8ab73d8, 0x00d80000
-.long 0x31625331, 0x00310000, 0x152a3f15, 0x00150000
-.long 0x04080c04, 0x00040000, 0xc79552c7, 0x00c70000
-.long 0x23466523, 0x00230000, 0xc39d5ec3, 0x00c30000
-.long 0x18302818, 0x00180000, 0x9637a196, 0x00960000
-.long 0x050a0f05, 0x00050000, 0x9a2fb59a, 0x009a0000
-.long 0x070e0907, 0x00070000, 0x12243612, 0x00120000
-.long 0x801b9b80, 0x00800000, 0xe2df3de2, 0x00e20000
-.long 0xebcd26eb, 0x00eb0000, 0x274e6927, 0x00270000
-.long 0xb27fcdb2, 0x00b20000, 0x75ea9f75, 0x00750000
-.long 0x09121b09, 0x00090000, 0x831d9e83, 0x00830000
-.long 0x2c58742c, 0x002c0000, 0x1a342e1a, 0x001a0000
-.long 0x1b362d1b, 0x001b0000, 0x6edcb26e, 0x006e0000
-.long 0x5ab4ee5a, 0x005a0000, 0xa05bfba0, 0x00a00000
-.long 0x52a4f652, 0x00520000, 0x3b764d3b, 0x003b0000
-.long 0xd6b761d6, 0x00d60000, 0xb37dceb3, 0x00b30000
-.long 0x29527b29, 0x00290000, 0xe3dd3ee3, 0x00e30000
-.long 0x2f5e712f, 0x002f0000, 0x84139784, 0x00840000
-.long 0x53a6f553, 0x00530000, 0xd1b968d1, 0x00d10000
-.long 0x00000000, 0x00000000, 0xedc12ced, 0x00ed0000
-.long 0x20406020, 0x00200000, 0xfce31ffc, 0x00fc0000
-.long 0xb179c8b1, 0x00b10000, 0x5bb6ed5b, 0x005b0000
-.long 0x6ad4be6a, 0x006a0000, 0xcb8d46cb, 0x00cb0000
-.long 0xbe67d9be, 0x00be0000, 0x39724b39, 0x00390000
-.long 0x4a94de4a, 0x004a0000, 0x4c98d44c, 0x004c0000
-.long 0x58b0e858, 0x00580000, 0xcf854acf, 0x00cf0000
-.long 0xd0bb6bd0, 0x00d00000, 0xefc52aef, 0x00ef0000
-.long 0xaa4fe5aa, 0x00aa0000, 0xfbed16fb, 0x00fb0000
-.long 0x4386c543, 0x00430000, 0x4d9ad74d, 0x004d0000
-.long 0x33665533, 0x00330000, 0x85119485, 0x00850000
-.long 0x458acf45, 0x00450000, 0xf9e910f9, 0x00f90000
-.long 0x02040602, 0x00020000, 0x7ffe817f, 0x007f0000
-.long 0x50a0f050, 0x00500000, 0x3c78443c, 0x003c0000
-.long 0x9f25ba9f, 0x009f0000, 0xa84be3a8, 0x00a80000
-.long 0x51a2f351, 0x00510000, 0xa35dfea3, 0x00a30000
-.long 0x4080c040, 0x00400000, 0x8f058a8f, 0x008f0000
-.long 0x923fad92, 0x00920000, 0x9d21bc9d, 0x009d0000
-.long 0x38704838, 0x00380000, 0xf5f104f5, 0x00f50000
-.long 0xbc63dfbc, 0x00bc0000, 0xb677c1b6, 0x00b60000
-.long 0xdaaf75da, 0x00da0000, 0x21426321, 0x00210000
-.long 0x10203010, 0x00100000, 0xffe51aff, 0x00ff0000
-.long 0xf3fd0ef3, 0x00f30000, 0xd2bf6dd2, 0x00d20000
-.long 0xcd814ccd, 0x00cd0000, 0x0c18140c, 0x000c0000
-.long 0x13263513, 0x00130000, 0xecc32fec, 0x00ec0000
-.long 0x5fbee15f, 0x005f0000, 0x9735a297, 0x00970000
-.long 0x4488cc44, 0x00440000, 0x172e3917, 0x00170000
-.long 0xc49357c4, 0x00c40000, 0xa755f2a7, 0x00a70000
-.long 0x7efc827e, 0x007e0000, 0x3d7a473d, 0x003d0000
-.long 0x64c8ac64, 0x00640000, 0x5dbae75d, 0x005d0000
-.long 0x19322b19, 0x00190000, 0x73e69573, 0x00730000
-.long 0x60c0a060, 0x00600000, 0x81199881, 0x00810000
-.long 0x4f9ed14f, 0x004f0000, 0xdca37fdc, 0x00dc0000
-.long 0x22446622, 0x00220000, 0x2a547e2a, 0x002a0000
-.long 0x903bab90, 0x00900000, 0x880b8388, 0x00880000
-.long 0x468cca46, 0x00460000, 0xeec729ee, 0x00ee0000
-.long 0xb86bd3b8, 0x00b80000, 0x14283c14, 0x00140000
-.long 0xdea779de, 0x00de0000, 0x5ebce25e, 0x005e0000
-.long 0x0b161d0b, 0x000b0000, 0xdbad76db, 0x00db0000
-.long 0xe0db3be0, 0x00e00000, 0x32645632, 0x00320000
-.long 0x3a744e3a, 0x003a0000, 0x0a141e0a, 0x000a0000
-.long 0x4992db49, 0x00490000, 0x060c0a06, 0x00060000
-.long 0x24486c24, 0x00240000, 0x5cb8e45c, 0x005c0000
-.long 0xc29f5dc2, 0x00c20000, 0xd3bd6ed3, 0x00d30000
-.long 0xac43efac, 0x00ac0000, 0x62c4a662, 0x00620000
-.long 0x9139a891, 0x00910000, 0x9531a495, 0x00950000
-.long 0xe4d337e4, 0x00e40000, 0x79f28b79, 0x00790000
-.long 0xe7d532e7, 0x00e70000, 0xc88b43c8, 0x00c80000
-.long 0x376e5937, 0x00370000, 0x6ddab76d, 0x006d0000
-.long 0x8d018c8d, 0x008d0000, 0xd5b164d5, 0x00d50000
-.long 0x4e9cd24e, 0x004e0000, 0xa949e0a9, 0x00a90000
-.long 0x6cd8b46c, 0x006c0000, 0x56acfa56, 0x00560000
-.long 0xf4f307f4, 0x00f40000, 0xeacf25ea, 0x00ea0000
-.long 0x65caaf65, 0x00650000, 0x7af48e7a, 0x007a0000
-.long 0xae47e9ae, 0x00ae0000, 0x08101808, 0x00080000
-.long 0xba6fd5ba, 0x00ba0000, 0x78f08878, 0x00780000
-.long 0x254a6f25, 0x00250000, 0x2e5c722e, 0x002e0000
-.long 0x1c38241c, 0x001c0000, 0xa657f1a6, 0x00a60000
-.long 0xb473c7b4, 0x00b40000, 0xc69751c6, 0x00c60000
-.long 0xe8cb23e8, 0x00e80000, 0xdda17cdd, 0x00dd0000
-.long 0x74e89c74, 0x00740000, 0x1f3e211f, 0x001f0000
-.long 0x4b96dd4b, 0x004b0000, 0xbd61dcbd, 0x00bd0000
-.long 0x8b0d868b, 0x008b0000, 0x8a0f858a, 0x008a0000
-.long 0x70e09070, 0x00700000, 0x3e7c423e, 0x003e0000
-.long 0xb571c4b5, 0x00b50000, 0x66ccaa66, 0x00660000
-.long 0x4890d848, 0x00480000, 0x03060503, 0x00030000
-.long 0xf6f701f6, 0x00f60000, 0x0e1c120e, 0x000e0000
-.long 0x61c2a361, 0x00610000, 0x356a5f35, 0x00350000
-.long 0x57aef957, 0x00570000, 0xb969d0b9, 0x00b90000
-.long 0x86179186, 0x00860000, 0xc19958c1, 0x00c10000
-.long 0x1d3a271d, 0x001d0000, 0x9e27b99e, 0x009e0000
-.long 0xe1d938e1, 0x00e10000, 0xf8eb13f8, 0x00f80000
-.long 0x982bb398, 0x00980000, 0x11223311, 0x00110000
-.long 0x69d2bb69, 0x00690000, 0xd9a970d9, 0x00d90000
-.long 0x8e07898e, 0x008e0000, 0x9433a794, 0x00940000
-.long 0x9b2db69b, 0x009b0000, 0x1e3c221e, 0x001e0000
-.long 0x87159287, 0x00870000, 0xe9c920e9, 0x00e90000
-.long 0xce8749ce, 0x00ce0000, 0x55aaff55, 0x00550000
-.long 0x28507828, 0x00280000, 0xdfa57adf, 0x00df0000
-.long 0x8c038f8c, 0x008c0000, 0xa159f8a1, 0x00a10000
-.long 0x89098089, 0x00890000, 0x0d1a170d, 0x000d0000
-.long 0xbf65dabf, 0x00bf0000, 0xe6d731e6, 0x00e60000
-.long 0x4284c642, 0x00420000, 0x68d0b868, 0x00680000
-.long 0x4182c341, 0x00410000, 0x9929b099, 0x00990000
-.long 0x2d5a772d, 0x002d0000, 0x0f1e110f, 0x000f0000
-.long 0xb07bcbb0, 0x00b00000, 0x54a8fc54, 0x00540000
-.long 0xbb6dd6bb, 0x00bb0000, 0x162c3a16, 0x00160000
-.LtableE3:
-.long 0xc6a56363
-.LtableEs3:
-.long             0x63000000, 0xf8847c7c, 0x7c000000
-.long 0xee997777, 0x77000000, 0xf68d7b7b, 0x7b000000
-.long 0xff0df2f2, 0xf2000000, 0xd6bd6b6b, 0x6b000000
-.long 0xdeb16f6f, 0x6f000000, 0x9154c5c5, 0xc5000000
-.long 0x60503030, 0x30000000, 0x02030101, 0x01000000
-.long 0xcea96767, 0x67000000, 0x567d2b2b, 0x2b000000
-.long 0xe719fefe, 0xfe000000, 0xb562d7d7, 0xd7000000
-.long 0x4de6abab, 0xab000000, 0xec9a7676, 0x76000000
-.long 0x8f45caca, 0xca000000, 0x1f9d8282, 0x82000000
-.long 0x8940c9c9, 0xc9000000, 0xfa877d7d, 0x7d000000
-.long 0xef15fafa, 0xfa000000, 0xb2eb5959, 0x59000000
-.long 0x8ec94747, 0x47000000, 0xfb0bf0f0, 0xf0000000
-.long 0x41ecadad, 0xad000000, 0xb367d4d4, 0xd4000000
-.long 0x5ffda2a2, 0xa2000000, 0x45eaafaf, 0xaf000000
-.long 0x23bf9c9c, 0x9c000000, 0x53f7a4a4, 0xa4000000
-.long 0xe4967272, 0x72000000, 0x9b5bc0c0, 0xc0000000
-.long 0x75c2b7b7, 0xb7000000, 0xe11cfdfd, 0xfd000000
-.long 0x3dae9393, 0x93000000, 0x4c6a2626, 0x26000000
-.long 0x6c5a3636, 0x36000000, 0x7e413f3f, 0x3f000000
-.long 0xf502f7f7, 0xf7000000, 0x834fcccc, 0xcc000000
-.long 0x685c3434, 0x34000000, 0x51f4a5a5, 0xa5000000
-.long 0xd134e5e5, 0xe5000000, 0xf908f1f1, 0xf1000000
-.long 0xe2937171, 0x71000000, 0xab73d8d8, 0xd8000000
-.long 0x62533131, 0x31000000, 0x2a3f1515, 0x15000000
-.long 0x080c0404, 0x04000000, 0x9552c7c7, 0xc7000000
-.long 0x46652323, 0x23000000, 0x9d5ec3c3, 0xc3000000
-.long 0x30281818, 0x18000000, 0x37a19696, 0x96000000
-.long 0x0a0f0505, 0x05000000, 0x2fb59a9a, 0x9a000000
-.long 0x0e090707, 0x07000000, 0x24361212, 0x12000000
-.long 0x1b9b8080, 0x80000000, 0xdf3de2e2, 0xe2000000
-.long 0xcd26ebeb, 0xeb000000, 0x4e692727, 0x27000000
-.long 0x7fcdb2b2, 0xb2000000, 0xea9f7575, 0x75000000
-.long 0x121b0909, 0x09000000, 0x1d9e8383, 0x83000000
-.long 0x58742c2c, 0x2c000000, 0x342e1a1a, 0x1a000000
-.long 0x362d1b1b, 0x1b000000, 0xdcb26e6e, 0x6e000000
-.long 0xb4ee5a5a, 0x5a000000, 0x5bfba0a0, 0xa0000000
-.long 0xa4f65252, 0x52000000, 0x764d3b3b, 0x3b000000
-.long 0xb761d6d6, 0xd6000000, 0x7dceb3b3, 0xb3000000
-.long 0x527b2929, 0x29000000, 0xdd3ee3e3, 0xe3000000
-.long 0x5e712f2f, 0x2f000000, 0x13978484, 0x84000000
-.long 0xa6f55353, 0x53000000, 0xb968d1d1, 0xd1000000
-.long 0x00000000, 0x00000000, 0xc12ceded, 0xed000000
-.long 0x40602020, 0x20000000, 0xe31ffcfc, 0xfc000000
-.long 0x79c8b1b1, 0xb1000000, 0xb6ed5b5b, 0x5b000000
-.long 0xd4be6a6a, 0x6a000000, 0x8d46cbcb, 0xcb000000
-.long 0x67d9bebe, 0xbe000000, 0x724b3939, 0x39000000
-.long 0x94de4a4a, 0x4a000000, 0x98d44c4c, 0x4c000000
-.long 0xb0e85858, 0x58000000, 0x854acfcf, 0xcf000000
-.long 0xbb6bd0d0, 0xd0000000, 0xc52aefef, 0xef000000
-.long 0x4fe5aaaa, 0xaa000000, 0xed16fbfb, 0xfb000000
-.long 0x86c54343, 0x43000000, 0x9ad74d4d, 0x4d000000
-.long 0x66553333, 0x33000000, 0x11948585, 0x85000000
-.long 0x8acf4545, 0x45000000, 0xe910f9f9, 0xf9000000
-.long 0x04060202, 0x02000000, 0xfe817f7f, 0x7f000000
-.long 0xa0f05050, 0x50000000, 0x78443c3c, 0x3c000000
-.long 0x25ba9f9f, 0x9f000000, 0x4be3a8a8, 0xa8000000
-.long 0xa2f35151, 0x51000000, 0x5dfea3a3, 0xa3000000
-.long 0x80c04040, 0x40000000, 0x058a8f8f, 0x8f000000
-.long 0x3fad9292, 0x92000000, 0x21bc9d9d, 0x9d000000
-.long 0x70483838, 0x38000000, 0xf104f5f5, 0xf5000000
-.long 0x63dfbcbc, 0xbc000000, 0x77c1b6b6, 0xb6000000
-.long 0xaf75dada, 0xda000000, 0x42632121, 0x21000000
-.long 0x20301010, 0x10000000, 0xe51affff, 0xff000000
-.long 0xfd0ef3f3, 0xf3000000, 0xbf6dd2d2, 0xd2000000
-.long 0x814ccdcd, 0xcd000000, 0x18140c0c, 0x0c000000
-.long 0x26351313, 0x13000000, 0xc32fecec, 0xec000000
-.long 0xbee15f5f, 0x5f000000, 0x35a29797, 0x97000000
-.long 0x88cc4444, 0x44000000, 0x2e391717, 0x17000000
-.long 0x9357c4c4, 0xc4000000, 0x55f2a7a7, 0xa7000000
-.long 0xfc827e7e, 0x7e000000, 0x7a473d3d, 0x3d000000
-.long 0xc8ac6464, 0x64000000, 0xbae75d5d, 0x5d000000
-.long 0x322b1919, 0x19000000, 0xe6957373, 0x73000000
-.long 0xc0a06060, 0x60000000, 0x19988181, 0x81000000
-.long 0x9ed14f4f, 0x4f000000, 0xa37fdcdc, 0xdc000000
-.long 0x44662222, 0x22000000, 0x547e2a2a, 0x2a000000
-.long 0x3bab9090, 0x90000000, 0x0b838888, 0x88000000
-.long 0x8cca4646, 0x46000000, 0xc729eeee, 0xee000000
-.long 0x6bd3b8b8, 0xb8000000, 0x283c1414, 0x14000000
-.long 0xa779dede, 0xde000000, 0xbce25e5e, 0x5e000000
-.long 0x161d0b0b, 0x0b000000, 0xad76dbdb, 0xdb000000
-.long 0xdb3be0e0, 0xe0000000, 0x64563232, 0x32000000
-.long 0x744e3a3a, 0x3a000000, 0x141e0a0a, 0x0a000000
-.long 0x92db4949, 0x49000000, 0x0c0a0606, 0x06000000
-.long 0x486c2424, 0x24000000, 0xb8e45c5c, 0x5c000000
-.long 0x9f5dc2c2, 0xc2000000, 0xbd6ed3d3, 0xd3000000
-.long 0x43efacac, 0xac000000, 0xc4a66262, 0x62000000
-.long 0x39a89191, 0x91000000, 0x31a49595, 0x95000000
-.long 0xd337e4e4, 0xe4000000, 0xf28b7979, 0x79000000
-.long 0xd532e7e7, 0xe7000000, 0x8b43c8c8, 0xc8000000
-.long 0x6e593737, 0x37000000, 0xdab76d6d, 0x6d000000
-.long 0x018c8d8d, 0x8d000000, 0xb164d5d5, 0xd5000000
-.long 0x9cd24e4e, 0x4e000000, 0x49e0a9a9, 0xa9000000
-.long 0xd8b46c6c, 0x6c000000, 0xacfa5656, 0x56000000
-.long 0xf307f4f4, 0xf4000000, 0xcf25eaea, 0xea000000
-.long 0xcaaf6565, 0x65000000, 0xf48e7a7a, 0x7a000000
-.long 0x47e9aeae, 0xae000000, 0x10180808, 0x08000000
-.long 0x6fd5baba, 0xba000000, 0xf0887878, 0x78000000
-.long 0x4a6f2525, 0x25000000, 0x5c722e2e, 0x2e000000
-.long 0x38241c1c, 0x1c000000, 0x57f1a6a6, 0xa6000000
-.long 0x73c7b4b4, 0xb4000000, 0x9751c6c6, 0xc6000000
-.long 0xcb23e8e8, 0xe8000000, 0xa17cdddd, 0xdd000000
-.long 0xe89c7474, 0x74000000, 0x3e211f1f, 0x1f000000
-.long 0x96dd4b4b, 0x4b000000, 0x61dcbdbd, 0xbd000000
-.long 0x0d868b8b, 0x8b000000, 0x0f858a8a, 0x8a000000
-.long 0xe0907070, 0x70000000, 0x7c423e3e, 0x3e000000
-.long 0x71c4b5b5, 0xb5000000, 0xccaa6666, 0x66000000
-.long 0x90d84848, 0x48000000, 0x06050303, 0x03000000
-.long 0xf701f6f6, 0xf6000000, 0x1c120e0e, 0x0e000000
-.long 0xc2a36161, 0x61000000, 0x6a5f3535, 0x35000000
-.long 0xaef95757, 0x57000000, 0x69d0b9b9, 0xb9000000
-.long 0x17918686, 0x86000000, 0x9958c1c1, 0xc1000000
-.long 0x3a271d1d, 0x1d000000, 0x27b99e9e, 0x9e000000
-.long 0xd938e1e1, 0xe1000000, 0xeb13f8f8, 0xf8000000
-.long 0x2bb39898, 0x98000000, 0x22331111, 0x11000000
-.long 0xd2bb6969, 0x69000000, 0xa970d9d9, 0xd9000000
-.long 0x07898e8e, 0x8e000000, 0x33a79494, 0x94000000
-.long 0x2db69b9b, 0x9b000000, 0x3c221e1e, 0x1e000000
-.long 0x15928787, 0x87000000, 0xc920e9e9, 0xe9000000
-.long 0x8749cece, 0xce000000, 0xaaff5555, 0x55000000
-.long 0x50782828, 0x28000000, 0xa57adfdf, 0xdf000000
-.long 0x038f8c8c, 0x8c000000, 0x59f8a1a1, 0xa1000000
-.long 0x09808989, 0x89000000, 0x1a170d0d, 0x0d000000
-.long 0x65dabfbf, 0xbf000000, 0xd731e6e6, 0xe6000000
-.long 0x84c64242, 0x42000000, 0xd0b86868, 0x68000000
-.long 0x82c34141, 0x41000000, 0x29b09999, 0x99000000
-.long 0x5a772d2d, 0x2d000000, 0x1e110f0f, 0x0f000000
-.long 0x7bcbb0b0, 0xb0000000, 0xa8fc5454, 0x54000000
-.long 0x6dd6bbbb, 0xbb000000, 0x2c3a1616, 0x16000000
-
-/* Decryption tables */
-.LtableD0:
-.long 0x50a7f451
-.LtableDs0:
-.long             0x00000052, 0x5365417e, 0x00000009
-.long 0xc3a4171a, 0x0000006a, 0x965e273a, 0x000000d5
-.long 0xcb6bab3b, 0x00000030, 0xf1459d1f, 0x00000036
-.long 0xab58faac, 0x000000a5, 0x9303e34b, 0x00000038
-.long 0x55fa3020, 0x000000bf, 0xf66d76ad, 0x00000040
-.long 0x9176cc88, 0x000000a3, 0x254c02f5, 0x0000009e
-.long 0xfcd7e54f, 0x00000081, 0xd7cb2ac5, 0x000000f3
-.long 0x80443526, 0x000000d7, 0x8fa362b5, 0x000000fb
-.long 0x495ab1de, 0x0000007c, 0x671bba25, 0x000000e3
-.long 0x980eea45, 0x00000039, 0xe1c0fe5d, 0x00000082
-.long 0x02752fc3, 0x0000009b, 0x12f04c81, 0x0000002f
-.long 0xa397468d, 0x000000ff, 0xc6f9d36b, 0x00000087
-.long 0xe75f8f03, 0x00000034, 0x959c9215, 0x0000008e
-.long 0xeb7a6dbf, 0x00000043, 0xda595295, 0x00000044
-.long 0x2d83bed4, 0x000000c4, 0xd3217458, 0x000000de
-.long 0x2969e049, 0x000000e9, 0x44c8c98e, 0x000000cb
-.long 0x6a89c275, 0x00000054, 0x78798ef4, 0x0000007b
-.long 0x6b3e5899, 0x00000094, 0xdd71b927, 0x00000032
-.long 0xb64fe1be, 0x000000a6, 0x17ad88f0, 0x000000c2
-.long 0x66ac20c9, 0x00000023, 0xb43ace7d, 0x0000003d
-.long 0x184adf63, 0x000000ee, 0x82311ae5, 0x0000004c
-.long 0x60335197, 0x00000095, 0x457f5362, 0x0000000b
-.long 0xe07764b1, 0x00000042, 0x84ae6bbb, 0x000000fa
-.long 0x1ca081fe, 0x000000c3, 0x942b08f9, 0x0000004e
-.long 0x58684870, 0x00000008, 0x19fd458f, 0x0000002e
-.long 0x876cde94, 0x000000a1, 0xb7f87b52, 0x00000066
-.long 0x23d373ab, 0x00000028, 0xe2024b72, 0x000000d9
-.long 0x578f1fe3, 0x00000024, 0x2aab5566, 0x000000b2
-.long 0x0728ebb2, 0x00000076, 0x03c2b52f, 0x0000005b
-.long 0x9a7bc586, 0x000000a2, 0xa50837d3, 0x00000049
-.long 0xf2872830, 0x0000006d, 0xb2a5bf23, 0x0000008b
-.long 0xba6a0302, 0x000000d1, 0x5c8216ed, 0x00000025
-.long 0x2b1ccf8a, 0x00000072, 0x92b479a7, 0x000000f8
-.long 0xf0f207f3, 0x000000f6, 0xa1e2694e, 0x00000064
-.long 0xcdf4da65, 0x00000086, 0xd5be0506, 0x00000068
-.long 0x1f6234d1, 0x00000098, 0x8afea6c4, 0x00000016
-.long 0x9d532e34, 0x000000d4, 0xa055f3a2, 0x000000a4
-.long 0x32e18a05, 0x0000005c, 0x75ebf6a4, 0x000000cc
-.long 0x39ec830b, 0x0000005d, 0xaaef6040, 0x00000065
-.long 0x069f715e, 0x000000b6, 0x51106ebd, 0x00000092
-.long 0xf98a213e, 0x0000006c, 0x3d06dd96, 0x00000070
-.long 0xae053edd, 0x00000048, 0x46bde64d, 0x00000050
-.long 0xb58d5491, 0x000000fd, 0x055dc471, 0x000000ed
-.long 0x6fd40604, 0x000000b9, 0xff155060, 0x000000da
-.long 0x24fb9819, 0x0000005e, 0x97e9bdd6, 0x00000015
-.long 0xcc434089, 0x00000046, 0x779ed967, 0x00000057
-.long 0xbd42e8b0, 0x000000a7, 0x888b8907, 0x0000008d
-.long 0x385b19e7, 0x0000009d, 0xdbeec879, 0x00000084
-.long 0x470a7ca1, 0x00000090, 0xe90f427c, 0x000000d8
-.long 0xc91e84f8, 0x000000ab, 0x00000000, 0x00000000
-.long 0x83868009, 0x0000008c, 0x48ed2b32, 0x000000bc
-.long 0xac70111e, 0x000000d3, 0x4e725a6c, 0x0000000a
-.long 0xfbff0efd, 0x000000f7, 0x5638850f, 0x000000e4
-.long 0x1ed5ae3d, 0x00000058, 0x27392d36, 0x00000005
-.long 0x64d90f0a, 0x000000b8, 0x21a65c68, 0x000000b3
-.long 0xd1545b9b, 0x00000045, 0x3a2e3624, 0x00000006
-.long 0xb1670a0c, 0x000000d0, 0x0fe75793, 0x0000002c
-.long 0xd296eeb4, 0x0000001e, 0x9e919b1b, 0x0000008f
-.long 0x4fc5c080, 0x000000ca, 0xa220dc61, 0x0000003f
-.long 0x694b775a, 0x0000000f, 0x161a121c, 0x00000002
-.long 0x0aba93e2, 0x000000c1, 0xe52aa0c0, 0x000000af
-.long 0x43e0223c, 0x000000bd, 0x1d171b12, 0x00000003
-.long 0x0b0d090e, 0x00000001, 0xadc78bf2, 0x00000013
-.long 0xb9a8b62d, 0x0000008a, 0xc8a91e14, 0x0000006b
-.long 0x8519f157, 0x0000003a, 0x4c0775af, 0x00000091
-.long 0xbbdd99ee, 0x00000011, 0xfd607fa3, 0x00000041
-.long 0x9f2601f7, 0x0000004f, 0xbcf5725c, 0x00000067
-.long 0xc53b6644, 0x000000dc, 0x347efb5b, 0x000000ea
-.long 0x7629438b, 0x00000097, 0xdcc623cb, 0x000000f2
-.long 0x68fcedb6, 0x000000cf, 0x63f1e4b8, 0x000000ce
-.long 0xcadc31d7, 0x000000f0, 0x10856342, 0x000000b4
-.long 0x40229713, 0x000000e6, 0x2011c684, 0x00000073
-.long 0x7d244a85, 0x00000096, 0xf83dbbd2, 0x000000ac
-.long 0x1132f9ae, 0x00000074, 0x6da129c7, 0x00000022
-.long 0x4b2f9e1d, 0x000000e7, 0xf330b2dc, 0x000000ad
-.long 0xec52860d, 0x00000035, 0xd0e3c177, 0x00000085
-.long 0x6c16b32b, 0x000000e2, 0x99b970a9, 0x000000f9
-.long 0xfa489411, 0x00000037, 0x2264e947, 0x000000e8
-.long 0xc48cfca8, 0x0000001c, 0x1a3ff0a0, 0x00000075
-.long 0xd82c7d56, 0x000000df, 0xef903322, 0x0000006e
-.long 0xc74e4987, 0x00000047, 0xc1d138d9, 0x000000f1
-.long 0xfea2ca8c, 0x0000001a, 0x360bd498, 0x00000071
-.long 0xcf81f5a6, 0x0000001d, 0x28de7aa5, 0x00000029
-.long 0x268eb7da, 0x000000c5, 0xa4bfad3f, 0x00000089
-.long 0xe49d3a2c, 0x0000006f, 0x0d927850, 0x000000b7
-.long 0x9bcc5f6a, 0x00000062, 0x62467e54, 0x0000000e
-.long 0xc2138df6, 0x000000aa, 0xe8b8d890, 0x00000018
-.long 0x5ef7392e, 0x000000be, 0xf5afc382, 0x0000001b
-.long 0xbe805d9f, 0x000000fc, 0x7c93d069, 0x00000056
-.long 0xa92dd56f, 0x0000003e, 0xb31225cf, 0x0000004b
-.long 0x3b99acc8, 0x000000c6, 0xa77d1810, 0x000000d2
-.long 0x6e639ce8, 0x00000079, 0x7bbb3bdb, 0x00000020
-.long 0x097826cd, 0x0000009a, 0xf418596e, 0x000000db
-.long 0x01b79aec, 0x000000c0, 0xa89a4f83, 0x000000fe
-.long 0x656e95e6, 0x00000078, 0x7ee6ffaa, 0x000000cd
-.long 0x08cfbc21, 0x0000005a, 0xe6e815ef, 0x000000f4
-.long 0xd99be7ba, 0x0000001f, 0xce366f4a, 0x000000dd
-.long 0xd4099fea, 0x000000a8, 0xd67cb029, 0x00000033
-.long 0xafb2a431, 0x00000088, 0x31233f2a, 0x00000007
-.long 0x3094a5c6, 0x000000c7, 0xc066a235, 0x00000031
-.long 0x37bc4e74, 0x000000b1, 0xa6ca82fc, 0x00000012
-.long 0xb0d090e0, 0x00000010, 0x15d8a733, 0x00000059
-.long 0x4a9804f1, 0x00000027, 0xf7daec41, 0x00000080
-.long 0x0e50cd7f, 0x000000ec, 0x2ff69117, 0x0000005f
-.long 0x8dd64d76, 0x00000060, 0x4db0ef43, 0x00000051
-.long 0x544daacc, 0x0000007f, 0xdf0496e4, 0x000000a9
-.long 0xe3b5d19e, 0x00000019, 0x1b886a4c, 0x000000b5
-.long 0xb81f2cc1, 0x0000004a, 0x7f516546, 0x0000000d
-.long 0x04ea5e9d, 0x0000002d, 0x5d358c01, 0x000000e5
-.long 0x737487fa, 0x0000007a, 0x2e410bfb, 0x0000009f
-.long 0x5a1d67b3, 0x00000093, 0x52d2db92, 0x000000c9
-.long 0x335610e9, 0x0000009c, 0x1347d66d, 0x000000ef
-.long 0x8c61d79a, 0x000000a0, 0x7a0ca137, 0x000000e0
-.long 0x8e14f859, 0x0000003b, 0x893c13eb, 0x0000004d
-.long 0xee27a9ce, 0x000000ae, 0x35c961b7, 0x0000002a
-.long 0xede51ce1, 0x000000f5, 0x3cb1477a, 0x000000b0
-.long 0x59dfd29c, 0x000000c8, 0x3f73f255, 0x000000eb
-.long 0x79ce1418, 0x000000bb, 0xbf37c773, 0x0000003c
-.long 0xeacdf753, 0x00000083, 0x5baafd5f, 0x00000053
-.long 0x146f3ddf, 0x00000099, 0x86db4478, 0x00000061
-.long 0x81f3afca, 0x00000017, 0x3ec468b9, 0x0000002b
-.long 0x2c342438, 0x00000004, 0x5f40a3c2, 0x0000007e
-.long 0x72c31d16, 0x000000ba, 0x0c25e2bc, 0x00000077
-.long 0x8b493c28, 0x000000d6, 0x41950dff, 0x00000026
-.long 0x7101a839, 0x000000e1, 0xdeb30c08, 0x00000069
-.long 0x9ce4b4d8, 0x00000014, 0x90c15664, 0x00000063
-.long 0x6184cb7b, 0x00000055, 0x70b632d5, 0x00000021
-.long 0x745c6c48, 0x0000000c, 0x4257b8d0, 0x0000007d
-.LtableD1:
-.long 0xa7f45150
-.LtableDs1:
-.long             0x00005200, 0x65417e53, 0x00000900
-.long 0xa4171ac3, 0x00006a00, 0x5e273a96, 0x0000d500
-.long 0x6bab3bcb, 0x00003000, 0x459d1ff1, 0x00003600
-.long 0x58faacab, 0x0000a500, 0x03e34b93, 0x00003800
-.long 0xfa302055, 0x0000bf00, 0x6d76adf6, 0x00004000
-.long 0x76cc8891, 0x0000a300, 0x4c02f525, 0x00009e00
-.long 0xd7e54ffc, 0x00008100, 0xcb2ac5d7, 0x0000f300
-.long 0x44352680, 0x0000d700, 0xa362b58f, 0x0000fb00
-.long 0x5ab1de49, 0x00007c00, 0x1bba2567, 0x0000e300
-.long 0x0eea4598, 0x00003900, 0xc0fe5de1, 0x00008200
-.long 0x752fc302, 0x00009b00, 0xf04c8112, 0x00002f00
-.long 0x97468da3, 0x0000ff00, 0xf9d36bc6, 0x00008700
-.long 0x5f8f03e7, 0x00003400, 0x9c921595, 0x00008e00
-.long 0x7a6dbfeb, 0x00004300, 0x595295da, 0x00004400
-.long 0x83bed42d, 0x0000c400, 0x217458d3, 0x0000de00
-.long 0x69e04929, 0x0000e900, 0xc8c98e44, 0x0000cb00
-.long 0x89c2756a, 0x00005400, 0x798ef478, 0x00007b00
-.long 0x3e58996b, 0x00009400, 0x71b927dd, 0x00003200
-.long 0x4fe1beb6, 0x0000a600, 0xad88f017, 0x0000c200
-.long 0xac20c966, 0x00002300, 0x3ace7db4, 0x00003d00
-.long 0x4adf6318, 0x0000ee00, 0x311ae582, 0x00004c00
-.long 0x33519760, 0x00009500, 0x7f536245, 0x00000b00
-.long 0x7764b1e0, 0x00004200, 0xae6bbb84, 0x0000fa00
-.long 0xa081fe1c, 0x0000c300, 0x2b08f994, 0x00004e00
-.long 0x68487058, 0x00000800, 0xfd458f19, 0x00002e00
-.long 0x6cde9487, 0x0000a100, 0xf87b52b7, 0x00006600
-.long 0xd373ab23, 0x00002800, 0x024b72e2, 0x0000d900
-.long 0x8f1fe357, 0x00002400, 0xab55662a, 0x0000b200
-.long 0x28ebb207, 0x00007600, 0xc2b52f03, 0x00005b00
-.long 0x7bc5869a, 0x0000a200, 0x0837d3a5, 0x00004900
-.long 0x872830f2, 0x00006d00, 0xa5bf23b2, 0x00008b00
-.long 0x6a0302ba, 0x0000d100, 0x8216ed5c, 0x00002500
-.long 0x1ccf8a2b, 0x00007200, 0xb479a792, 0x0000f800
-.long 0xf207f3f0, 0x0000f600, 0xe2694ea1, 0x00006400
-.long 0xf4da65cd, 0x00008600, 0xbe0506d5, 0x00006800
-.long 0x6234d11f, 0x00009800, 0xfea6c48a, 0x00001600
-.long 0x532e349d, 0x0000d400, 0x55f3a2a0, 0x0000a400
-.long 0xe18a0532, 0x00005c00, 0xebf6a475, 0x0000cc00
-.long 0xec830b39, 0x00005d00, 0xef6040aa, 0x00006500
-.long 0x9f715e06, 0x0000b600, 0x106ebd51, 0x00009200
-.long 0x8a213ef9, 0x00006c00, 0x06dd963d, 0x00007000
-.long 0x053eddae, 0x00004800, 0xbde64d46, 0x00005000
-.long 0x8d5491b5, 0x0000fd00, 0x5dc47105, 0x0000ed00
-.long 0xd406046f, 0x0000b900, 0x155060ff, 0x0000da00
-.long 0xfb981924, 0x00005e00, 0xe9bdd697, 0x00001500
-.long 0x434089cc, 0x00004600, 0x9ed96777, 0x00005700
-.long 0x42e8b0bd, 0x0000a700, 0x8b890788, 0x00008d00
-.long 0x5b19e738, 0x00009d00, 0xeec879db, 0x00008400
-.long 0x0a7ca147, 0x00009000, 0x0f427ce9, 0x0000d800
-.long 0x1e84f8c9, 0x0000ab00, 0x00000000, 0x00000000
-.long 0x86800983, 0x00008c00, 0xed2b3248, 0x0000bc00
-.long 0x70111eac, 0x0000d300, 0x725a6c4e, 0x00000a00
-.long 0xff0efdfb, 0x0000f700, 0x38850f56, 0x0000e400
-.long 0xd5ae3d1e, 0x00005800, 0x392d3627, 0x00000500
-.long 0xd90f0a64, 0x0000b800, 0xa65c6821, 0x0000b300
-.long 0x545b9bd1, 0x00004500, 0x2e36243a, 0x00000600
-.long 0x670a0cb1, 0x0000d000, 0xe757930f, 0x00002c00
-.long 0x96eeb4d2, 0x00001e00, 0x919b1b9e, 0x00008f00
-.long 0xc5c0804f, 0x0000ca00, 0x20dc61a2, 0x00003f00
-.long 0x4b775a69, 0x00000f00, 0x1a121c16, 0x00000200
-.long 0xba93e20a, 0x0000c100, 0x2aa0c0e5, 0x0000af00
-.long 0xe0223c43, 0x0000bd00, 0x171b121d, 0x00000300
-.long 0x0d090e0b, 0x00000100, 0xc78bf2ad, 0x00001300
-.long 0xa8b62db9, 0x00008a00, 0xa91e14c8, 0x00006b00
-.long 0x19f15785, 0x00003a00, 0x0775af4c, 0x00009100
-.long 0xdd99eebb, 0x00001100, 0x607fa3fd, 0x00004100
-.long 0x2601f79f, 0x00004f00, 0xf5725cbc, 0x00006700
-.long 0x3b6644c5, 0x0000dc00, 0x7efb5b34, 0x0000ea00
-.long 0x29438b76, 0x00009700, 0xc623cbdc, 0x0000f200
-.long 0xfcedb668, 0x0000cf00, 0xf1e4b863, 0x0000ce00
-.long 0xdc31d7ca, 0x0000f000, 0x85634210, 0x0000b400
-.long 0x22971340, 0x0000e600, 0x11c68420, 0x00007300
-.long 0x244a857d, 0x00009600, 0x3dbbd2f8, 0x0000ac00
-.long 0x32f9ae11, 0x00007400, 0xa129c76d, 0x00002200
-.long 0x2f9e1d4b, 0x0000e700, 0x30b2dcf3, 0x0000ad00
-.long 0x52860dec, 0x00003500, 0xe3c177d0, 0x00008500
-.long 0x16b32b6c, 0x0000e200, 0xb970a999, 0x0000f900
-.long 0x489411fa, 0x00003700, 0x64e94722, 0x0000e800
-.long 0x8cfca8c4, 0x00001c00, 0x3ff0a01a, 0x00007500
-.long 0x2c7d56d8, 0x0000df00, 0x903322ef, 0x00006e00
-.long 0x4e4987c7, 0x00004700, 0xd138d9c1, 0x0000f100
-.long 0xa2ca8cfe, 0x00001a00, 0x0bd49836, 0x00007100
-.long 0x81f5a6cf, 0x00001d00, 0xde7aa528, 0x00002900
-.long 0x8eb7da26, 0x0000c500, 0xbfad3fa4, 0x00008900
-.long 0x9d3a2ce4, 0x00006f00, 0x9278500d, 0x0000b700
-.long 0xcc5f6a9b, 0x00006200, 0x467e5462, 0x00000e00
-.long 0x138df6c2, 0x0000aa00, 0xb8d890e8, 0x00001800
-.long 0xf7392e5e, 0x0000be00, 0xafc382f5, 0x00001b00
-.long 0x805d9fbe, 0x0000fc00, 0x93d0697c, 0x00005600
-.long 0x2dd56fa9, 0x00003e00, 0x1225cfb3, 0x00004b00
-.long 0x99acc83b, 0x0000c600, 0x7d1810a7, 0x0000d200
-.long 0x639ce86e, 0x00007900, 0xbb3bdb7b, 0x00002000
-.long 0x7826cd09, 0x00009a00, 0x18596ef4, 0x0000db00
-.long 0xb79aec01, 0x0000c000, 0x9a4f83a8, 0x0000fe00
-.long 0x6e95e665, 0x00007800, 0xe6ffaa7e, 0x0000cd00
-.long 0xcfbc2108, 0x00005a00, 0xe815efe6, 0x0000f400
-.long 0x9be7bad9, 0x00001f00, 0x366f4ace, 0x0000dd00
-.long 0x099fead4, 0x0000a800, 0x7cb029d6, 0x00003300
-.long 0xb2a431af, 0x00008800, 0x233f2a31, 0x00000700
-.long 0x94a5c630, 0x0000c700, 0x66a235c0, 0x00003100
-.long 0xbc4e7437, 0x0000b100, 0xca82fca6, 0x00001200
-.long 0xd090e0b0, 0x00001000, 0xd8a73315, 0x00005900
-.long 0x9804f14a, 0x00002700, 0xdaec41f7, 0x00008000
-.long 0x50cd7f0e, 0x0000ec00, 0xf691172f, 0x00005f00
-.long 0xd64d768d, 0x00006000, 0xb0ef434d, 0x00005100
-.long 0x4daacc54, 0x00007f00, 0x0496e4df, 0x0000a900
-.long 0xb5d19ee3, 0x00001900, 0x886a4c1b, 0x0000b500
-.long 0x1f2cc1b8, 0x00004a00, 0x5165467f, 0x00000d00
-.long 0xea5e9d04, 0x00002d00, 0x358c015d, 0x0000e500
-.long 0x7487fa73, 0x00007a00, 0x410bfb2e, 0x00009f00
-.long 0x1d67b35a, 0x00009300, 0xd2db9252, 0x0000c900
-.long 0x5610e933, 0x00009c00, 0x47d66d13, 0x0000ef00
-.long 0x61d79a8c, 0x0000a000, 0x0ca1377a, 0x0000e000
-.long 0x14f8598e, 0x00003b00, 0x3c13eb89, 0x00004d00
-.long 0x27a9ceee, 0x0000ae00, 0xc961b735, 0x00002a00
-.long 0xe51ce1ed, 0x0000f500, 0xb1477a3c, 0x0000b000
-.long 0xdfd29c59, 0x0000c800, 0x73f2553f, 0x0000eb00
-.long 0xce141879, 0x0000bb00, 0x37c773bf, 0x00003c00
-.long 0xcdf753ea, 0x00008300, 0xaafd5f5b, 0x00005300
-.long 0x6f3ddf14, 0x00009900, 0xdb447886, 0x00006100
-.long 0xf3afca81, 0x00001700, 0xc468b93e, 0x00002b00
-.long 0x3424382c, 0x00000400, 0x40a3c25f, 0x00007e00
-.long 0xc31d1672, 0x0000ba00, 0x25e2bc0c, 0x00007700
-.long 0x493c288b, 0x0000d600, 0x950dff41, 0x00002600
-.long 0x01a83971, 0x0000e100, 0xb30c08de, 0x00006900
-.long 0xe4b4d89c, 0x00001400, 0xc1566490, 0x00006300
-.long 0x84cb7b61, 0x00005500, 0xb632d570, 0x00002100
-.long 0x5c6c4874, 0x00000c00, 0x57b8d042, 0x00007d00
-.LtableD2:
-.long 0xf45150a7
-.LtableDs2:
-.long             0x00520000, 0x417e5365, 0x00090000
-.long 0x171ac3a4, 0x006a0000, 0x273a965e, 0x00d50000
-.long 0xab3bcb6b, 0x00300000, 0x9d1ff145, 0x00360000
-.long 0xfaacab58, 0x00a50000, 0xe34b9303, 0x00380000
-.long 0x302055fa, 0x00bf0000, 0x76adf66d, 0x00400000
-.long 0xcc889176, 0x00a30000, 0x02f5254c, 0x009e0000
-.long 0xe54ffcd7, 0x00810000, 0x2ac5d7cb, 0x00f30000
-.long 0x35268044, 0x00d70000, 0x62b58fa3, 0x00fb0000
-.long 0xb1de495a, 0x007c0000, 0xba25671b, 0x00e30000
-.long 0xea45980e, 0x00390000, 0xfe5de1c0, 0x00820000
-.long 0x2fc30275, 0x009b0000, 0x4c8112f0, 0x002f0000
-.long 0x468da397, 0x00ff0000, 0xd36bc6f9, 0x00870000
-.long 0x8f03e75f, 0x00340000, 0x9215959c, 0x008e0000
-.long 0x6dbfeb7a, 0x00430000, 0x5295da59, 0x00440000
-.long 0xbed42d83, 0x00c40000, 0x7458d321, 0x00de0000
-.long 0xe0492969, 0x00e90000, 0xc98e44c8, 0x00cb0000
-.long 0xc2756a89, 0x00540000, 0x8ef47879, 0x007b0000
-.long 0x58996b3e, 0x00940000, 0xb927dd71, 0x00320000
-.long 0xe1beb64f, 0x00a60000, 0x88f017ad, 0x00c20000
-.long 0x20c966ac, 0x00230000, 0xce7db43a, 0x003d0000
-.long 0xdf63184a, 0x00ee0000, 0x1ae58231, 0x004c0000
-.long 0x51976033, 0x00950000, 0x5362457f, 0x000b0000
-.long 0x64b1e077, 0x00420000, 0x6bbb84ae, 0x00fa0000
-.long 0x81fe1ca0, 0x00c30000, 0x08f9942b, 0x004e0000
-.long 0x48705868, 0x00080000, 0x458f19fd, 0x002e0000
-.long 0xde94876c, 0x00a10000, 0x7b52b7f8, 0x00660000
-.long 0x73ab23d3, 0x00280000, 0x4b72e202, 0x00d90000
-.long 0x1fe3578f, 0x00240000, 0x55662aab, 0x00b20000
-.long 0xebb20728, 0x00760000, 0xb52f03c2, 0x005b0000
-.long 0xc5869a7b, 0x00a20000, 0x37d3a508, 0x00490000
-.long 0x2830f287, 0x006d0000, 0xbf23b2a5, 0x008b0000
-.long 0x0302ba6a, 0x00d10000, 0x16ed5c82, 0x00250000
-.long 0xcf8a2b1c, 0x00720000, 0x79a792b4, 0x00f80000
-.long 0x07f3f0f2, 0x00f60000, 0x694ea1e2, 0x00640000
-.long 0xda65cdf4, 0x00860000, 0x0506d5be, 0x00680000
-.long 0x34d11f62, 0x00980000, 0xa6c48afe, 0x00160000
-.long 0x2e349d53, 0x00d40000, 0xf3a2a055, 0x00a40000
-.long 0x8a0532e1, 0x005c0000, 0xf6a475eb, 0x00cc0000
-.long 0x830b39ec, 0x005d0000, 0x6040aaef, 0x00650000
-.long 0x715e069f, 0x00b60000, 0x6ebd5110, 0x00920000
-.long 0x213ef98a, 0x006c0000, 0xdd963d06, 0x00700000
-.long 0x3eddae05, 0x00480000, 0xe64d46bd, 0x00500000
-.long 0x5491b58d, 0x00fd0000, 0xc471055d, 0x00ed0000
-.long 0x06046fd4, 0x00b90000, 0x5060ff15, 0x00da0000
-.long 0x981924fb, 0x005e0000, 0xbdd697e9, 0x00150000
-.long 0x4089cc43, 0x00460000, 0xd967779e, 0x00570000
-.long 0xe8b0bd42, 0x00a70000, 0x8907888b, 0x008d0000
-.long 0x19e7385b, 0x009d0000, 0xc879dbee, 0x00840000
-.long 0x7ca1470a, 0x00900000, 0x427ce90f, 0x00d80000
-.long 0x84f8c91e, 0x00ab0000, 0x00000000, 0x00000000
-.long 0x80098386, 0x008c0000, 0x2b3248ed, 0x00bc0000
-.long 0x111eac70, 0x00d30000, 0x5a6c4e72, 0x000a0000
-.long 0x0efdfbff, 0x00f70000, 0x850f5638, 0x00e40000
-.long 0xae3d1ed5, 0x00580000, 0x2d362739, 0x00050000
-.long 0x0f0a64d9, 0x00b80000, 0x5c6821a6, 0x00b30000
-.long 0x5b9bd154, 0x00450000, 0x36243a2e, 0x00060000
-.long 0x0a0cb167, 0x00d00000, 0x57930fe7, 0x002c0000
-.long 0xeeb4d296, 0x001e0000, 0x9b1b9e91, 0x008f0000
-.long 0xc0804fc5, 0x00ca0000, 0xdc61a220, 0x003f0000
-.long 0x775a694b, 0x000f0000, 0x121c161a, 0x00020000
-.long 0x93e20aba, 0x00c10000, 0xa0c0e52a, 0x00af0000
-.long 0x223c43e0, 0x00bd0000, 0x1b121d17, 0x00030000
-.long 0x090e0b0d, 0x00010000, 0x8bf2adc7, 0x00130000
-.long 0xb62db9a8, 0x008a0000, 0x1e14c8a9, 0x006b0000
-.long 0xf1578519, 0x003a0000, 0x75af4c07, 0x00910000
-.long 0x99eebbdd, 0x00110000, 0x7fa3fd60, 0x00410000
-.long 0x01f79f26, 0x004f0000, 0x725cbcf5, 0x00670000
-.long 0x6644c53b, 0x00dc0000, 0xfb5b347e, 0x00ea0000
-.long 0x438b7629, 0x00970000, 0x23cbdcc6, 0x00f20000
-.long 0xedb668fc, 0x00cf0000, 0xe4b863f1, 0x00ce0000
-.long 0x31d7cadc, 0x00f00000, 0x63421085, 0x00b40000
-.long 0x97134022, 0x00e60000, 0xc6842011, 0x00730000
-.long 0x4a857d24, 0x00960000, 0xbbd2f83d, 0x00ac0000
-.long 0xf9ae1132, 0x00740000, 0x29c76da1, 0x00220000
-.long 0x9e1d4b2f, 0x00e70000, 0xb2dcf330, 0x00ad0000
-.long 0x860dec52, 0x00350000, 0xc177d0e3, 0x00850000
-.long 0xb32b6c16, 0x00e20000, 0x70a999b9, 0x00f90000
-.long 0x9411fa48, 0x00370000, 0xe9472264, 0x00e80000
-.long 0xfca8c48c, 0x001c0000, 0xf0a01a3f, 0x00750000
-.long 0x7d56d82c, 0x00df0000, 0x3322ef90, 0x006e0000
-.long 0x4987c74e, 0x00470000, 0x38d9c1d1, 0x00f10000
-.long 0xca8cfea2, 0x001a0000, 0xd498360b, 0x00710000
-.long 0xf5a6cf81, 0x001d0000, 0x7aa528de, 0x00290000
-.long 0xb7da268e, 0x00c50000, 0xad3fa4bf, 0x00890000
-.long 0x3a2ce49d, 0x006f0000, 0x78500d92, 0x00b70000
-.long 0x5f6a9bcc, 0x00620000, 0x7e546246, 0x000e0000
-.long 0x8df6c213, 0x00aa0000, 0xd890e8b8, 0x00180000
-.long 0x392e5ef7, 0x00be0000, 0xc382f5af, 0x001b0000
-.long 0x5d9fbe80, 0x00fc0000, 0xd0697c93, 0x00560000
-.long 0xd56fa92d, 0x003e0000, 0x25cfb312, 0x004b0000
-.long 0xacc83b99, 0x00c60000, 0x1810a77d, 0x00d20000
-.long 0x9ce86e63, 0x00790000, 0x3bdb7bbb, 0x00200000
-.long 0x26cd0978, 0x009a0000, 0x596ef418, 0x00db0000
-.long 0x9aec01b7, 0x00c00000, 0x4f83a89a, 0x00fe0000
-.long 0x95e6656e, 0x00780000, 0xffaa7ee6, 0x00cd0000
-.long 0xbc2108cf, 0x005a0000, 0x15efe6e8, 0x00f40000
-.long 0xe7bad99b, 0x001f0000, 0x6f4ace36, 0x00dd0000
-.long 0x9fead409, 0x00a80000, 0xb029d67c, 0x00330000
-.long 0xa431afb2, 0x00880000, 0x3f2a3123, 0x00070000
-.long 0xa5c63094, 0x00c70000, 0xa235c066, 0x00310000
-.long 0x4e7437bc, 0x00b10000, 0x82fca6ca, 0x00120000
-.long 0x90e0b0d0, 0x00100000, 0xa73315d8, 0x00590000
-.long 0x04f14a98, 0x00270000, 0xec41f7da, 0x00800000
-.long 0xcd7f0e50, 0x00ec0000, 0x91172ff6, 0x005f0000
-.long 0x4d768dd6, 0x00600000, 0xef434db0, 0x00510000
-.long 0xaacc544d, 0x007f0000, 0x96e4df04, 0x00a90000
-.long 0xd19ee3b5, 0x00190000, 0x6a4c1b88, 0x00b50000
-.long 0x2cc1b81f, 0x004a0000, 0x65467f51, 0x000d0000
-.long 0x5e9d04ea, 0x002d0000, 0x8c015d35, 0x00e50000
-.long 0x87fa7374, 0x007a0000, 0x0bfb2e41, 0x009f0000
-.long 0x67b35a1d, 0x00930000, 0xdb9252d2, 0x00c90000
-.long 0x10e93356, 0x009c0000, 0xd66d1347, 0x00ef0000
-.long 0xd79a8c61, 0x00a00000, 0xa1377a0c, 0x00e00000
-.long 0xf8598e14, 0x003b0000, 0x13eb893c, 0x004d0000
-.long 0xa9ceee27, 0x00ae0000, 0x61b735c9, 0x002a0000
-.long 0x1ce1ede5, 0x00f50000, 0x477a3cb1, 0x00b00000
-.long 0xd29c59df, 0x00c80000, 0xf2553f73, 0x00eb0000
-.long 0x141879ce, 0x00bb0000, 0xc773bf37, 0x003c0000
-.long 0xf753eacd, 0x00830000, 0xfd5f5baa, 0x00530000
-.long 0x3ddf146f, 0x00990000, 0x447886db, 0x00610000
-.long 0xafca81f3, 0x00170000, 0x68b93ec4, 0x002b0000
-.long 0x24382c34, 0x00040000, 0xa3c25f40, 0x007e0000
-.long 0x1d1672c3, 0x00ba0000, 0xe2bc0c25, 0x00770000
-.long 0x3c288b49, 0x00d60000, 0x0dff4195, 0x00260000
-.long 0xa8397101, 0x00e10000, 0x0c08deb3, 0x00690000
-.long 0xb4d89ce4, 0x00140000, 0x566490c1, 0x00630000
-.long 0xcb7b6184, 0x00550000, 0x32d570b6, 0x00210000
-.long 0x6c48745c, 0x000c0000, 0xb8d04257, 0x007d0000
-.LtableD3:
-.long 0x5150a7f4
-.LtableDs3:
-.long             0x52000000, 0x7e536541, 0x09000000
-.long 0x1ac3a417, 0x6a000000, 0x3a965e27, 0xd5000000
-.long 0x3bcb6bab, 0x30000000, 0x1ff1459d, 0x36000000
-.long 0xacab58fa, 0xa5000000, 0x4b9303e3, 0x38000000
-.long 0x2055fa30, 0xbf000000, 0xadf66d76, 0x40000000
-.long 0x889176cc, 0xa3000000, 0xf5254c02, 0x9e000000
-.long 0x4ffcd7e5, 0x81000000, 0xc5d7cb2a, 0xf3000000
-.long 0x26804435, 0xd7000000, 0xb58fa362, 0xfb000000
-.long 0xde495ab1, 0x7c000000, 0x25671bba, 0xe3000000
-.long 0x45980eea, 0x39000000, 0x5de1c0fe, 0x82000000
-.long 0xc302752f, 0x9b000000, 0x8112f04c, 0x2f000000
-.long 0x8da39746, 0xff000000, 0x6bc6f9d3, 0x87000000
-.long 0x03e75f8f, 0x34000000, 0x15959c92, 0x8e000000
-.long 0xbfeb7a6d, 0x43000000, 0x95da5952, 0x44000000
-.long 0xd42d83be, 0xc4000000, 0x58d32174, 0xde000000
-.long 0x492969e0, 0xe9000000, 0x8e44c8c9, 0xcb000000
-.long 0x756a89c2, 0x54000000, 0xf478798e, 0x7b000000
-.long 0x996b3e58, 0x94000000, 0x27dd71b9, 0x32000000
-.long 0xbeb64fe1, 0xa6000000, 0xf017ad88, 0xc2000000
-.long 0xc966ac20, 0x23000000, 0x7db43ace, 0x3d000000
-.long 0x63184adf, 0xee000000, 0xe582311a, 0x4c000000
-.long 0x97603351, 0x95000000, 0x62457f53, 0x0b000000
-.long 0xb1e07764, 0x42000000, 0xbb84ae6b, 0xfa000000
-.long 0xfe1ca081, 0xc3000000, 0xf9942b08, 0x4e000000
-.long 0x70586848, 0x08000000, 0x8f19fd45, 0x2e000000
-.long 0x94876cde, 0xa1000000, 0x52b7f87b, 0x66000000
-.long 0xab23d373, 0x28000000, 0x72e2024b, 0xd9000000
-.long 0xe3578f1f, 0x24000000, 0x662aab55, 0xb2000000
-.long 0xb20728eb, 0x76000000, 0x2f03c2b5, 0x5b000000
-.long 0x869a7bc5, 0xa2000000, 0xd3a50837, 0x49000000
-.long 0x30f28728, 0x6d000000, 0x23b2a5bf, 0x8b000000
-.long 0x02ba6a03, 0xd1000000, 0xed5c8216, 0x25000000
-.long 0x8a2b1ccf, 0x72000000, 0xa792b479, 0xf8000000
-.long 0xf3f0f207, 0xf6000000, 0x4ea1e269, 0x64000000
-.long 0x65cdf4da, 0x86000000, 0x06d5be05, 0x68000000
-.long 0xd11f6234, 0x98000000, 0xc48afea6, 0x16000000
-.long 0x349d532e, 0xd4000000, 0xa2a055f3, 0xa4000000
-.long 0x0532e18a, 0x5c000000, 0xa475ebf6, 0xcc000000
-.long 0x0b39ec83, 0x5d000000, 0x40aaef60, 0x65000000
-.long 0x5e069f71, 0xb6000000, 0xbd51106e, 0x92000000
-.long 0x3ef98a21, 0x6c000000, 0x963d06dd, 0x70000000
-.long 0xddae053e, 0x48000000, 0x4d46bde6, 0x50000000
-.long 0x91b58d54, 0xfd000000, 0x71055dc4, 0xed000000
-.long 0x046fd406, 0xb9000000, 0x60ff1550, 0xda000000
-.long 0x1924fb98, 0x5e000000, 0xd697e9bd, 0x15000000
-.long 0x89cc4340, 0x46000000, 0x67779ed9, 0x57000000
-.long 0xb0bd42e8, 0xa7000000, 0x07888b89, 0x8d000000
-.long 0xe7385b19, 0x9d000000, 0x79dbeec8, 0x84000000
-.long 0xa1470a7c, 0x90000000, 0x7ce90f42, 0xd8000000
-.long 0xf8c91e84, 0xab000000, 0x00000000, 0x00000000
-.long 0x09838680, 0x8c000000, 0x3248ed2b, 0xbc000000
-.long 0x1eac7011, 0xd3000000, 0x6c4e725a, 0x0a000000
-.long 0xfdfbff0e, 0xf7000000, 0x0f563885, 0xe4000000
-.long 0x3d1ed5ae, 0x58000000, 0x3627392d, 0x05000000
-.long 0x0a64d90f, 0xb8000000, 0x6821a65c, 0xb3000000
-.long 0x9bd1545b, 0x45000000, 0x243a2e36, 0x06000000
-.long 0x0cb1670a, 0xd0000000, 0x930fe757, 0x2c000000
-.long 0xb4d296ee, 0x1e000000, 0x1b9e919b, 0x8f000000
-.long 0x804fc5c0, 0xca000000, 0x61a220dc, 0x3f000000
-.long 0x5a694b77, 0x0f000000, 0x1c161a12, 0x02000000
-.long 0xe20aba93, 0xc1000000, 0xc0e52aa0, 0xaf000000
-.long 0x3c43e022, 0xbd000000, 0x121d171b, 0x03000000
-.long 0x0e0b0d09, 0x01000000, 0xf2adc78b, 0x13000000
-.long 0x2db9a8b6, 0x8a000000, 0x14c8a91e, 0x6b000000
-.long 0x578519f1, 0x3a000000, 0xaf4c0775, 0x91000000
-.long 0xeebbdd99, 0x11000000, 0xa3fd607f, 0x41000000
-.long 0xf79f2601, 0x4f000000, 0x5cbcf572, 0x67000000
-.long 0x44c53b66, 0xdc000000, 0x5b347efb, 0xea000000
-.long 0x8b762943, 0x97000000, 0xcbdcc623, 0xf2000000
-.long 0xb668fced, 0xcf000000, 0xb863f1e4, 0xce000000
-.long 0xd7cadc31, 0xf0000000, 0x42108563, 0xb4000000
-.long 0x13402297, 0xe6000000, 0x842011c6, 0x73000000
-.long 0x857d244a, 0x96000000, 0xd2f83dbb, 0xac000000
-.long 0xae1132f9, 0x74000000, 0xc76da129, 0x22000000
-.long 0x1d4b2f9e, 0xe7000000, 0xdcf330b2, 0xad000000
-.long 0x0dec5286, 0x35000000, 0x77d0e3c1, 0x85000000
-.long 0x2b6c16b3, 0xe2000000, 0xa999b970, 0xf9000000
-.long 0x11fa4894, 0x37000000, 0x472264e9, 0xe8000000
-.long 0xa8c48cfc, 0x1c000000, 0xa01a3ff0, 0x75000000
-.long 0x56d82c7d, 0xdf000000, 0x22ef9033, 0x6e000000
-.long 0x87c74e49, 0x47000000, 0xd9c1d138, 0xf1000000
-.long 0x8cfea2ca, 0x1a000000, 0x98360bd4, 0x71000000
-.long 0xa6cf81f5, 0x1d000000, 0xa528de7a, 0x29000000
-.long 0xda268eb7, 0xc5000000, 0x3fa4bfad, 0x89000000
-.long 0x2ce49d3a, 0x6f000000, 0x500d9278, 0xb7000000
-.long 0x6a9bcc5f, 0x62000000, 0x5462467e, 0x0e000000
-.long 0xf6c2138d, 0xaa000000, 0x90e8b8d8, 0x18000000
-.long 0x2e5ef739, 0xbe000000, 0x82f5afc3, 0x1b000000
-.long 0x9fbe805d, 0xfc000000, 0x697c93d0, 0x56000000
-.long 0x6fa92dd5, 0x3e000000, 0xcfb31225, 0x4b000000
-.long 0xc83b99ac, 0xc6000000, 0x10a77d18, 0xd2000000
-.long 0xe86e639c, 0x79000000, 0xdb7bbb3b, 0x20000000
-.long 0xcd097826, 0x9a000000, 0x6ef41859, 0xdb000000
-.long 0xec01b79a, 0xc0000000, 0x83a89a4f, 0xfe000000
-.long 0xe6656e95, 0x78000000, 0xaa7ee6ff, 0xcd000000
-.long 0x2108cfbc, 0x5a000000, 0xefe6e815, 0xf4000000
-.long 0xbad99be7, 0x1f000000, 0x4ace366f, 0xdd000000
-.long 0xead4099f, 0xa8000000, 0x29d67cb0, 0x33000000
-.long 0x31afb2a4, 0x88000000, 0x2a31233f, 0x07000000
-.long 0xc63094a5, 0xc7000000, 0x35c066a2, 0x31000000
-.long 0x7437bc4e, 0xb1000000, 0xfca6ca82, 0x12000000
-.long 0xe0b0d090, 0x10000000, 0x3315d8a7, 0x59000000
-.long 0xf14a9804, 0x27000000, 0x41f7daec, 0x80000000
-.long 0x7f0e50cd, 0xec000000, 0x172ff691, 0x5f000000
-.long 0x768dd64d, 0x60000000, 0x434db0ef, 0x51000000
-.long 0xcc544daa, 0x7f000000, 0xe4df0496, 0xa9000000
-.long 0x9ee3b5d1, 0x19000000, 0x4c1b886a, 0xb5000000
-.long 0xc1b81f2c, 0x4a000000, 0x467f5165, 0x0d000000
-.long 0x9d04ea5e, 0x2d000000, 0x015d358c, 0xe5000000
-.long 0xfa737487, 0x7a000000, 0xfb2e410b, 0x9f000000
-.long 0xb35a1d67, 0x93000000, 0x9252d2db, 0xc9000000
-.long 0xe9335610, 0x9c000000, 0x6d1347d6, 0xef000000
-.long 0x9a8c61d7, 0xa0000000, 0x377a0ca1, 0xe0000000
-.long 0x598e14f8, 0x3b000000, 0xeb893c13, 0x4d000000
-.long 0xceee27a9, 0xae000000, 0xb735c961, 0x2a000000
-.long 0xe1ede51c, 0xf5000000, 0x7a3cb147, 0xb0000000
-.long 0x9c59dfd2, 0xc8000000, 0x553f73f2, 0xeb000000
-.long 0x1879ce14, 0xbb000000, 0x73bf37c7, 0x3c000000
-.long 0x53eacdf7, 0x83000000, 0x5f5baafd, 0x53000000
-.long 0xdf146f3d, 0x99000000, 0x7886db44, 0x61000000
-.long 0xca81f3af, 0x17000000, 0xb93ec468, 0x2b000000
-.long 0x382c3424, 0x04000000, 0xc25f40a3, 0x7e000000
-.long 0x1672c31d, 0xba000000, 0xbc0c25e2, 0x77000000
-.long 0x288b493c, 0xd6000000, 0xff41950d, 0x26000000
-.long 0x397101a8, 0xe1000000, 0x08deb30c, 0x69000000
-.long 0xd89ce4b4, 0x14000000, 0x6490c156, 0x63000000
-.long 0x7b6184cb, 0x55000000, 0xd570b632, 0x21000000
-.long 0x48745c6c, 0x0c000000, 0xd04257b8, 0x7d000000
+ELF(.size _gcry_aes_amd64_decrypt_block,.-_gcry_aes_amd64_decrypt_block;)
 
 #endif /*USE_AES*/
 #endif /*__x86_64*/
index 421c3b4..694369d 100644 (file)
@@ -1,6 +1,6 @@
 /* rijndael-arm.S  -  ARM assembly implementation of AES cipher
  *
- * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
 .syntax unified
 .arm
 
-#ifdef __PIC__
-#  define GET_DATA_POINTER(reg, name, rtmp) \
-               ldr reg, 1f; \
-               ldr rtmp, 2f; \
-               b 3f; \
-       1:      .word _GLOBAL_OFFSET_TABLE_-(3f+8); \
-       2:      .word name(GOT); \
-       3:      add reg, pc, reg; \
-               ldr reg, [reg, rtmp];
-#else
-#  define GET_DATA_POINTER(reg, name, rtmp) ldr reg, =name
-#endif
-
 /* register macros */
 #define CTX    %r0
 #define RTAB   %lr
 #define do_encround(next_r, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_key) \
        ldr rnb, [CTX, #(((next_r) * 16) + 1 * 4)]; \
        \
-       and RT0, RMASK, ra, lsl#3; \
+       and RT0, RMASK, ra, lsl#2; \
        ldr rnc, [CTX, #(((next_r) * 16) + 2 * 4)]; \
-       and RT1, RMASK, ra, lsr#(8 - 3); \
+       and RT1, RMASK, ra, lsr#(8 - 2); \
        ldr rnd, [CTX, #(((next_r) * 16) + 3 * 4)]; \
-       and RT2, RMASK, ra, lsr#(16 - 3); \
+       and RT2, RMASK, ra, lsr#(16 - 2); \
        ldr RT0, [RTAB, RT0]; \
-       and ra,  RMASK, ra, lsr#(24 - 3); \
+       and ra,  RMASK, ra, lsr#(24 - 2); \
        \
        ldr RT1, [RTAB, RT1]; \
        eor rna, rna, RT0; \
        ldr RT2, [RTAB, RT2]; \
-       and RT0, RMASK, rd, lsl#3; \
+       and RT0, RMASK, rd, lsl#2; \
        ldr ra,  [RTAB, ra]; \
        \
        eor rnd, rnd, RT1, ror #24; \
-       and RT1, RMASK, rd, lsr#(8 - 3); \
+       and RT1, RMASK, rd, lsr#(8 - 2); \
        eor rnc, rnc, RT2, ror #16; \
-       and RT2, RMASK, rd, lsr#(16 - 3); \
+       and RT2, RMASK, rd, lsr#(16 - 2); \
        eor rnb, rnb, ra, ror #8; \
        ldr RT0, [RTAB, RT0]; \
-       and rd,  RMASK, rd, lsr#(24 - 3); \
+       and rd,  RMASK, rd, lsr#(24 - 2); \
        \
        ldr RT1, [RTAB, RT1]; \
        eor rnd, rnd, RT0; \
        ldr RT2, [RTAB, RT2]; \
-       and RT0, RMASK, rc, lsl#3; \
+       and RT0, RMASK, rc, lsl#2; \
        ldr rd,  [RTAB, rd]; \
        \
        eor rnc, rnc, RT1, ror #24; \
-       and RT1, RMASK, rc, lsr#(8 - 3); \
+       and RT1, RMASK, rc, lsr#(8 - 2); \
        eor rnb, rnb, RT2, ror #16; \
-       and RT2, RMASK, rc, lsr#(16 - 3); \
+       and RT2, RMASK, rc, lsr#(16 - 2); \
        eor rna, rna, rd, ror #8; \
        ldr RT0, [RTAB, RT0]; \
-       and rc,  RMASK, rc, lsr#(24 - 3); \
+       and rc,  RMASK, rc, lsr#(24 - 2); \
        \
        ldr RT1, [RTAB, RT1]; \
        eor rnc, rnc, RT0; \
        ldr RT2, [RTAB, RT2]; \
-       and RT0, RMASK, rb, lsl#3; \
+       and RT0, RMASK, rb, lsl#2; \
        ldr rc,  [RTAB, rc]; \
        \
        eor rnb, rnb, RT1, ror #24; \
-       and RT1, RMASK, rb, lsr#(8 - 3); \
+       and RT1, RMASK, rb, lsr#(8 - 2); \
        eor rna, rna, RT2, ror #16; \
-       and RT2, RMASK, rb, lsr#(16 - 3); \
+       and RT2, RMASK, rb, lsr#(16 - 2); \
        eor rnd, rnd, rc, ror #8; \
        ldr RT0, [RTAB, RT0]; \
-       and rb,  RMASK, rb, lsr#(24 - 3); \
+       and rb,  RMASK, rb, lsr#(24 - 2); \
        \
        ldr RT1, [RTAB, RT1]; \
        eor rnb, rnb, RT0; \
        eor rnc, rnc, rb, ror #8;
 
 #define do_lastencround(ra, rb, rc, rd, rna, rnb, rnc, rnd) \
-       and RT0, RMASK, ra, lsl#3; \
-       and RT1, RMASK, ra, lsr#(8 - 3); \
-       and RT2, RMASK, ra, lsr#(16 - 3); \
-       ldr rna, [RTAB, RT0]; \
-       and ra,  RMASK, ra, lsr#(24 - 3); \
-       ldr rnd, [RTAB, RT1]; \
-       and RT0, RMASK, rd, lsl#3; \
-       ldr rnc, [RTAB, RT2]; \
+       and RT0, RMASK, ra, lsl#2; \
+       and RT1, RMASK, ra, lsr#(8 - 2); \
+       and RT2, RMASK, ra, lsr#(16 - 2); \
+       ldrb rna, [RTAB, RT0]; \
+       and ra,  RMASK, ra, lsr#(24 - 2); \
+       ldrb rnd, [RTAB, RT1]; \
+       and RT0, RMASK, rd, lsl#2; \
+       ldrb rnc, [RTAB, RT2]; \
        mov rnd, rnd, ror #24; \
-       ldr rnb, [RTAB, ra]; \
-       and RT1, RMASK, rd, lsr#(8 - 3); \
+       ldrb rnb, [RTAB, ra]; \
+       and RT1, RMASK, rd, lsr#(8 - 2); \
        mov rnc, rnc, ror #16; \
-       and RT2, RMASK, rd, lsr#(16 - 3); \
+       and RT2, RMASK, rd, lsr#(16 - 2); \
        mov rnb, rnb, ror #8; \
-       ldr RT0, [RTAB, RT0]; \
-       and rd,  RMASK, rd, lsr#(24 - 3); \
-       ldr RT1, [RTAB, RT1]; \
+       ldrb RT0, [RTAB, RT0]; \
+       and rd,  RMASK, rd, lsr#(24 - 2); \
+       ldrb RT1, [RTAB, RT1]; \
        \
        orr rnd, rnd, RT0; \
-       ldr RT2, [RTAB, RT2]; \
-       and RT0, RMASK, rc, lsl#3; \
-       ldr rd,  [RTAB, rd]; \
+       ldrb RT2, [RTAB, RT2]; \
+       and RT0, RMASK, rc, lsl#2; \
+       ldrb rd,  [RTAB, rd]; \
        orr rnc, rnc, RT1, ror #24; \
-       and RT1, RMASK, rc, lsr#(8 - 3); \
+       and RT1, RMASK, rc, lsr#(8 - 2); \
        orr rnb, rnb, RT2, ror #16; \
-       and RT2, RMASK, rc, lsr#(16 - 3); \
+       and RT2, RMASK, rc, lsr#(16 - 2); \
        orr rna, rna, rd, ror #8; \
-       ldr RT0, [RTAB, RT0]; \
-       and rc,  RMASK, rc, lsr#(24 - 3); \
-       ldr RT1, [RTAB, RT1]; \
+       ldrb RT0, [RTAB, RT0]; \
+       and rc,  RMASK, rc, lsr#(24 - 2); \
+       ldrb RT1, [RTAB, RT1]; \
        \
        orr rnc, rnc, RT0; \
-       ldr RT2, [RTAB, RT2]; \
-       and RT0, RMASK, rb, lsl#3; \
-       ldr rc,  [RTAB, rc]; \
+       ldrb RT2, [RTAB, RT2]; \
+       and RT0, RMASK, rb, lsl#2; \
+       ldrb rc,  [RTAB, rc]; \
        orr rnb, rnb, RT1, ror #24; \
-       and RT1, RMASK, rb, lsr#(8 - 3); \
+       and RT1, RMASK, rb, lsr#(8 - 2); \
        orr rna, rna, RT2, ror #16; \
-       ldr RT0, [RTAB, RT0]; \
-       and RT2, RMASK, rb, lsr#(16 - 3); \
-       ldr RT1, [RTAB, RT1]; \
+       ldrb RT0, [RTAB, RT0]; \
+       and RT2, RMASK, rb, lsr#(16 - 2); \
+       ldrb RT1, [RTAB, RT1]; \
        orr rnd, rnd, rc, ror #8; \
-       ldr RT2, [RTAB, RT2]; \
-       and rb,  RMASK, rb, lsr#(24 - 3); \
-       ldr rb,  [RTAB, rb]; \
+       ldrb RT2, [RTAB, RT2]; \
+       and rb,  RMASK, rb, lsr#(24 - 2); \
+       ldrb rb,  [RTAB, rb]; \
        \
        orr rnb, rnb, RT0; \
        orr rna, rna, RT1, ror #24; \
 
 #define lastencround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd) \
        add CTX, #(((round) + 1) * 16); \
-       add RTAB, #4; \
+       add RTAB, #1; \
        do_lastencround(ra, rb, rc, rd, rna, rnb, rnc, rnd); \
        addroundkey(rna, rnb, rnc, rnd, ra, rb, rc, rd, dummy);
 
@@ -233,6 +220,7 @@ _gcry_aes_arm_encrypt_block:
         *      %r1: dst
         *      %r2: src
         *      %r3: number of rounds.. 10, 12 or 14
+        *      %st+0: encryption table
         */
        push {%r4-%r11, %ip, %lr};
 
@@ -260,14 +248,13 @@ _gcry_aes_arm_encrypt_block:
        rev     RD, RD;
 #endif
 2:
+       ldr     RTAB, [%sp, #40];
        sub     %sp, #16;
 
-       GET_DATA_POINTER(RTAB, .LtableE0, RMASK);
-
        str     %r1, [%sp, #4];         /* dst */
        mov     RMASK, #0xff;
        str     %r3, [%sp, #8];         /* nrounds */
-       mov     RMASK, RMASK, lsl#3;    /* byte mask */
+       mov     RMASK, RMASK, lsl#2;    /* byte mask */
 
        firstencround(0, RA, RB, RC, RD, RNA, RNB, RNC, RND);
        encround(1, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
@@ -314,6 +301,8 @@ _gcry_aes_arm_encrypt_block:
        /* write output block */
        stm     RT0, {RA, RB, RC, RD};
 2:
+
+       mov     r0, #(10 * 4);
        pop {%r4-%r11, %ip, %pc};
 
 .ltorg
@@ -353,55 +342,55 @@ _gcry_aes_arm_encrypt_block:
 #define do_decround(next_r, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_key) \
        ldr rnb, [CTX, #(((next_r) * 16) + 1 * 4)]; \
        \
-       and RT0, RMASK, ra, lsl#3; \
+       and RT0, RMASK, ra, lsl#2; \
        ldr rnc, [CTX, #(((next_r) * 16) + 2 * 4)]; \
-       and RT1, RMASK, ra, lsr#(8 - 3); \
+       and RT1, RMASK, ra, lsr#(8 - 2); \
        ldr rnd, [CTX, #(((next_r) * 16) + 3 * 4)]; \
-       and RT2, RMASK, ra, lsr#(16 - 3); \
+       and RT2, RMASK, ra, lsr#(16 - 2); \
        ldr RT0, [RTAB, RT0]; \
-       and ra,  RMASK, ra, lsr#(24 - 3); \
+       and ra,  RMASK, ra, lsr#(24 - 2); \
        \
        ldr RT1, [RTAB, RT1]; \
        eor rna, rna, RT0; \
        ldr RT2, [RTAB, RT2]; \
-       and RT0, RMASK, rb, lsl#3; \
+       and RT0, RMASK, rb, lsl#2; \
        ldr ra,  [RTAB, ra]; \
        \
        eor rnb, rnb, RT1, ror #24; \
-       and RT1, RMASK, rb, lsr#(8 - 3); \
+       and RT1, RMASK, rb, lsr#(8 - 2); \
        eor rnc, rnc, RT2, ror #16; \
-       and RT2, RMASK, rb, lsr#(16 - 3); \
+       and RT2, RMASK, rb, lsr#(16 - 2); \
        eor rnd, rnd, ra, ror #8; \
        ldr RT0, [RTAB, RT0]; \
-       and rb,  RMASK, rb, lsr#(24 - 3); \
+       and rb,  RMASK, rb, lsr#(24 - 2); \
        \
        ldr RT1, [RTAB, RT1]; \
        eor rnb, rnb, RT0; \
        ldr RT2, [RTAB, RT2]; \
-       and RT0, RMASK, rc, lsl#3; \
+       and RT0, RMASK, rc, lsl#2; \
        ldr rb,  [RTAB, rb]; \
        \
        eor rnc, rnc, RT1, ror #24; \
-       and RT1, RMASK, rc, lsr#(8 - 3); \
+       and RT1, RMASK, rc, lsr#(8 - 2); \
        eor rnd, rnd, RT2, ror #16; \
-       and RT2, RMASK, rc, lsr#(16 - 3); \
+       and RT2, RMASK, rc, lsr#(16 - 2); \
        eor rna, rna, rb, ror #8; \
        ldr RT0, [RTAB, RT0]; \
-       and rc,  RMASK, rc, lsr#(24 - 3); \
+       and rc,  RMASK, rc, lsr#(24 - 2); \
        \
        ldr RT1, [RTAB, RT1]; \
        eor rnc, rnc, RT0; \
        ldr RT2, [RTAB, RT2]; \
-       and RT0, RMASK, rd, lsl#3; \
+       and RT0, RMASK, rd, lsl#2; \
        ldr rc,  [RTAB, rc]; \
        \
        eor rnd, rnd, RT1, ror #24; \
-       and RT1, RMASK, rd, lsr#(8 - 3); \
+       and RT1, RMASK, rd, lsr#(8 - 2); \
        eor rna, rna, RT2, ror #16; \
-       and RT2, RMASK, rd, lsr#(16 - 3); \
+       and RT2, RMASK, rd, lsr#(16 - 2); \
        eor rnb, rnb, rc, ror #8; \
        ldr RT0, [RTAB, RT0]; \
-       and rd,  RMASK, rd, lsr#(24 - 3); \
+       and rd,  RMASK, rd, lsr#(24 - 2); \
        \
        ldr RT1, [RTAB, RT1]; \
        eor rnd, rnd, RT0; \
@@ -414,51 +403,51 @@ _gcry_aes_arm_encrypt_block:
        eor rnc, rnc, rd, ror #8;
 
 #define do_lastdecround(ra, rb, rc, rd, rna, rnb, rnc, rnd) \
-       and RT0, RMASK, ra, lsl#3; \
-       and RT1, RMASK, ra, lsr#(8 - 3); \
-       and RT2, RMASK, ra, lsr#(16 - 3); \
-       ldr rna, [RTAB, RT0]; \
-       and ra,  RMASK, ra, lsr#(24 - 3); \
-       ldr rnb, [RTAB, RT1]; \
-       and RT0, RMASK, rb, lsl#3; \
-       ldr rnc, [RTAB, RT2]; \
+       and RT0, RMASK, ra; \
+       and RT1, RMASK, ra, lsr#8; \
+       and RT2, RMASK, ra, lsr#16; \
+       ldrb rna, [RTAB, RT0]; \
+       mov ra,  ra, lsr#24; \
+       ldrb rnb, [RTAB, RT1]; \
+       and RT0, RMASK, rb; \
+       ldrb rnc, [RTAB, RT2]; \
        mov rnb, rnb, ror #24; \
-       ldr rnd, [RTAB, ra]; \
-       and RT1, RMASK, rb, lsr#(8 - 3); \
+       ldrb rnd, [RTAB, ra]; \
+       and RT1, RMASK, rb, lsr#8; \
        mov rnc, rnc, ror #16; \
-       and RT2, RMASK, rb, lsr#(16 - 3); \
+       and RT2, RMASK, rb, lsr#16; \
        mov rnd, rnd, ror #8; \
-       ldr RT0, [RTAB, RT0]; \
-       and rb,  RMASK, rb, lsr#(24 - 3); \
-       ldr RT1, [RTAB, RT1]; \
+       ldrb RT0, [RTAB, RT0]; \
+       mov rb,  rb, lsr#24; \
+       ldrb RT1, [RTAB, RT1]; \
        \
        orr rnb, rnb, RT0; \
-       ldr RT2, [RTAB, RT2]; \
-       and RT0, RMASK, rc, lsl#3; \
-       ldr rb,  [RTAB, rb]; \
+       ldrb RT2, [RTAB, RT2]; \
+       and RT0, RMASK, rc; \
+       ldrb rb,  [RTAB, rb]; \
        orr rnc, rnc, RT1, ror #24; \
-       and RT1, RMASK, rc, lsr#(8 - 3); \
+       and RT1, RMASK, rc, lsr#8; \
        orr rnd, rnd, RT2, ror #16; \
-       and RT2, RMASK, rc, lsr#(16 - 3); \
+       and RT2, RMASK, rc, lsr#16; \
        orr rna, rna, rb, ror #8; \
-       ldr RT0, [RTAB, RT0]; \
-       and rc,  RMASK, rc, lsr#(24 - 3); \
-       ldr RT1, [RTAB, RT1]; \
+       ldrb RT0, [RTAB, RT0]; \
+       mov rc,  rc, lsr#24; \
+       ldrb RT1, [RTAB, RT1]; \
        \
        orr rnc, rnc, RT0; \
-       ldr RT2, [RTAB, RT2]; \
-       and RT0, RMASK, rd, lsl#3; \
-       ldr rc,  [RTAB, rc]; \
+       ldrb RT2, [RTAB, RT2]; \
+       and RT0, RMASK, rd; \
+       ldrb rc,  [RTAB, rc]; \
        orr rnd, rnd, RT1, ror #24; \
-       and RT1, RMASK, rd, lsr#(8 - 3); \
+       and RT1, RMASK, rd, lsr#8; \
        orr rna, rna, RT2, ror #16; \
-       ldr RT0, [RTAB, RT0]; \
-       and RT2, RMASK, rd, lsr#(16 - 3); \
-       ldr RT1, [RTAB, RT1]; \
+       ldrb RT0, [RTAB, RT0]; \
+       and RT2, RMASK, rd, lsr#16; \
+       ldrb RT1, [RTAB, RT1]; \
        orr rnb, rnb, rc, ror #8; \
-       ldr RT2, [RTAB, RT2]; \
-       and rd,  RMASK, rd, lsr#(24 - 3); \
-       ldr rd,  [RTAB, rd]; \
+       ldrb RT2, [RTAB, RT2]; \
+       mov rd,  rd, lsr#24; \
+       ldrb rd,  [RTAB, rd]; \
        \
        orr rnd, rnd, RT0; \
        orr rna, rna, RT1, ror #24; \
@@ -472,8 +461,11 @@ _gcry_aes_arm_encrypt_block:
 #define decround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_key) \
        do_decround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_key);
 
+#define set_last_round_rmask(_, __) \
+       mov RMASK, #0xff;
+
 #define lastdecround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd) \
-       add RTAB, #4; \
+       add RTAB, #(4 * 256); \
        do_lastdecround(ra, rb, rc, rd, rna, rnb, rnc, rnd); \
        addroundkey(rna, rnb, rnc, rnd, ra, rb, rc, rd, dummy);
 
@@ -487,6 +479,7 @@ _gcry_aes_arm_decrypt_block:
         *      %r1: dst
         *      %r2: src
         *      %r3: number of rounds.. 10, 12 or 14
+        *      %st+0: decryption table
         */
        push {%r4-%r11, %ip, %lr};
 
@@ -514,13 +507,12 @@ _gcry_aes_arm_decrypt_block:
        rev     RD, RD;
 #endif
 2:
+       ldr     RTAB, [%sp, #40];
        sub     %sp, #16;
 
-       GET_DATA_POINTER(RTAB, .LtableD0, RMASK);
-
        mov     RMASK, #0xff;
        str     %r1, [%sp, #4];         /* dst */
-       mov     RMASK, RMASK, lsl#3;    /* byte mask */
+       mov     RMASK, RMASK, lsl#2;    /* byte mask */
 
        cmp     %r3, #12;
        bge     .Ldec_256;
@@ -534,7 +526,7 @@ _gcry_aes_arm_decrypt_block:
        decround(4, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
        decround(3, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
        decround(2, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
-       decround(1, RA, RB, RC, RD, RNA, RNB, RNC, RND, dummy);
+       decround(1, RA, RB, RC, RD, RNA, RNB, RNC, RND, set_last_round_rmask);
        lastdecround(0, RNA, RNB, RNC, RND, RA, RB, RC, RD);
 
        ldr     RT0, [%sp, #4];         /* dst */
@@ -565,6 +557,7 @@ _gcry_aes_arm_decrypt_block:
        /* write output block */
        stm     RT0, {RA, RB, RC, RD};
 2:
+       mov     r0, #(10 * 4);
        pop {%r4-%r11, %ip, %pc};
 
 .ltorg
@@ -588,279 +581,5 @@ _gcry_aes_arm_decrypt_block:
        b .Ldec_tail;
 .size _gcry_aes_arm_encrypt_block,.-_gcry_aes_arm_encrypt_block;
 
-.data
-
-/* Encryption tables */
-.align 5
-.type .LtableE0, %object
-.type .LtableEs0, %object
-.LtableE0:
-.long 0xa56363c6
-.LtableEs0:
-.long             0x00000063, 0x847c7cf8, 0x0000007c
-.long 0x997777ee, 0x00000077, 0x8d7b7bf6, 0x0000007b
-.long 0x0df2f2ff, 0x000000f2, 0xbd6b6bd6, 0x0000006b
-.long 0xb16f6fde, 0x0000006f, 0x54c5c591, 0x000000c5
-.long 0x50303060, 0x00000030, 0x03010102, 0x00000001
-.long 0xa96767ce, 0x00000067, 0x7d2b2b56, 0x0000002b
-.long 0x19fefee7, 0x000000fe, 0x62d7d7b5, 0x000000d7
-.long 0xe6abab4d, 0x000000ab, 0x9a7676ec, 0x00000076
-.long 0x45caca8f, 0x000000ca, 0x9d82821f, 0x00000082
-.long 0x40c9c989, 0x000000c9, 0x877d7dfa, 0x0000007d
-.long 0x15fafaef, 0x000000fa, 0xeb5959b2, 0x00000059
-.long 0xc947478e, 0x00000047, 0x0bf0f0fb, 0x000000f0
-.long 0xecadad41, 0x000000ad, 0x67d4d4b3, 0x000000d4
-.long 0xfda2a25f, 0x000000a2, 0xeaafaf45, 0x000000af
-.long 0xbf9c9c23, 0x0000009c, 0xf7a4a453, 0x000000a4
-.long 0x967272e4, 0x00000072, 0x5bc0c09b, 0x000000c0
-.long 0xc2b7b775, 0x000000b7, 0x1cfdfde1, 0x000000fd
-.long 0xae93933d, 0x00000093, 0x6a26264c, 0x00000026
-.long 0x5a36366c, 0x00000036, 0x413f3f7e, 0x0000003f
-.long 0x02f7f7f5, 0x000000f7, 0x4fcccc83, 0x000000cc
-.long 0x5c343468, 0x00000034, 0xf4a5a551, 0x000000a5
-.long 0x34e5e5d1, 0x000000e5, 0x08f1f1f9, 0x000000f1
-.long 0x937171e2, 0x00000071, 0x73d8d8ab, 0x000000d8
-.long 0x53313162, 0x00000031, 0x3f15152a, 0x00000015
-.long 0x0c040408, 0x00000004, 0x52c7c795, 0x000000c7
-.long 0x65232346, 0x00000023, 0x5ec3c39d, 0x000000c3
-.long 0x28181830, 0x00000018, 0xa1969637, 0x00000096
-.long 0x0f05050a, 0x00000005, 0xb59a9a2f, 0x0000009a
-.long 0x0907070e, 0x00000007, 0x36121224, 0x00000012
-.long 0x9b80801b, 0x00000080, 0x3de2e2df, 0x000000e2
-.long 0x26ebebcd, 0x000000eb, 0x6927274e, 0x00000027
-.long 0xcdb2b27f, 0x000000b2, 0x9f7575ea, 0x00000075
-.long 0x1b090912, 0x00000009, 0x9e83831d, 0x00000083
-.long 0x742c2c58, 0x0000002c, 0x2e1a1a34, 0x0000001a
-.long 0x2d1b1b36, 0x0000001b, 0xb26e6edc, 0x0000006e
-.long 0xee5a5ab4, 0x0000005a, 0xfba0a05b, 0x000000a0
-.long 0xf65252a4, 0x00000052, 0x4d3b3b76, 0x0000003b
-.long 0x61d6d6b7, 0x000000d6, 0xceb3b37d, 0x000000b3
-.long 0x7b292952, 0x00000029, 0x3ee3e3dd, 0x000000e3
-.long 0x712f2f5e, 0x0000002f, 0x97848413, 0x00000084
-.long 0xf55353a6, 0x00000053, 0x68d1d1b9, 0x000000d1
-.long 0x00000000, 0x00000000, 0x2cededc1, 0x000000ed
-.long 0x60202040, 0x00000020, 0x1ffcfce3, 0x000000fc
-.long 0xc8b1b179, 0x000000b1, 0xed5b5bb6, 0x0000005b
-.long 0xbe6a6ad4, 0x0000006a, 0x46cbcb8d, 0x000000cb
-.long 0xd9bebe67, 0x000000be, 0x4b393972, 0x00000039
-.long 0xde4a4a94, 0x0000004a, 0xd44c4c98, 0x0000004c
-.long 0xe85858b0, 0x00000058, 0x4acfcf85, 0x000000cf
-.long 0x6bd0d0bb, 0x000000d0, 0x2aefefc5, 0x000000ef
-.long 0xe5aaaa4f, 0x000000aa, 0x16fbfbed, 0x000000fb
-.long 0xc5434386, 0x00000043, 0xd74d4d9a, 0x0000004d
-.long 0x55333366, 0x00000033, 0x94858511, 0x00000085
-.long 0xcf45458a, 0x00000045, 0x10f9f9e9, 0x000000f9
-.long 0x06020204, 0x00000002, 0x817f7ffe, 0x0000007f
-.long 0xf05050a0, 0x00000050, 0x443c3c78, 0x0000003c
-.long 0xba9f9f25, 0x0000009f, 0xe3a8a84b, 0x000000a8
-.long 0xf35151a2, 0x00000051, 0xfea3a35d, 0x000000a3
-.long 0xc0404080, 0x00000040, 0x8a8f8f05, 0x0000008f
-.long 0xad92923f, 0x00000092, 0xbc9d9d21, 0x0000009d
-.long 0x48383870, 0x00000038, 0x04f5f5f1, 0x000000f5
-.long 0xdfbcbc63, 0x000000bc, 0xc1b6b677, 0x000000b6
-.long 0x75dadaaf, 0x000000da, 0x63212142, 0x00000021
-.long 0x30101020, 0x00000010, 0x1affffe5, 0x000000ff
-.long 0x0ef3f3fd, 0x000000f3, 0x6dd2d2bf, 0x000000d2
-.long 0x4ccdcd81, 0x000000cd, 0x140c0c18, 0x0000000c
-.long 0x35131326, 0x00000013, 0x2fececc3, 0x000000ec
-.long 0xe15f5fbe, 0x0000005f, 0xa2979735, 0x00000097
-.long 0xcc444488, 0x00000044, 0x3917172e, 0x00000017
-.long 0x57c4c493, 0x000000c4, 0xf2a7a755, 0x000000a7
-.long 0x827e7efc, 0x0000007e, 0x473d3d7a, 0x0000003d
-.long 0xac6464c8, 0x00000064, 0xe75d5dba, 0x0000005d
-.long 0x2b191932, 0x00000019, 0x957373e6, 0x00000073
-.long 0xa06060c0, 0x00000060, 0x98818119, 0x00000081
-.long 0xd14f4f9e, 0x0000004f, 0x7fdcdca3, 0x000000dc
-.long 0x66222244, 0x00000022, 0x7e2a2a54, 0x0000002a
-.long 0xab90903b, 0x00000090, 0x8388880b, 0x00000088
-.long 0xca46468c, 0x00000046, 0x29eeeec7, 0x000000ee
-.long 0xd3b8b86b, 0x000000b8, 0x3c141428, 0x00000014
-.long 0x79dedea7, 0x000000de, 0xe25e5ebc, 0x0000005e
-.long 0x1d0b0b16, 0x0000000b, 0x76dbdbad, 0x000000db
-.long 0x3be0e0db, 0x000000e0, 0x56323264, 0x00000032
-.long 0x4e3a3a74, 0x0000003a, 0x1e0a0a14, 0x0000000a
-.long 0xdb494992, 0x00000049, 0x0a06060c, 0x00000006
-.long 0x6c242448, 0x00000024, 0xe45c5cb8, 0x0000005c
-.long 0x5dc2c29f, 0x000000c2, 0x6ed3d3bd, 0x000000d3
-.long 0xefacac43, 0x000000ac, 0xa66262c4, 0x00000062
-.long 0xa8919139, 0x00000091, 0xa4959531, 0x00000095
-.long 0x37e4e4d3, 0x000000e4, 0x8b7979f2, 0x00000079
-.long 0x32e7e7d5, 0x000000e7, 0x43c8c88b, 0x000000c8
-.long 0x5937376e, 0x00000037, 0xb76d6dda, 0x0000006d
-.long 0x8c8d8d01, 0x0000008d, 0x64d5d5b1, 0x000000d5
-.long 0xd24e4e9c, 0x0000004e, 0xe0a9a949, 0x000000a9
-.long 0xb46c6cd8, 0x0000006c, 0xfa5656ac, 0x00000056
-.long 0x07f4f4f3, 0x000000f4, 0x25eaeacf, 0x000000ea
-.long 0xaf6565ca, 0x00000065, 0x8e7a7af4, 0x0000007a
-.long 0xe9aeae47, 0x000000ae, 0x18080810, 0x00000008
-.long 0xd5baba6f, 0x000000ba, 0x887878f0, 0x00000078
-.long 0x6f25254a, 0x00000025, 0x722e2e5c, 0x0000002e
-.long 0x241c1c38, 0x0000001c, 0xf1a6a657, 0x000000a6
-.long 0xc7b4b473, 0x000000b4, 0x51c6c697, 0x000000c6
-.long 0x23e8e8cb, 0x000000e8, 0x7cdddda1, 0x000000dd
-.long 0x9c7474e8, 0x00000074, 0x211f1f3e, 0x0000001f
-.long 0xdd4b4b96, 0x0000004b, 0xdcbdbd61, 0x000000bd
-.long 0x868b8b0d, 0x0000008b, 0x858a8a0f, 0x0000008a
-.long 0x907070e0, 0x00000070, 0x423e3e7c, 0x0000003e
-.long 0xc4b5b571, 0x000000b5, 0xaa6666cc, 0x00000066
-.long 0xd8484890, 0x00000048, 0x05030306, 0x00000003
-.long 0x01f6f6f7, 0x000000f6, 0x120e0e1c, 0x0000000e
-.long 0xa36161c2, 0x00000061, 0x5f35356a, 0x00000035
-.long 0xf95757ae, 0x00000057, 0xd0b9b969, 0x000000b9
-.long 0x91868617, 0x00000086, 0x58c1c199, 0x000000c1
-.long 0x271d1d3a, 0x0000001d, 0xb99e9e27, 0x0000009e
-.long 0x38e1e1d9, 0x000000e1, 0x13f8f8eb, 0x000000f8
-.long 0xb398982b, 0x00000098, 0x33111122, 0x00000011
-.long 0xbb6969d2, 0x00000069, 0x70d9d9a9, 0x000000d9
-.long 0x898e8e07, 0x0000008e, 0xa7949433, 0x00000094
-.long 0xb69b9b2d, 0x0000009b, 0x221e1e3c, 0x0000001e
-.long 0x92878715, 0x00000087, 0x20e9e9c9, 0x000000e9
-.long 0x49cece87, 0x000000ce, 0xff5555aa, 0x00000055
-.long 0x78282850, 0x00000028, 0x7adfdfa5, 0x000000df
-.long 0x8f8c8c03, 0x0000008c, 0xf8a1a159, 0x000000a1
-.long 0x80898909, 0x00000089, 0x170d0d1a, 0x0000000d
-.long 0xdabfbf65, 0x000000bf, 0x31e6e6d7, 0x000000e6
-.long 0xc6424284, 0x00000042, 0xb86868d0, 0x00000068
-.long 0xc3414182, 0x00000041, 0xb0999929, 0x00000099
-.long 0x772d2d5a, 0x0000002d, 0x110f0f1e, 0x0000000f
-.long 0xcbb0b07b, 0x000000b0, 0xfc5454a8, 0x00000054
-.long 0xd6bbbb6d, 0x000000bb, 0x3a16162c, 0x00000016
-
-/* Decryption tables */
-.align 5
-.type .LtableD0, %object
-.type .LtableDs0, %object
-.LtableD0:
-.long 0x50a7f451
-.LtableDs0:
-.long             0x00000052, 0x5365417e, 0x00000009
-.long 0xc3a4171a, 0x0000006a, 0x965e273a, 0x000000d5
-.long 0xcb6bab3b, 0x00000030, 0xf1459d1f, 0x00000036
-.long 0xab58faac, 0x000000a5, 0x9303e34b, 0x00000038
-.long 0x55fa3020, 0x000000bf, 0xf66d76ad, 0x00000040
-.long 0x9176cc88, 0x000000a3, 0x254c02f5, 0x0000009e
-.long 0xfcd7e54f, 0x00000081, 0xd7cb2ac5, 0x000000f3
-.long 0x80443526, 0x000000d7, 0x8fa362b5, 0x000000fb
-.long 0x495ab1de, 0x0000007c, 0x671bba25, 0x000000e3
-.long 0x980eea45, 0x00000039, 0xe1c0fe5d, 0x00000082
-.long 0x02752fc3, 0x0000009b, 0x12f04c81, 0x0000002f
-.long 0xa397468d, 0x000000ff, 0xc6f9d36b, 0x00000087
-.long 0xe75f8f03, 0x00000034, 0x959c9215, 0x0000008e
-.long 0xeb7a6dbf, 0x00000043, 0xda595295, 0x00000044
-.long 0x2d83bed4, 0x000000c4, 0xd3217458, 0x000000de
-.long 0x2969e049, 0x000000e9, 0x44c8c98e, 0x000000cb
-.long 0x6a89c275, 0x00000054, 0x78798ef4, 0x0000007b
-.long 0x6b3e5899, 0x00000094, 0xdd71b927, 0x00000032
-.long 0xb64fe1be, 0x000000a6, 0x17ad88f0, 0x000000c2
-.long 0x66ac20c9, 0x00000023, 0xb43ace7d, 0x0000003d
-.long 0x184adf63, 0x000000ee, 0x82311ae5, 0x0000004c
-.long 0x60335197, 0x00000095, 0x457f5362, 0x0000000b
-.long 0xe07764b1, 0x00000042, 0x84ae6bbb, 0x000000fa
-.long 0x1ca081fe, 0x000000c3, 0x942b08f9, 0x0000004e
-.long 0x58684870, 0x00000008, 0x19fd458f, 0x0000002e
-.long 0x876cde94, 0x000000a1, 0xb7f87b52, 0x00000066
-.long 0x23d373ab, 0x00000028, 0xe2024b72, 0x000000d9
-.long 0x578f1fe3, 0x00000024, 0x2aab5566, 0x000000b2
-.long 0x0728ebb2, 0x00000076, 0x03c2b52f, 0x0000005b
-.long 0x9a7bc586, 0x000000a2, 0xa50837d3, 0x00000049
-.long 0xf2872830, 0x0000006d, 0xb2a5bf23, 0x0000008b
-.long 0xba6a0302, 0x000000d1, 0x5c8216ed, 0x00000025
-.long 0x2b1ccf8a, 0x00000072, 0x92b479a7, 0x000000f8
-.long 0xf0f207f3, 0x000000f6, 0xa1e2694e, 0x00000064
-.long 0xcdf4da65, 0x00000086, 0xd5be0506, 0x00000068
-.long 0x1f6234d1, 0x00000098, 0x8afea6c4, 0x00000016
-.long 0x9d532e34, 0x000000d4, 0xa055f3a2, 0x000000a4
-.long 0x32e18a05, 0x0000005c, 0x75ebf6a4, 0x000000cc
-.long 0x39ec830b, 0x0000005d, 0xaaef6040, 0x00000065
-.long 0x069f715e, 0x000000b6, 0x51106ebd, 0x00000092
-.long 0xf98a213e, 0x0000006c, 0x3d06dd96, 0x00000070
-.long 0xae053edd, 0x00000048, 0x46bde64d, 0x00000050
-.long 0xb58d5491, 0x000000fd, 0x055dc471, 0x000000ed
-.long 0x6fd40604, 0x000000b9, 0xff155060, 0x000000da
-.long 0x24fb9819, 0x0000005e, 0x97e9bdd6, 0x00000015
-.long 0xcc434089, 0x00000046, 0x779ed967, 0x00000057
-.long 0xbd42e8b0, 0x000000a7, 0x888b8907, 0x0000008d
-.long 0x385b19e7, 0x0000009d, 0xdbeec879, 0x00000084
-.long 0x470a7ca1, 0x00000090, 0xe90f427c, 0x000000d8
-.long 0xc91e84f8, 0x000000ab, 0x00000000, 0x00000000
-.long 0x83868009, 0x0000008c, 0x48ed2b32, 0x000000bc
-.long 0xac70111e, 0x000000d3, 0x4e725a6c, 0x0000000a
-.long 0xfbff0efd, 0x000000f7, 0x5638850f, 0x000000e4
-.long 0x1ed5ae3d, 0x00000058, 0x27392d36, 0x00000005
-.long 0x64d90f0a, 0x000000b8, 0x21a65c68, 0x000000b3
-.long 0xd1545b9b, 0x00000045, 0x3a2e3624, 0x00000006
-.long 0xb1670a0c, 0x000000d0, 0x0fe75793, 0x0000002c
-.long 0xd296eeb4, 0x0000001e, 0x9e919b1b, 0x0000008f
-.long 0x4fc5c080, 0x000000ca, 0xa220dc61, 0x0000003f
-.long 0x694b775a, 0x0000000f, 0x161a121c, 0x00000002
-.long 0x0aba93e2, 0x000000c1, 0xe52aa0c0, 0x000000af
-.long 0x43e0223c, 0x000000bd, 0x1d171b12, 0x00000003
-.long 0x0b0d090e, 0x00000001, 0xadc78bf2, 0x00000013
-.long 0xb9a8b62d, 0x0000008a, 0xc8a91e14, 0x0000006b
-.long 0x8519f157, 0x0000003a, 0x4c0775af, 0x00000091
-.long 0xbbdd99ee, 0x00000011, 0xfd607fa3, 0x00000041
-.long 0x9f2601f7, 0x0000004f, 0xbcf5725c, 0x00000067
-.long 0xc53b6644, 0x000000dc, 0x347efb5b, 0x000000ea
-.long 0x7629438b, 0x00000097, 0xdcc623cb, 0x000000f2
-.long 0x68fcedb6, 0x000000cf, 0x63f1e4b8, 0x000000ce
-.long 0xcadc31d7, 0x000000f0, 0x10856342, 0x000000b4
-.long 0x40229713, 0x000000e6, 0x2011c684, 0x00000073
-.long 0x7d244a85, 0x00000096, 0xf83dbbd2, 0x000000ac
-.long 0x1132f9ae, 0x00000074, 0x6da129c7, 0x00000022
-.long 0x4b2f9e1d, 0x000000e7, 0xf330b2dc, 0x000000ad
-.long 0xec52860d, 0x00000035, 0xd0e3c177, 0x00000085
-.long 0x6c16b32b, 0x000000e2, 0x99b970a9, 0x000000f9
-.long 0xfa489411, 0x00000037, 0x2264e947, 0x000000e8
-.long 0xc48cfca8, 0x0000001c, 0x1a3ff0a0, 0x00000075
-.long 0xd82c7d56, 0x000000df, 0xef903322, 0x0000006e
-.long 0xc74e4987, 0x00000047, 0xc1d138d9, 0x000000f1
-.long 0xfea2ca8c, 0x0000001a, 0x360bd498, 0x00000071
-.long 0xcf81f5a6, 0x0000001d, 0x28de7aa5, 0x00000029
-.long 0x268eb7da, 0x000000c5, 0xa4bfad3f, 0x00000089
-.long 0xe49d3a2c, 0x0000006f, 0x0d927850, 0x000000b7
-.long 0x9bcc5f6a, 0x00000062, 0x62467e54, 0x0000000e
-.long 0xc2138df6, 0x000000aa, 0xe8b8d890, 0x00000018
-.long 0x5ef7392e, 0x000000be, 0xf5afc382, 0x0000001b
-.long 0xbe805d9f, 0x000000fc, 0x7c93d069, 0x00000056
-.long 0xa92dd56f, 0x0000003e, 0xb31225cf, 0x0000004b
-.long 0x3b99acc8, 0x000000c6, 0xa77d1810, 0x000000d2
-.long 0x6e639ce8, 0x00000079, 0x7bbb3bdb, 0x00000020
-.long 0x097826cd, 0x0000009a, 0xf418596e, 0x000000db
-.long 0x01b79aec, 0x000000c0, 0xa89a4f83, 0x000000fe
-.long 0x656e95e6, 0x00000078, 0x7ee6ffaa, 0x000000cd
-.long 0x08cfbc21, 0x0000005a, 0xe6e815ef, 0x000000f4
-.long 0xd99be7ba, 0x0000001f, 0xce366f4a, 0x000000dd
-.long 0xd4099fea, 0x000000a8, 0xd67cb029, 0x00000033
-.long 0xafb2a431, 0x00000088, 0x31233f2a, 0x00000007
-.long 0x3094a5c6, 0x000000c7, 0xc066a235, 0x00000031
-.long 0x37bc4e74, 0x000000b1, 0xa6ca82fc, 0x00000012
-.long 0xb0d090e0, 0x00000010, 0x15d8a733, 0x00000059
-.long 0x4a9804f1, 0x00000027, 0xf7daec41, 0x00000080
-.long 0x0e50cd7f, 0x000000ec, 0x2ff69117, 0x0000005f
-.long 0x8dd64d76, 0x00000060, 0x4db0ef43, 0x00000051
-.long 0x544daacc, 0x0000007f, 0xdf0496e4, 0x000000a9
-.long 0xe3b5d19e, 0x00000019, 0x1b886a4c, 0x000000b5
-.long 0xb81f2cc1, 0x0000004a, 0x7f516546, 0x0000000d
-.long 0x04ea5e9d, 0x0000002d, 0x5d358c01, 0x000000e5
-.long 0x737487fa, 0x0000007a, 0x2e410bfb, 0x0000009f
-.long 0x5a1d67b3, 0x00000093, 0x52d2db92, 0x000000c9
-.long 0x335610e9, 0x0000009c, 0x1347d66d, 0x000000ef
-.long 0x8c61d79a, 0x000000a0, 0x7a0ca137, 0x000000e0
-.long 0x8e14f859, 0x0000003b, 0x893c13eb, 0x0000004d
-.long 0xee27a9ce, 0x000000ae, 0x35c961b7, 0x0000002a
-.long 0xede51ce1, 0x000000f5, 0x3cb1477a, 0x000000b0
-.long 0x59dfd29c, 0x000000c8, 0x3f73f255, 0x000000eb
-.long 0x79ce1418, 0x000000bb, 0xbf37c773, 0x0000003c
-.long 0xeacdf753, 0x00000083, 0x5baafd5f, 0x00000053
-.long 0x146f3ddf, 0x00000099, 0x86db4478, 0x00000061
-.long 0x81f3afca, 0x00000017, 0x3ec468b9, 0x0000002b
-.long 0x2c342438, 0x00000004, 0x5f40a3c2, 0x0000007e
-.long 0x72c31d16, 0x000000ba, 0x0c25e2bc, 0x00000077
-.long 0x8b493c28, 0x000000d6, 0x41950dff, 0x00000026
-.long 0x7101a839, 0x000000e1, 0xdeb30c08, 0x00000069
-.long 0x9ce4b4d8, 0x00000014, 0x90c15664, 0x00000063
-.long 0x6184cb7b, 0x00000055, 0x70b632d5, 0x00000021
-.long 0x745c6c48, 0x0000000c, 0x4257b8d0, 0x0000007d
-
 #endif /*HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS*/
 #endif /*__ARMEL__ */
diff --git a/cipher/rijndael-internal.h b/cipher/rijndael-internal.h
new file mode 100644 (file)
index 0000000..6641728
--- /dev/null
@@ -0,0 +1,143 @@
+/* Rijndael (AES) for GnuPG
+ * Copyright (C) 2000, 2001, 2002, 2003, 2007,
+ *               2008, 2011, 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef G10_RIJNDAEL_INTERNAL_H
+#define G10_RIJNDAEL_INTERNAL_H
+
+#include "types.h"  /* for byte and u32 typedefs */
+
+
+#define MAXKC                   (256/32)
+#define MAXROUNDS               14
+#define BLOCKSIZE               (128/8)
+
+
+/* Helper macro to force alignment to 16 bytes.  */
+#ifdef HAVE_GCC_ATTRIBUTE_ALIGNED
+# define ATTR_ALIGNED_16  __attribute__ ((aligned (16)))
+#else
+# define ATTR_ALIGNED_16
+#endif
+
+
+/* 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) || \
+    defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define USE_AMD64_ASM 1
+#endif
+
+/* USE_SSSE3 indicates whether to use SSSE3 code. */
+#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_SSSE3) && \
+    (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+#  define USE_SSSE3 1
+#endif
+
+/* USE_ARM_ASM indicates whether to use ARM assembly code. */
+#undef USE_ARM_ASM
+#if defined(__ARMEL__)
+# ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS
+#  define USE_ARM_ASM 1
+# endif
+#endif
+
+/* USE_PADLOCK indicates whether to compile the padlock specific
+   code.  */
+#undef USE_PADLOCK
+#ifdef ENABLE_PADLOCK_SUPPORT
+# ifdef HAVE_GCC_ATTRIBUTE_ALIGNED
+#  if (defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__)
+#   define USE_PADLOCK 1
+#  endif
+# endif
+#endif /*ENABLE_PADLOCK_SUPPORT*/
+
+/* USE_AESNI inidicates whether to compile with Intel AES-NI code.  We
+   need the vector-size attribute which seems to be available since
+   gcc 3.  However, to be on the safe side we require at least gcc 4.  */
+#undef USE_AESNI
+#ifdef ENABLE_AESNI_SUPPORT
+# if ((defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__))
+#  if __GNUC__ >= 4
+#   define USE_AESNI 1
+#  endif
+# endif
+#endif /* ENABLE_AESNI_SUPPORT */
+
+struct RIJNDAEL_context_s;
+
+typedef unsigned int (*rijndael_cryptfn_t)(const struct RIJNDAEL_context_s *ctx,
+                                           unsigned char *bx,
+                                           const unsigned char *ax);
+typedef void (*rijndael_prefetchfn_t)(void);
+
+/* Our context object.  */
+typedef struct RIJNDAEL_context_s
+{
+  /* The first fields are the keyschedule arrays.  This is so that
+     they are aligned on a 16 byte boundary if using gcc.  This
+     alignment is required for the AES-NI code and a good idea in any
+     case.  The alignment is guaranteed due to the way cipher.c
+     allocates the space for the context.  The PROPERLY_ALIGNED_TYPE
+     hack is used to force a minimal alignment if not using gcc of if
+     the alignment requirement is higher that 16 bytes.  */
+  union
+  {
+    PROPERLY_ALIGNED_TYPE dummy;
+    byte keyschedule[MAXROUNDS+1][4][4];
+    u32 keyschedule32[MAXROUNDS+1][4];
+#ifdef USE_PADLOCK
+    /* The key as passed to the padlock engine.  It is only used if
+       the padlock engine is used (USE_PADLOCK, below).  */
+    unsigned char padlock_key[16] __attribute__ ((aligned (16)));
+#endif /*USE_PADLOCK*/
+  } u1;
+  union
+  {
+    PROPERLY_ALIGNED_TYPE dummy;
+    byte keyschedule[MAXROUNDS+1][4][4];
+    u32 keyschedule32[MAXROUNDS+1][4];
+  } u2;
+  int rounds;                         /* Key-length-dependent number of rounds.  */
+  unsigned int decryption_prepared:1; /* The decryption key schedule is available.  */
+#ifdef USE_PADLOCK
+  unsigned int use_padlock:1;         /* Padlock shall be used.  */
+#endif /*USE_PADLOCK*/
+#ifdef USE_AESNI
+  unsigned int use_aesni:1;           /* AES-NI shall be used.  */
+#endif /*USE_AESNI*/
+#ifdef USE_SSSE3
+  unsigned int use_ssse3:1;           /* SSSE3 shall be used.  */
+#endif /*USE_SSSE3*/
+  rijndael_cryptfn_t encrypt_fn;
+  rijndael_cryptfn_t decrypt_fn;
+  rijndael_prefetchfn_t prefetch_enc_fn;
+  rijndael_prefetchfn_t prefetch_dec_fn;
+} RIJNDAEL_context ATTR_ALIGNED_16;
+
+/* Macros defining alias for the keyschedules.  */
+#define keyschenc   u1.keyschedule
+#define keyschenc32 u1.keyschedule32
+#define keyschdec   u2.keyschedule
+#define keyschdec32 u2.keyschedule32
+#define padlockkey  u1.padlock_key
+
+#endif /* G10_RIJNDAEL_INTERNAL_H */
diff --git a/cipher/rijndael-padlock.c b/cipher/rijndael-padlock.c
new file mode 100644 (file)
index 0000000..476772a
--- /dev/null
@@ -0,0 +1,102 @@
+/* Padlock accelerated AES for Libgcrypt
+ * Copyright (C) 2000, 2001, 2002, 2003, 2007,
+ *               2008, 2011, 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* for memcmp() */
+
+#include "types.h"  /* for byte and u32 typedefs */
+#include "g10lib.h"
+#include "cipher.h"
+#include "bufhelp.h"
+#include "cipher-selftest.h"
+#include "rijndael-internal.h"
+
+#ifdef USE_PADLOCK
+
+/* Encrypt or decrypt one block using the padlock engine.  A and B may
+   be the same. */
+static unsigned int
+do_padlock (const RIJNDAEL_context *ctx, unsigned char *bx,
+            const unsigned char *ax, int decrypt_flag)
+{
+  /* BX and AX are not necessary correctly aligned.  Thus we need to
+     copy them here. */
+  unsigned char a[16] __attribute__ ((aligned (16)));
+  unsigned char b[16] __attribute__ ((aligned (16)));
+  unsigned int cword[4] __attribute__ ((aligned (16)));
+  int blocks;
+
+  /* The control word fields are:
+      127:12   11:10 9     8     7     6     5     4     3:0
+      RESERVED KSIZE CRYPT INTER KEYGN CIPHR ALIGN DGEST ROUND  */
+  cword[0] = (ctx->rounds & 15);  /* (The mask is just a safeguard.)  */
+  cword[1] = 0;
+  cword[2] = 0;
+  cword[3] = 0;
+  if (decrypt_flag)
+    cword[0] |= 0x00000200;
+
+  memcpy (a, ax, 16);
+
+  blocks = 1; /* Init counter for just one block.  */
+#ifdef __x86_64__
+  asm volatile
+    ("pushfq\n\t"          /* Force key reload.  */
+     "popfq\n\t"
+     ".byte 0xf3, 0x0f, 0xa7, 0xc8\n\t" /* REP XCRYPT ECB. */
+     : /* No output */
+     : "S" (a), "D" (b), "d" (cword), "b" (ctx->padlockkey), "c" (blocks)
+     : "cc", "memory"
+     );
+#else
+  asm volatile
+    ("pushfl\n\t"          /* Force key reload.  */
+     "popfl\n\t"
+     "xchg %3, %%ebx\n\t"  /* Load key.  */
+     ".byte 0xf3, 0x0f, 0xa7, 0xc8\n\t" /* REP XCRYPT ECB. */
+     "xchg %3, %%ebx\n"    /* Restore GOT register.  */
+     : /* No output */
+     : "S" (a), "D" (b), "d" (cword), "r" (ctx->padlockkey), "c" (blocks)
+     : "cc", "memory"
+     );
+#endif
+
+  memcpy (bx, b, 16);
+
+  return (48 + 15 /* possible padding for alignment */);
+}
+
+unsigned int
+_gcry_aes_padlock_encrypt (const RIJNDAEL_context *ctx,
+                           unsigned char *bx, const unsigned char *ax)
+{
+  return do_padlock(ctx, bx, ax, 0);
+}
+
+unsigned int
+_gcry_aes_padlock_decrypt (const RIJNDAEL_context *ctx,
+                           unsigned char *bx, const unsigned char *ax)
+{
+  return do_padlock(ctx, bx, ax, 1);
+}
+
+#endif /* USE_PADLOCK */
diff --git a/cipher/rijndael-ssse3-amd64.c b/cipher/rijndael-ssse3-amd64.c
new file mode 100644 (file)
index 0000000..937d868
--- /dev/null
@@ -0,0 +1,1589 @@
+/* SSSE3 vector permutation AES for Libgcrypt
+ * Copyright (C) 2014-2015 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * The code is based on the public domain library libvpaes version 0.5
+ * available at http://crypto.stanford.edu/vpaes/ and which carries
+ * this notice:
+ *
+ *     libvpaes: constant-time SSSE3 AES encryption and decryption.
+ *     version 0.5
+ *
+ *     By Mike Hamburg, Stanford University, 2009.  Public domain.
+ *     I wrote essentially all of this code.  I did not write the test
+ *     vectors; they are the NIST known answer tests.  I hereby release all
+ *     the code and documentation here that I wrote into the public domain.
+ *
+ *     This is an implementation of AES following my paper,
+ *       "Accelerating AES with Vector Permute Instructions"
+ *       CHES 2009; http://shiftleft.org/papers/vector_aes/
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* for memcmp() */
+
+#include "types.h"  /* for byte and u32 typedefs */
+#include "g10lib.h"
+#include "cipher.h"
+#include "bufhelp.h"
+#include "cipher-selftest.h"
+#include "rijndael-internal.h"
+#include "./cipher-internal.h"
+
+
+#ifdef USE_SSSE3
+
+
+#if _GCRY_GCC_VERSION >= 40400 /* 4.4 */
+/* Prevent compiler from issuing SSE instructions between asm blocks. */
+#  pragma GCC target("no-sse")
+#endif
+
+
+/* Two macros to be called prior and after the use of SSSE3
+  instructions.  There should be no external function calls between
+  the use of these macros.  There purpose is to make sure that the
+  SSE registers are cleared and won't reveal any information about
+  the key or the data.  */
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+# define SSSE3_STATE_SIZE (16 * 10)
+/* XMM6-XMM15 are callee-saved registers on WIN64. */
+# define vpaes_ssse3_prepare() \
+    asm volatile ("movdqu %%xmm6,  0*16(%0)\n\t" \
+                  "movdqu %%xmm7,  1*16(%0)\n\t" \
+                  "movdqu %%xmm8,  2*16(%0)\n\t" \
+                  "movdqu %%xmm9,  3*16(%0)\n\t" \
+                  "movdqu %%xmm10, 4*16(%0)\n\t" \
+                  "movdqu %%xmm11, 5*16(%0)\n\t" \
+                  "movdqu %%xmm12, 6*16(%0)\n\t" \
+                  "movdqu %%xmm13, 7*16(%0)\n\t" \
+                  "movdqu %%xmm14, 8*16(%0)\n\t" \
+                  "movdqu %%xmm15, 9*16(%0)\n\t" \
+                  : \
+                  : "r" (ssse3_state) \
+                  : "memory" )
+# define vpaes_ssse3_cleanup() \
+    asm volatile ("pxor        %%xmm0,  %%xmm0 \n\t" \
+                  "pxor        %%xmm1,  %%xmm1 \n\t" \
+                  "pxor        %%xmm2,  %%xmm2 \n\t" \
+                  "pxor        %%xmm3,  %%xmm3 \n\t" \
+                  "pxor        %%xmm4,  %%xmm4 \n\t" \
+                  "pxor        %%xmm5,  %%xmm5 \n\t" \
+                  "movdqu 0*16(%0), %%xmm6 \n\t" \
+                  "movdqu 1*16(%0), %%xmm7 \n\t" \
+                  "movdqu 2*16(%0), %%xmm8 \n\t" \
+                  "movdqu 3*16(%0), %%xmm9 \n\t" \
+                  "movdqu 4*16(%0), %%xmm10 \n\t" \
+                  "movdqu 5*16(%0), %%xmm11 \n\t" \
+                  "movdqu 6*16(%0), %%xmm12 \n\t" \
+                  "movdqu 7*16(%0), %%xmm13 \n\t" \
+                  "movdqu 8*16(%0), %%xmm14 \n\t" \
+                  "movdqu 9*16(%0), %%xmm15 \n\t" \
+                  : \
+                  : "r" (ssse3_state) \
+                  : "memory" )
+#else
+# define SSSE3_STATE_SIZE 1
+# define vpaes_ssse3_prepare() (void)ssse3_state
+# define vpaes_ssse3_cleanup() \
+    asm volatile ("pxor        %%xmm0,  %%xmm0 \n\t" \
+                  "pxor        %%xmm1,  %%xmm1 \n\t" \
+                  "pxor        %%xmm2,  %%xmm2 \n\t" \
+                  "pxor        %%xmm3,  %%xmm3 \n\t" \
+                  "pxor        %%xmm4,  %%xmm4 \n\t" \
+                  "pxor        %%xmm5,  %%xmm5 \n\t" \
+                  "pxor        %%xmm6,  %%xmm6 \n\t" \
+                  "pxor        %%xmm7,  %%xmm7 \n\t" \
+                  "pxor        %%xmm8,  %%xmm8 \n\t" \
+                  ::: "memory" )
+#endif
+
+#define vpaes_ssse3_prepare_enc(const_ptr) \
+    vpaes_ssse3_prepare(); \
+    asm volatile ("lea .Laes_consts(%%rip), %q0 \n\t" \
+                  "movdqa                (%q0), %%xmm9  # 0F \n\t" \
+                  "movdqa      .Lk_inv   (%q0), %%xmm10 # inv \n\t" \
+                  "movdqa      .Lk_inv+16(%q0), %%xmm11 # inva \n\t" \
+                  "movdqa      .Lk_sb1   (%q0), %%xmm13 # sb1u \n\t" \
+                  "movdqa      .Lk_sb1+16(%q0), %%xmm12 # sb1t \n\t" \
+                  "movdqa      .Lk_sb2   (%q0), %%xmm15 # sb2u \n\t" \
+                  "movdqa      .Lk_sb2+16(%q0), %%xmm14 # sb2t \n\t" \
+                  : "=c" (const_ptr) \
+                  : \
+                  : "memory" )
+
+#define vpaes_ssse3_prepare_dec(const_ptr) \
+    vpaes_ssse3_prepare(); \
+    asm volatile ("lea .Laes_consts(%%rip), %q0 \n\t" \
+                  "movdqa                (%q0), %%xmm9  # 0F \n\t" \
+                  "movdqa      .Lk_inv   (%q0), %%xmm10 # inv \n\t" \
+                  "movdqa      .Lk_inv+16(%q0), %%xmm11 # inva \n\t" \
+                  "movdqa      .Lk_dsb9   (%q0), %%xmm13 # sb9u \n\t" \
+                  "movdqa      .Lk_dsb9+16(%q0), %%xmm12 # sb9t \n\t" \
+                  "movdqa      .Lk_dsbd   (%q0), %%xmm15 # sbdu \n\t" \
+                  "movdqa      .Lk_dsbb   (%q0), %%xmm14 # sbbu \n\t" \
+                  "movdqa      .Lk_dsbe   (%q0), %%xmm8 # sbeu \n\t" \
+                  : "=c" (const_ptr) \
+                  : \
+                  : "memory" )
+
+
+
+void
+_gcry_aes_ssse3_do_setkey (RIJNDAEL_context *ctx, const byte *key)
+{
+  unsigned int keybits = (ctx->rounds - 10) * 32 + 128;
+  byte ssse3_state[SSSE3_STATE_SIZE];
+
+  vpaes_ssse3_prepare();
+
+  asm volatile ("leaq %q[key], %%rdi"                  "\n\t"
+                "movl %[bits], %%esi"                  "\n\t"
+                "leaq %[buf], %%rdx"                   "\n\t"
+                "movl %[dir], %%ecx"                   "\n\t"
+                "movl %[rotoffs], %%r8d"               "\n\t"
+                "call _aes_schedule_core"              "\n\t"
+                :
+                : [key] "m" (*key),
+                  [bits] "g" (keybits),
+                  [buf] "m" (ctx->keyschenc32[0][0]),
+                  [dir] "g" (0),
+                  [rotoffs] "g" (48)
+                : "r8", "r9", "r10", "r11", "rax", "rcx", "rdx", "rdi", "rsi",
+                  "cc", "memory");
+
+  vpaes_ssse3_cleanup();
+
+  /* Save key for setting up decryption. */
+  memcpy(&ctx->keyschdec32[0][0], key, keybits / 8);
+}
+
+
+/* Make a decryption key from an encryption key. */
+void
+_gcry_aes_ssse3_prepare_decryption (RIJNDAEL_context *ctx)
+{
+  unsigned int keybits = (ctx->rounds - 10) * 32 + 128;
+  byte ssse3_state[SSSE3_STATE_SIZE];
+
+  vpaes_ssse3_prepare();
+
+  asm volatile ("leaq %q[key], %%rdi"                  "\n\t"
+                "movl %[bits], %%esi"                  "\n\t"
+                "leaq %[buf], %%rdx"                   "\n\t"
+                "movl %[dir], %%ecx"                   "\n\t"
+                "movl %[rotoffs], %%r8d"               "\n\t"
+                "call _aes_schedule_core"              "\n\t"
+                :
+                : [key] "m" (ctx->keyschdec32[0][0]),
+                  [bits] "g" (keybits),
+                  [buf] "m" (ctx->keyschdec32[ctx->rounds][0]),
+                  [dir] "g" (1),
+                  [rotoffs] "g" ((keybits == 192) ? 0 : 32)
+                : "r8", "r9", "r10", "r11", "rax", "rcx", "rdx", "rdi", "rsi",
+                  "cc", "memory");
+
+  vpaes_ssse3_cleanup();
+}
+
+
+/* Encrypt one block using the Intel SSSE3 instructions.  Block is input
+* and output through SSE register xmm0. */
+static inline void
+do_vpaes_ssse3_enc (const RIJNDAEL_context *ctx, unsigned int nrounds,
+                    const void *aes_const_ptr)
+{
+  unsigned int middle_rounds = nrounds - 1;
+  const void *keysched = ctx->keyschenc32;
+
+  asm volatile ("call _aes_encrypt_core"               "\n\t"
+                : "+a" (middle_rounds), "+d" (keysched)
+                : "c" (aes_const_ptr)
+                : "rdi", "rsi", "cc", "memory");
+}
+
+
+/* Decrypt one block using the Intel SSSE3 instructions.  Block is input
+* and output through SSE register xmm0. */
+static inline void
+do_vpaes_ssse3_dec (const RIJNDAEL_context *ctx, unsigned int nrounds,
+                    const void *aes_const_ptr)
+{
+  unsigned int middle_rounds = nrounds - 1;
+  const void *keysched = ctx->keyschdec32;
+
+  asm volatile ("call _aes_decrypt_core"               "\n\t"
+                : "+a" (middle_rounds), "+d" (keysched)
+                : "c" (aes_const_ptr)
+                : "rsi", "cc", "memory");
+}
+
+
+unsigned int
+_gcry_aes_ssse3_encrypt (const RIJNDAEL_context *ctx, unsigned char *dst,
+                        const unsigned char *src)
+{
+  unsigned int nrounds = ctx->rounds;
+  const void *aes_const_ptr;
+  byte ssse3_state[SSSE3_STATE_SIZE];
+
+  vpaes_ssse3_prepare_enc (aes_const_ptr);
+  asm volatile ("movdqu %[src], %%xmm0\n\t"
+                :
+                : [src] "m" (*src)
+                : "memory" );
+  do_vpaes_ssse3_enc (ctx, nrounds, aes_const_ptr);
+  asm volatile ("movdqu %%xmm0, %[dst]\n\t"
+                : [dst] "=m" (*dst)
+                :
+                : "memory" );
+  vpaes_ssse3_cleanup ();
+  return 0;
+}
+
+
+void
+_gcry_aes_ssse3_cfb_enc (RIJNDAEL_context *ctx, unsigned char *outbuf,
+                        const unsigned char *inbuf, unsigned char *iv,
+                        size_t nblocks)
+{
+  unsigned int nrounds = ctx->rounds;
+  const void *aes_const_ptr;
+  byte ssse3_state[SSSE3_STATE_SIZE];
+
+  vpaes_ssse3_prepare_enc (aes_const_ptr);
+
+  asm volatile ("movdqu %[iv], %%xmm0\n\t"
+                : /* No output */
+                : [iv] "m" (*iv)
+                : "memory" );
+
+  for ( ;nblocks; nblocks-- )
+    {
+      do_vpaes_ssse3_enc (ctx, nrounds, aes_const_ptr);
+
+      asm volatile ("movdqu %[inbuf], %%xmm1\n\t"
+                    "pxor %%xmm1, %%xmm0\n\t"
+                    "movdqu %%xmm0, %[outbuf]\n\t"
+                    : [outbuf] "=m" (*outbuf)
+                    : [inbuf] "m" (*inbuf)
+                    : "memory" );
+
+      outbuf += BLOCKSIZE;
+      inbuf  += BLOCKSIZE;
+    }
+
+  asm volatile ("movdqu %%xmm0, %[iv]\n\t"
+                : [iv] "=m" (*iv)
+                :
+                : "memory" );
+
+  vpaes_ssse3_cleanup ();
+}
+
+
+void
+_gcry_aes_ssse3_cbc_enc (RIJNDAEL_context *ctx, unsigned char *outbuf,
+                        const unsigned char *inbuf, unsigned char *iv,
+                        size_t nblocks, int cbc_mac)
+{
+  unsigned int nrounds = ctx->rounds;
+  const void *aes_const_ptr;
+  byte ssse3_state[SSSE3_STATE_SIZE];
+
+  vpaes_ssse3_prepare_enc (aes_const_ptr);
+
+  asm volatile ("movdqu %[iv], %%xmm7\n\t"
+                : /* No output */
+                : [iv] "m" (*iv)
+                : "memory" );
+
+  for ( ;nblocks; nblocks-- )
+    {
+      asm volatile ("movdqu %[inbuf], %%xmm0\n\t"
+                    "pxor %%xmm7, %%xmm0\n\t"
+                    : /* No output */
+                    : [inbuf] "m" (*inbuf)
+                    : "memory" );
+
+      do_vpaes_ssse3_enc (ctx, nrounds, aes_const_ptr);
+
+      asm volatile ("movdqa %%xmm0, %%xmm7\n\t"
+                    "movdqu %%xmm0, %[outbuf]\n\t"
+                    : [outbuf] "=m" (*outbuf)
+                    :
+                    : "memory" );
+
+      inbuf += BLOCKSIZE;
+      if (!cbc_mac)
+        outbuf += BLOCKSIZE;
+    }
+
+  asm volatile ("movdqu %%xmm7, %[iv]\n\t"
+                : [iv] "=m" (*iv)
+                :
+                : "memory" );
+
+  vpaes_ssse3_cleanup ();
+}
+
+
+void
+_gcry_aes_ssse3_ctr_enc (RIJNDAEL_context *ctx, unsigned char *outbuf,
+                        const unsigned char *inbuf, unsigned char *ctr,
+                        size_t nblocks)
+{
+  static const unsigned char be_mask[16] __attribute__ ((aligned (16))) =
+    { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
+  unsigned int nrounds = ctx->rounds;
+  const void *aes_const_ptr;
+  byte ssse3_state[SSSE3_STATE_SIZE];
+  u64 ctrlow;
+
+  vpaes_ssse3_prepare_enc (aes_const_ptr);
+
+  asm volatile ("movdqa %[mask], %%xmm6\n\t" /* Preload mask */
+                "movdqa (%[ctr]), %%xmm7\n\t"  /* Preload CTR */
+                "movq 8(%[ctr]), %q[ctrlow]\n\t"
+                "bswapq %q[ctrlow]\n\t"
+                : [ctrlow] "=r" (ctrlow)
+                : [mask] "m" (*be_mask),
+                  [ctr] "r" (ctr)
+                : "memory", "cc");
+
+  for ( ;nblocks; nblocks-- )
+    {
+      asm volatile ("movdqa %%xmm7, %%xmm0\n\t"     /* xmm0 := CTR (xmm7)  */
+                    "pcmpeqd %%xmm1, %%xmm1\n\t"
+                    "psrldq $8, %%xmm1\n\t"         /* xmm1 = -1 */
+
+                    "pshufb %%xmm6, %%xmm7\n\t"
+                    "psubq  %%xmm1, %%xmm7\n\t"     /* xmm7++ (big endian) */
+
+                    /* detect if 64-bit carry handling is needed */
+                    "incq   %q[ctrlow]\n\t"
+                    "jnz    .Lno_carry%=\n\t"
+
+                    "pslldq $8, %%xmm1\n\t"         /* move lower 64-bit to high */
+                    "psubq   %%xmm1, %%xmm7\n\t"    /* add carry to upper 64bits */
+
+                    ".Lno_carry%=:\n\t"
+
+                    "pshufb %%xmm6, %%xmm7\n\t"
+                    :
+                    : [ctr] "r" (ctr), [ctrlow] "r" (ctrlow)
+                    : "cc", "memory");
+
+      do_vpaes_ssse3_enc (ctx, nrounds, aes_const_ptr);
+
+      asm volatile ("movdqu %[src], %%xmm1\n\t"      /* xmm1 := input   */
+                    "pxor %%xmm1, %%xmm0\n\t"        /* EncCTR ^= input  */
+                    "movdqu %%xmm0, %[dst]"          /* Store EncCTR.    */
+                    : [dst] "=m" (*outbuf)
+                    : [src] "m" (*inbuf)
+                    : "memory");
+
+      outbuf += BLOCKSIZE;
+      inbuf  += BLOCKSIZE;
+    }
+
+  asm volatile ("movdqu %%xmm7, %[ctr]\n\t"   /* Update CTR (mem).       */
+                : [ctr] "=m" (*ctr)
+                :
+                : "memory" );
+
+  vpaes_ssse3_cleanup ();
+}
+
+
+unsigned int
+_gcry_aes_ssse3_decrypt (const RIJNDAEL_context *ctx, unsigned char *dst,
+                        const unsigned char *src)
+{
+  unsigned int nrounds = ctx->rounds;
+  const void *aes_const_ptr;
+  byte ssse3_state[SSSE3_STATE_SIZE];
+
+  vpaes_ssse3_prepare_dec (aes_const_ptr);
+  asm volatile ("movdqu %[src], %%xmm0\n\t"
+                :
+                : [src] "m" (*src)
+                : "memory" );
+  do_vpaes_ssse3_dec (ctx, nrounds, aes_const_ptr);
+  asm volatile ("movdqu %%xmm0, %[dst]\n\t"
+                : [dst] "=m" (*dst)
+                :
+                : "memory" );
+  vpaes_ssse3_cleanup ();
+  return 0;
+}
+
+
+void
+_gcry_aes_ssse3_cfb_dec (RIJNDAEL_context *ctx, unsigned char *outbuf,
+                        const unsigned char *inbuf, unsigned char *iv,
+                        size_t nblocks)
+{
+  unsigned int nrounds = ctx->rounds;
+  const void *aes_const_ptr;
+  byte ssse3_state[SSSE3_STATE_SIZE];
+
+  vpaes_ssse3_prepare_enc (aes_const_ptr);
+
+  asm volatile ("movdqu %[iv], %%xmm0\n\t"
+                : /* No output */
+                : [iv] "m" (*iv)
+                : "memory" );
+
+  for ( ;nblocks; nblocks-- )
+    {
+      do_vpaes_ssse3_enc (ctx, nrounds, aes_const_ptr);
+
+      asm volatile ("movdqa %%xmm0, %%xmm6\n\t"
+                    "movdqu %[inbuf], %%xmm0\n\t"
+                    "pxor %%xmm0, %%xmm6\n\t"
+                    "movdqu %%xmm6, %[outbuf]\n\t"
+                    : [outbuf] "=m" (*outbuf)
+                    : [inbuf] "m" (*inbuf)
+                    : "memory" );
+
+      outbuf += BLOCKSIZE;
+      inbuf  += BLOCKSIZE;
+    }
+
+  asm volatile ("movdqu %%xmm0, %[iv]\n\t"
+                : [iv] "=m" (*iv)
+                :
+                : "memory" );
+
+  vpaes_ssse3_cleanup ();
+}
+
+
+void
+_gcry_aes_ssse3_cbc_dec (RIJNDAEL_context *ctx, unsigned char *outbuf,
+                        const unsigned char *inbuf, unsigned char *iv,
+                        size_t nblocks)
+{
+  unsigned int nrounds = ctx->rounds;
+  const void *aes_const_ptr;
+  byte ssse3_state[SSSE3_STATE_SIZE];
+
+  vpaes_ssse3_prepare_dec (aes_const_ptr);
+
+  asm volatile
+    ("movdqu %[iv], %%xmm7\n\t"        /* use xmm7 as fast IV storage */
+    : /* No output */
+    : [iv] "m" (*iv)
+    : "memory");
+
+  for ( ;nblocks; nblocks-- )
+    {
+      asm volatile
+        ("movdqu %[inbuf], %%xmm0\n\t"
+        "movdqa %%xmm0, %%xmm6\n\t"    /* use xmm6 as savebuf */
+        : /* No output */
+        : [inbuf] "m" (*inbuf)
+        : "memory");
+
+      do_vpaes_ssse3_dec (ctx, nrounds, aes_const_ptr);
+
+      asm volatile
+        ("pxor %%xmm7, %%xmm0\n\t"     /* xor IV with output */
+        "movdqu %%xmm0, %[outbuf]\n\t"
+        "movdqu %%xmm6, %%xmm7\n\t"    /* store savebuf as new IV */
+        : [outbuf] "=m" (*outbuf)
+        :
+        : "memory");
+
+      outbuf += BLOCKSIZE;
+      inbuf  += BLOCKSIZE;
+    }
+
+  asm volatile
+    ("movdqu %%xmm7, %[iv]\n\t"        /* store IV */
+    : /* No output */
+    : [iv] "m" (*iv)
+    : "memory");
+
+  vpaes_ssse3_cleanup ();
+}
+
+
+static inline const unsigned char *
+get_l (gcry_cipher_hd_t c, unsigned char *l_tmp, u64 i, unsigned char *iv,
+       unsigned char *ctr, const void **aes_const_ptr,
+       byte ssse3_state[SSSE3_STATE_SIZE], int encrypt)
+{
+  const unsigned char *l;
+  unsigned int ntz;
+
+  if (i & 1)
+    return c->u_mode.ocb.L[0];
+  else if (i & 2)
+    return c->u_mode.ocb.L[1];
+  else if (i & 0xffffffffU)
+    {
+      asm ("rep;bsf %k[low], %k[ntz]\n\t"
+           : [ntz] "=r" (ntz)
+           : [low] "r" (i & 0xffffffffU)
+           : "cc");
+    }
+  else
+    {
+      if (OCB_L_TABLE_SIZE < 32)
+        {
+          ntz = 32;
+        }
+      else if (i)
+        {
+          asm ("rep;bsf %k[high], %k[ntz]\n\t"
+               : [ntz] "=r" (ntz)
+               : [high] "r" (i >> 32)
+               : "cc");
+          ntz += 32;
+        }
+      else
+        {
+          ntz = 64;
+        }
+    }
+
+  if (ntz < OCB_L_TABLE_SIZE)
+    {
+      l = c->u_mode.ocb.L[ntz];
+    }
+  else
+    {
+      /* Store Offset & Checksum before calling external function */
+      asm volatile ("movdqu %%xmm7, %[iv]\n\t"
+                    "movdqu %%xmm6, %[ctr]\n\t"
+                    : [iv] "=m" (*iv),
+                      [ctr] "=m" (*ctr)
+                    :
+                    : "memory" );
+
+      /* Restore SSSE3 state. */
+      vpaes_ssse3_cleanup();
+
+      l = _gcry_cipher_ocb_get_l (c, l_tmp, i);
+
+      /* Save SSSE3 state. */
+      if (encrypt)
+       {
+         vpaes_ssse3_prepare_enc (*aes_const_ptr);
+       }
+      else
+       {
+         vpaes_ssse3_prepare_dec (*aes_const_ptr);
+       }
+
+      /* Restore Offset & Checksum */
+      asm volatile ("movdqu %[iv], %%xmm7\n\t"
+                    "movdqu %[ctr], %%xmm6\n\t"
+                    : /* No output */
+                    : [iv] "m" (*iv),
+                      [ctr] "m" (*ctr)
+                    : "memory" );
+    }
+
+  return l;
+}
+
+
+static void
+ssse3_ocb_enc (gcry_cipher_hd_t c, void *outbuf_arg,
+               const void *inbuf_arg, size_t nblocks)
+{
+  union { unsigned char x1[16] ATTR_ALIGNED_16; u32 x32[4]; } l_tmp;
+  RIJNDAEL_context *ctx = (void *)&c->context.c;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  u64 n = c->u_mode.ocb.data_nblocks;
+  unsigned int nrounds = ctx->rounds;
+  const void *aes_const_ptr;
+  byte ssse3_state[SSSE3_STATE_SIZE];
+
+  vpaes_ssse3_prepare_enc (aes_const_ptr);
+
+  /* Preload Offset and Checksum */
+  asm volatile ("movdqu %[iv], %%xmm7\n\t"
+                "movdqu %[ctr], %%xmm6\n\t"
+                : /* No output */
+                : [iv] "m" (*c->u_iv.iv),
+                  [ctr] "m" (*c->u_ctr.ctr)
+                : "memory" );
+
+  for ( ;nblocks; nblocks-- )
+    {
+      const unsigned char *l;
+
+      l = get_l(c, l_tmp.x1, ++n, c->u_iv.iv, c->u_ctr.ctr, &aes_const_ptr,
+               ssse3_state, 1);
+
+      /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+      /* Checksum_i = Checksum_{i-1} xor P_i  */
+      /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)  */
+      asm volatile ("movdqu %[l],     %%xmm1\n\t"
+                    "movdqu %[inbuf], %%xmm0\n\t"
+                    "pxor   %%xmm1,   %%xmm7\n\t"
+                    "pxor   %%xmm0,   %%xmm6\n\t"
+                    "pxor   %%xmm7,   %%xmm0\n\t"
+                    :
+                    : [l] "m" (*l),
+                      [inbuf] "m" (*inbuf)
+                    : "memory" );
+
+      do_vpaes_ssse3_enc (ctx, nrounds, aes_const_ptr);
+
+      asm volatile ("pxor   %%xmm7, %%xmm0\n\t"
+                    "movdqu %%xmm0, %[outbuf]\n\t"
+                    : [outbuf] "=m" (*outbuf)
+                    :
+                    : "memory" );
+
+      inbuf += BLOCKSIZE;
+      outbuf += BLOCKSIZE;
+    }
+
+  c->u_mode.ocb.data_nblocks = n;
+  asm volatile ("movdqu %%xmm7, %[iv]\n\t"
+                "movdqu %%xmm6, %[ctr]\n\t"
+                : [iv] "=m" (*c->u_iv.iv),
+                  [ctr] "=m" (*c->u_ctr.ctr)
+                :
+                : "memory" );
+
+  wipememory(&l_tmp, sizeof(l_tmp));
+  vpaes_ssse3_cleanup ();
+}
+
+static void
+ssse3_ocb_dec (gcry_cipher_hd_t c, void *outbuf_arg,
+               const void *inbuf_arg, size_t nblocks)
+{
+  union { unsigned char x1[16] ATTR_ALIGNED_16; u32 x32[4]; } l_tmp;
+  RIJNDAEL_context *ctx = (void *)&c->context.c;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  u64 n = c->u_mode.ocb.data_nblocks;
+  unsigned int nrounds = ctx->rounds;
+  const void *aes_const_ptr;
+  byte ssse3_state[SSSE3_STATE_SIZE];
+
+  vpaes_ssse3_prepare_dec (aes_const_ptr);
+
+  /* Preload Offset and Checksum */
+  asm volatile ("movdqu %[iv], %%xmm7\n\t"
+                "movdqu %[ctr], %%xmm6\n\t"
+                : /* No output */
+                : [iv] "m" (*c->u_iv.iv),
+                  [ctr] "m" (*c->u_ctr.ctr)
+                : "memory" );
+
+  for ( ;nblocks; nblocks-- )
+    {
+      const unsigned char *l;
+
+      l = get_l(c, l_tmp.x1, ++n, c->u_iv.iv, c->u_ctr.ctr, &aes_const_ptr,
+               ssse3_state, 0);
+
+      /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+      /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i)  */
+      /* Checksum_i = Checksum_{i-1} xor P_i  */
+      asm volatile ("movdqu %[l],     %%xmm1\n\t"
+                    "movdqu %[inbuf], %%xmm0\n\t"
+                    "pxor   %%xmm1,   %%xmm7\n\t"
+                    "pxor   %%xmm7,   %%xmm0\n\t"
+                    :
+                    : [l] "m" (*l),
+                      [inbuf] "m" (*inbuf)
+                    : "memory" );
+
+      do_vpaes_ssse3_dec (ctx, nrounds, aes_const_ptr);
+
+      asm volatile ("pxor   %%xmm7, %%xmm0\n\t"
+                    "pxor   %%xmm0, %%xmm6\n\t"
+                    "movdqu %%xmm0, %[outbuf]\n\t"
+                    : [outbuf] "=m" (*outbuf)
+                    :
+                    : "memory" );
+
+      inbuf += BLOCKSIZE;
+      outbuf += BLOCKSIZE;
+    }
+
+  c->u_mode.ocb.data_nblocks = n;
+  asm volatile ("movdqu %%xmm7, %[iv]\n\t"
+                "movdqu %%xmm6, %[ctr]\n\t"
+                : [iv] "=m" (*c->u_iv.iv),
+                  [ctr] "=m" (*c->u_ctr.ctr)
+                :
+                : "memory" );
+
+  wipememory(&l_tmp, sizeof(l_tmp));
+  vpaes_ssse3_cleanup ();
+}
+
+
+void
+_gcry_aes_ssse3_ocb_crypt(gcry_cipher_hd_t c, void *outbuf_arg,
+                          const void *inbuf_arg, size_t nblocks, int encrypt)
+{
+  if (encrypt)
+    ssse3_ocb_enc(c, outbuf_arg, inbuf_arg, nblocks);
+  else
+    ssse3_ocb_dec(c, outbuf_arg, inbuf_arg, nblocks);
+}
+
+
+void
+_gcry_aes_ssse3_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
+                          size_t nblocks)
+{
+  union { unsigned char x1[16] ATTR_ALIGNED_16; u32 x32[4]; } l_tmp;
+  RIJNDAEL_context *ctx = (void *)&c->context.c;
+  const unsigned char *abuf = abuf_arg;
+  u64 n = c->u_mode.ocb.aad_nblocks;
+  unsigned int nrounds = ctx->rounds;
+  const void *aes_const_ptr;
+  byte ssse3_state[SSSE3_STATE_SIZE];
+
+  vpaes_ssse3_prepare_enc (aes_const_ptr);
+
+  /* Preload Offset and Sum */
+  asm volatile ("movdqu %[iv], %%xmm7\n\t"
+                "movdqu %[ctr], %%xmm6\n\t"
+                : /* No output */
+                : [iv] "m" (*c->u_mode.ocb.aad_offset),
+                  [ctr] "m" (*c->u_mode.ocb.aad_sum)
+                : "memory" );
+
+  for ( ;nblocks; nblocks-- )
+    {
+      const unsigned char *l;
+
+      l = get_l(c, l_tmp.x1, ++n, c->u_mode.ocb.aad_offset,
+                c->u_mode.ocb.aad_sum, &aes_const_ptr, ssse3_state, 1);
+
+      /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+      /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i)  */
+      asm volatile ("movdqu %[l],     %%xmm1\n\t"
+                    "movdqu %[abuf],  %%xmm0\n\t"
+                    "pxor   %%xmm1,   %%xmm7\n\t"
+                    "pxor   %%xmm7,   %%xmm0\n\t"
+                    :
+                    : [l] "m" (*l),
+                      [abuf] "m" (*abuf)
+                    : "memory" );
+
+      do_vpaes_ssse3_enc (ctx, nrounds, aes_const_ptr);
+
+      asm volatile ("pxor   %%xmm0,   %%xmm6\n\t"
+                    :
+                    :
+                    : "memory" );
+
+      abuf += BLOCKSIZE;
+    }
+
+  c->u_mode.ocb.aad_nblocks = n;
+  asm volatile ("movdqu %%xmm7, %[iv]\n\t"
+                "movdqu %%xmm6, %[ctr]\n\t"
+                : [iv] "=m" (*c->u_mode.ocb.aad_offset),
+                  [ctr] "=m" (*c->u_mode.ocb.aad_sum)
+                :
+                : "memory" );
+
+  wipememory(&l_tmp, sizeof(l_tmp));
+  vpaes_ssse3_cleanup ();
+}
+
+
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+# define X(...)
+#else
+# define X(...) __VA_ARGS__
+#endif
+
+asm (
+  "\n\t" "##"
+  "\n\t" "## Constant-time SSSE3 AES core implementation."
+  "\n\t" "##"
+  "\n\t" "## By Mike Hamburg (Stanford University), 2009"
+  "\n\t" "## Public domain."
+  "\n\t" "##"
+
+  "\n\t" ".text"
+
+  "\n\t" "##"
+  "\n\t" "##  _aes_encrypt_core"
+  "\n\t" "##"
+  "\n\t" "##  AES-encrypt %xmm0."
+  "\n\t" "##"
+  "\n\t" "##  Inputs:"
+  "\n\t" "##     %xmm0 = input"
+  "\n\t" "##     %xmm9-%xmm15 as in .Laes_preheat"
+  "\n\t" "##     %rcx  = .Laes_consts"
+  "\n\t" "##    (%rdx) = scheduled keys"
+  "\n\t" "##     %rax  = nrounds - 1"
+  "\n\t" "##"
+  "\n\t" "##  Output in %xmm0"
+  "\n\t" "##  Clobbers  %xmm1-%xmm4, %r9, %r11, %rax"
+  "\n\t" "##  Preserves %xmm6 - %xmm7 so you get some local vectors"
+  "\n\t" "##"
+  "\n\t" "##"
+  "\n\t" ".align 16"
+X("\n\t" ".type _aes_encrypt_core,@function")
+  "\n\t" "_aes_encrypt_core:"
+  "\n\t" "     leaq    .Lk_mc_backward(%rcx), %rdi"
+  "\n\t" "     mov     $16,    %rsi"
+  "\n\t" "     movdqa  .Lk_ipt   (%rcx), %xmm2 # iptlo"
+  "\n\t" "     movdqa  %xmm9,  %xmm1"
+  "\n\t" "     pandn   %xmm0,  %xmm1"
+  "\n\t" "     psrld   $4,     %xmm1"
+  "\n\t" "     pand    %xmm9,  %xmm0"
+  "\n\t" "     pshufb  %xmm0,  %xmm2"
+  "\n\t" "     movdqa  .Lk_ipt+16(%rcx), %xmm0 # ipthi"
+  "\n\t" "     pshufb  %xmm1,  %xmm0"
+  "\n\t" "     pxor    (%rdx),%xmm2"
+  "\n\t" "     pxor    %xmm2,  %xmm0"
+  "\n\t" "     add     $16,    %rdx"
+  "\n\t" "     jmp     .Laes_entry"
+
+  "\n\t" ".align 8"
+  "\n\t" ".Laes_loop:"
+  "\n\t" "     # middle of middle round"
+  "\n\t" "     movdqa  %xmm13, %xmm4   # 4 : sb1u"
+  "\n\t" "     pshufb  %xmm2,  %xmm4   # 4 = sb1u"
+  "\n\t" "     pxor    (%rdx), %xmm4   # 4 = sb1u + k"
+  "\n\t" "     movdqa  %xmm12, %xmm0   # 0 : sb1t"
+  "\n\t" "     pshufb  %xmm3,  %xmm0   # 0 = sb1t"
+  "\n\t" "     pxor    %xmm4,  %xmm0   # 0 = A"
+  "\n\t" "     movdqa  %xmm15, %xmm4   # 4 : sb2u"
+  "\n\t" "     pshufb  %xmm2,  %xmm4   # 4 = sb2u"
+  "\n\t" "     movdqa  .Lk_mc_forward-.Lk_mc_backward(%rsi,%rdi), %xmm1"
+  "\n\t" "     movdqa  %xmm14, %xmm2   # 2 : sb2t"
+  "\n\t" "     pshufb  %xmm3,  %xmm2   # 2 = sb2t"
+  "\n\t" "     pxor    %xmm4,  %xmm2   # 2 = 2A"
+  "\n\t" "     movdqa  %xmm0,  %xmm3   # 3 = A"
+  "\n\t" "     pshufb  %xmm1,  %xmm0   # 0 = B"
+  "\n\t" "     pxor    %xmm2,  %xmm0   # 0 = 2A+B"
+  "\n\t" "     pshufb  (%rsi,%rdi), %xmm3  # 3 = D"
+  "\n\t" "     lea     16(%esi),%esi   # next mc"
+  "\n\t" "     pxor    %xmm0,  %xmm3   # 3 = 2A+B+D"
+  "\n\t" "     lea     16(%rdx),%rdx   # next key"
+  "\n\t" "     pshufb  %xmm1,  %xmm0   # 0 = 2B+C"
+  "\n\t" "     pxor    %xmm3,  %xmm0   # 0 = 2A+3B+C+D"
+  "\n\t" "     and     $48, %rsi       # ... mod 4"
+  "\n\t" "     dec     %rax            # nr--"
+
+  "\n\t" ".Laes_entry:"
+  "\n\t" "     # top of round"
+  "\n\t" "     movdqa  %xmm9,  %xmm1   # 1 : i"
+  "\n\t" "     pandn   %xmm0,  %xmm1   # 1 = i<<4"
+  "\n\t" "     psrld   $4,     %xmm1   # 1 = i"
+  "\n\t" "     pand    %xmm9,  %xmm0   # 0 = k"
+  "\n\t" "     movdqa  %xmm11, %xmm2   # 2 : a/k"
+  "\n\t" "     pshufb  %xmm0,  %xmm2   # 2 = a/k"
+  "\n\t" "     pxor    %xmm1,  %xmm0   # 0 = j"
+  "\n\t" "     movdqa  %xmm10, %xmm3   # 3 : 1/i"
+  "\n\t" "     pshufb  %xmm1,  %xmm3   # 3 = 1/i"
+  "\n\t" "     pxor    %xmm2,  %xmm3   # 3 = iak = 1/i + a/k"
+  "\n\t" "     movdqa  %xmm10, %xmm4   # 4 : 1/j"
+  "\n\t" "     pshufb  %xmm0,  %xmm4   # 4 = 1/j"
+  "\n\t" "     pxor    %xmm2,  %xmm4   # 4 = jak = 1/j + a/k"
+  "\n\t" "     movdqa  %xmm10, %xmm2   # 2 : 1/iak"
+  "\n\t" "     pshufb  %xmm3,  %xmm2   # 2 = 1/iak"
+  "\n\t" "     pxor    %xmm0,  %xmm2   # 2 = io"
+  "\n\t" "     movdqa  %xmm10, %xmm3   # 3 : 1/jak"
+  "\n\t" "     pshufb  %xmm4,  %xmm3   # 3 = 1/jak"
+  "\n\t" "     pxor    %xmm1,  %xmm3   # 3 = jo"
+  "\n\t" "     jnz     .Laes_loop"
+
+  "\n\t" "     # middle of last round"
+  "\n\t" "     movdqa  .Lk_sbo(%rcx), %xmm4    # 3 : sbou"
+  "\n\t" "     pshufb  %xmm2,  %xmm4   # 4 = sbou"
+  "\n\t" "     pxor    (%rdx), %xmm4   # 4 = sb1u + k"
+  "\n\t" "     movdqa  .Lk_sbo+16(%rcx), %xmm0 # 0 : sbot"
+  "\n\t" "     pshufb  %xmm3,  %xmm0   # 0 = sb1t"
+  "\n\t" "     pxor    %xmm4,  %xmm0   # 0 = A"
+  "\n\t" "     pshufb  .Lk_sr(%rsi,%rcx), %xmm0"
+  "\n\t" "     ret"
+X("\n\t" ".size _aes_encrypt_core,.-_aes_encrypt_core")
+
+  "\n\t" "##"
+  "\n\t" "##  Decryption core"
+  "\n\t" "##"
+  "\n\t" "##  Same API as encryption core."
+  "\n\t" "##"
+  "\n\t" ".align 16"
+X("\n\t" ".type _aes_decrypt_core,@function")
+  "\n\t" "_aes_decrypt_core:"
+  "\n\t" "     movl    %eax,   %esi"
+  "\n\t" "     shll    $4,     %esi"
+  "\n\t" "     xorl    $48,    %esi"
+  "\n\t" "     andl    $48,    %esi"
+  "\n\t" "     movdqa  .Lk_dipt   (%rcx), %xmm2 # iptlo"
+  "\n\t" "     movdqa  %xmm9,  %xmm1"
+  "\n\t" "     pandn   %xmm0,  %xmm1"
+  "\n\t" "     psrld   $4,     %xmm1"
+  "\n\t" "     pand    %xmm9,  %xmm0"
+  "\n\t" "     pshufb  %xmm0,  %xmm2"
+  "\n\t" "     movdqa  .Lk_dipt+16(%rcx), %xmm0 # ipthi"
+  "\n\t" "     pshufb  %xmm1,  %xmm0"
+  "\n\t" "     pxor    (%rdx), %xmm2"
+  "\n\t" "     pxor    %xmm2,  %xmm0"
+  "\n\t" "     movdqa  .Lk_mc_forward+48(%rcx), %xmm5"
+  "\n\t" "     lea     16(%rdx), %rdx"
+  "\n\t" "     neg     %rax"
+  "\n\t" "     jmp     .Laes_dec_entry"
+
+  "\n\t" ".align 16"
+  "\n\t" ".Laes_dec_loop:"
+  "\n\t" "##"
+  "\n\t" "##  Inverse mix columns"
+  "\n\t" "##"
+  "\n\t" "     movdqa  %xmm13, %xmm4           # 4 : sb9u"
+  "\n\t" "     pshufb  %xmm2,  %xmm4           # 4 = sb9u"
+  "\n\t" "     pxor    (%rdx), %xmm4"
+  "\n\t" "     movdqa  %xmm12, %xmm0           # 0 : sb9t"
+  "\n\t" "     pshufb  %xmm3,  %xmm0           # 0 = sb9t"
+  "\n\t" "     movdqa  .Lk_dsbd+16(%rcx),%xmm1 # 1 : sbdt"
+  "\n\t" "     pxor    %xmm4,  %xmm0           # 0 = ch"
+  "\n\t" "     lea     16(%rdx), %rdx          # next round key"
+
+  "\n\t" "     pshufb  %xmm5,  %xmm0           # MC ch"
+  "\n\t" "     movdqa  %xmm15, %xmm4           # 4 : sbdu"
+  "\n\t" "     pshufb  %xmm2,  %xmm4           # 4 = sbdu"
+  "\n\t" "     pxor    %xmm0,  %xmm4           # 4 = ch"
+  "\n\t" "     pshufb  %xmm3,  %xmm1           # 1 = sbdt"
+  "\n\t" "     pxor    %xmm4,  %xmm1           # 1 = ch"
+
+  "\n\t" "     pshufb  %xmm5,  %xmm1           # MC ch"
+  "\n\t" "     movdqa  %xmm14, %xmm4           # 4 : sbbu"
+  "\n\t" "     pshufb  %xmm2,  %xmm4           # 4 = sbbu"
+  "\n\t" "      inc     %rax                    # nr--"
+  "\n\t" "     pxor    %xmm1,  %xmm4           # 4 = ch"
+  "\n\t" "     movdqa  .Lk_dsbb+16(%rcx),%xmm0 # 0 : sbbt"
+  "\n\t" "     pshufb  %xmm3,  %xmm0           # 0 = sbbt"
+  "\n\t" "     pxor    %xmm4,  %xmm0           # 0 = ch"
+
+  "\n\t" "     pshufb  %xmm5,  %xmm0           # MC ch"
+  "\n\t" "     movdqa  %xmm8,  %xmm4           # 4 : sbeu"
+  "\n\t" "     pshufb  %xmm2,  %xmm4           # 4 = sbeu"
+  "\n\t" "     pshufd  $0x93,  %xmm5,  %xmm5"
+  "\n\t" "     pxor    %xmm0,  %xmm4           # 4 = ch"
+  "\n\t" "     movdqa  .Lk_dsbe+16(%rcx),%xmm0 # 0 : sbet"
+  "\n\t" "     pshufb  %xmm3,  %xmm0           # 0 = sbet"
+  "\n\t" "     pxor    %xmm4,  %xmm0           # 0 = ch"
+
+  "\n\t" ".Laes_dec_entry:"
+  "\n\t" "     # top of round"
+  "\n\t" "     movdqa  %xmm9,  %xmm1   # 1 : i"
+  "\n\t" "     pandn   %xmm0,  %xmm1   # 1 = i<<4"
+  "\n\t" "     psrld   $4,     %xmm1   # 1 = i"
+  "\n\t" "     pand    %xmm9,  %xmm0   # 0 = k"
+  "\n\t" "     movdqa  %xmm11, %xmm2   # 2 : a/k"
+  "\n\t" "     pshufb  %xmm0,  %xmm2   # 2 = a/k"
+  "\n\t" "     pxor    %xmm1,  %xmm0   # 0 = j"
+  "\n\t" "     movdqa  %xmm10, %xmm3   # 3 : 1/i"
+  "\n\t" "     pshufb  %xmm1,  %xmm3   # 3 = 1/i"
+  "\n\t" "     pxor    %xmm2,  %xmm3   # 3 = iak = 1/i + a/k"
+  "\n\t" "     movdqa  %xmm10, %xmm4   # 4 : 1/j"
+  "\n\t" "     pshufb  %xmm0,  %xmm4   # 4 = 1/j"
+  "\n\t" "     pxor    %xmm2,  %xmm4   # 4 = jak = 1/j + a/k"
+  "\n\t" "     movdqa  %xmm10, %xmm2   # 2 : 1/iak"
+  "\n\t" "     pshufb  %xmm3,  %xmm2   # 2 = 1/iak"
+  "\n\t" "     pxor    %xmm0,  %xmm2   # 2 = io"
+  "\n\t" "     movdqa  %xmm10, %xmm3   # 3 : 1/jak"
+  "\n\t" "     pshufb  %xmm4,  %xmm3   # 3 = 1/jak"
+  "\n\t" "     pxor    %xmm1,  %xmm3   # 3 = jo"
+  "\n\t" "     jnz     .Laes_dec_loop"
+
+  "\n\t" "     # middle of last round"
+  "\n\t" "     movdqa  .Lk_dsbo(%rcx), %xmm4           # 3 : sbou"
+  "\n\t" "     pshufb  %xmm2,  %xmm4   # 4 = sbou"
+  "\n\t" "     pxor    (%rdx), %xmm4   # 4 = sb1u + k"
+  "\n\t" "     movdqa  .Lk_dsbo+16(%rcx), %xmm0        # 0 : sbot"
+  "\n\t" "     pshufb  %xmm3,  %xmm0   # 0 = sb1t"
+  "\n\t" "     pxor    %xmm4,  %xmm0   # 0 = A"
+  "\n\t" "     pshufb  .Lk_sr(%rsi,%rcx), %xmm0"
+  "\n\t" "     ret"
+X("\n\t" ".size _aes_decrypt_core,.-_aes_decrypt_core")
+
+  "\n\t" "########################################################"
+  "\n\t" "##                                                    ##"
+  "\n\t" "##                  AES key schedule                  ##"
+  "\n\t" "##                                                    ##"
+  "\n\t" "########################################################"
+
+  "\n\t" ".align 16"
+X("\n\t" ".type _aes_schedule_core,@function")
+  "\n\t" "_aes_schedule_core:"
+  "\n\t" "     # rdi = key"
+  "\n\t" "     # rsi = size in bits"
+  "\n\t" "     # rdx = buffer"
+  "\n\t" "     # rcx = direction.  0=encrypt, 1=decrypt"
+
+  "\n\t" "     # load the tables"
+  "\n\t" "     lea     .Laes_consts(%rip), %r10"
+  "\n\t" "     movdqa            (%r10), %xmm9  # 0F"
+  "\n\t" "     movdqa  .Lk_inv   (%r10), %xmm10 # inv"
+  "\n\t" "     movdqa  .Lk_inv+16(%r10), %xmm11 # inva"
+  "\n\t" "     movdqa  .Lk_sb1   (%r10), %xmm13 # sb1u"
+  "\n\t" "     movdqa  .Lk_sb1+16(%r10), %xmm12 # sb1t"
+  "\n\t" "     movdqa  .Lk_sb2   (%r10), %xmm15 # sb2u"
+  "\n\t" "     movdqa  .Lk_sb2+16(%r10), %xmm14 # sb2t"
+
+  "\n\t" "     movdqa  .Lk_rcon(%r10), %xmm8   # load rcon"
+  "\n\t" "     movdqu  (%rdi), %xmm0           # load key (unaligned)"
+
+  "\n\t" "     # input transform"
+  "\n\t" "     movdqu  %xmm0,  %xmm3"
+  "\n\t" "     lea     .Lk_ipt(%r10), %r11"
+  "\n\t" "     call    .Laes_schedule_transform"
+  "\n\t" "     movdqu  %xmm0,  %xmm7"
+
+  "\n\t" "     test    %rcx,   %rcx"
+  "\n\t" "     jnz     .Laes_schedule_am_decrypting"
+
+  "\n\t" "     # encrypting, output zeroth round key after transform"
+  "\n\t" "     movdqa  %xmm0,  (%rdx)"
+  "\n\t" "     jmp     .Laes_schedule_go"
+
+  "\n\t" ".Laes_schedule_am_decrypting:"
+  "\n\t" "     # decrypting, output zeroth round key after shiftrows"
+  "\n\t" "     pshufb  .Lk_sr(%r8,%r10),%xmm3"
+  "\n\t" "     movdqa  %xmm3,  (%rdx)"
+  "\n\t" "     xor     $48,    %r8"
+
+  "\n\t" ".Laes_schedule_go:"
+  "\n\t" "     cmp     $192,   %rsi"
+  "\n\t" "     je      .Laes_schedule_192"
+  "\n\t" "     cmp     $256,   %rsi"
+  "\n\t" "     je      .Laes_schedule_256"
+  "\n\t" "     # 128: fall though"
+
+  "\n\t" "##"
+  "\n\t" "##  .Laes_schedule_128"
+  "\n\t" "##"
+  "\n\t" "##  128-bit specific part of key schedule."
+  "\n\t" "##"
+  "\n\t" "##  This schedule is really simple, because all its parts"
+  "\n\t" "##  are accomplished by the subroutines."
+  "\n\t" "##"
+  "\n\t" ".Laes_schedule_128:"
+  "\n\t" "     mov     $10, %rsi"
+
+  "\n\t" ".Laes_schedule_128_L:"
+  "\n\t" "     call    .Laes_schedule_round"
+  "\n\t" "     dec     %rsi"
+  "\n\t" "     jz      .Laes_schedule_mangle_last"
+  "\n\t" "     call    .Laes_schedule_mangle   # write output"
+  "\n\t" "     jmp     .Laes_schedule_128_L"
+
+  "\n\t" "##"
+  "\n\t" "##  .Laes_schedule_192"
+  "\n\t" "##"
+  "\n\t" "##  192-bit specific part of key schedule."
+  "\n\t" "##"
+  "\n\t" "##  The main body of this schedule is the same as the 128-bit"
+  "\n\t" "##  schedule, but with more smearing.  The long, high side is"
+  "\n\t" "##  stored in %xmm7 as before, and the short, low side is in"
+  "\n\t" "##  the high bits of %xmm6."
+  "\n\t" "##"
+  "\n\t" "##  This schedule is somewhat nastier, however, because each"
+  "\n\t" "##  round produces 192 bits of key material, or 1.5 round keys."
+  "\n\t" "##  Therefore, on each cycle we do 2 rounds and produce 3 round"
+  "\n\t" "##  keys."
+  "\n\t" "##"
+  "\n\t" ".Laes_schedule_192:"
+  "\n\t" "     movdqu  8(%rdi),%xmm0           # load key part 2 (very unaligned)"
+  "\n\t" "     call    .Laes_schedule_transform        # input transform"
+  "\n\t" "     pshufd  $0x0E,  %xmm0,  %xmm6"
+  "\n\t" "     pslldq  $8,     %xmm6           # clobber low side with zeros"
+  "\n\t" "     mov     $4,     %rsi"
+
+  "\n\t" ".Laes_schedule_192_L:"
+  "\n\t" "     call    .Laes_schedule_round"
+  "\n\t" "     palignr $8,%xmm6,%xmm0  "
+  "\n\t" "     call    .Laes_schedule_mangle   # save key n"
+  "\n\t" "     call    .Laes_schedule_192_smear"
+  "\n\t" "     call    .Laes_schedule_mangle   # save key n+1"
+  "\n\t" "     call    .Laes_schedule_round"
+  "\n\t" "     dec     %rsi"
+  "\n\t" "     jz      .Laes_schedule_mangle_last"
+  "\n\t" "     call    .Laes_schedule_mangle   # save key n+2"
+  "\n\t" "     call    .Laes_schedule_192_smear"
+  "\n\t" "     jmp     .Laes_schedule_192_L"
+
+  "\n\t" "##"
+  "\n\t" "##  .Laes_schedule_192_smear"
+  "\n\t" "##"
+  "\n\t" "##  Smear the short, low side in the 192-bit key schedule."
+  "\n\t" "##"
+  "\n\t" "##  Inputs:"
+  "\n\t" "##    %xmm7: high side, b  a  x  y"
+  "\n\t" "##    %xmm6:  low side, d  c  0  0"
+  "\n\t" "##    %xmm13: 0"
+  "\n\t" "##"
+  "\n\t" "##  Outputs:"
+  "\n\t" "##    %xmm6: b+c+d  b+c  0  0"
+  "\n\t" "##    %xmm0: b+c+d  b+c  b  a"
+  "\n\t" "##"
+  "\n\t" ".Laes_schedule_192_smear:"
+  "\n\t" "     pshufd  $0x80,  %xmm6,  %xmm0   # d c 0 0 -> c 0 0 0"
+  "\n\t" "     pxor    %xmm0,  %xmm6           # -> c+d c 0 0"
+  "\n\t" "     pshufd  $0xFE,  %xmm7,  %xmm0   # b a _ _ -> b b b a"
+  "\n\t" "     pxor    %xmm6,  %xmm0           # -> b+c+d b+c b a"
+  "\n\t" "     pshufd  $0x0E,  %xmm0,  %xmm6"
+  "\n\t" "     pslldq  $8,     %xmm6           # clobber low side with zeros"
+  "\n\t" "     ret"
+
+  "\n\t" "##"
+  "\n\t" "##  .Laes_schedule_256"
+  "\n\t" "##"
+  "\n\t" "##  256-bit specific part of key schedule."
+  "\n\t" "##"
+  "\n\t" "##  The structure here is very similar to the 128-bit"
+  "\n\t" "##  schedule, but with an additional 'low side' in"
+  "\n\t" "##  %xmm6.  The low side's rounds are the same as the"
+  "\n\t" "##  high side's, except no rcon and no rotation."
+  "\n\t" "##"
+  "\n\t" ".Laes_schedule_256:"
+  "\n\t" "     movdqu  16(%rdi),%xmm0          # load key part 2 (unaligned)"
+  "\n\t" "     call    .Laes_schedule_transform        # input transform"
+  "\n\t" "     mov     $7, %rsi"
+
+  "\n\t" ".Laes_schedule_256_L:"
+  "\n\t" "     call    .Laes_schedule_mangle   # output low result"
+  "\n\t" "     movdqa  %xmm0,  %xmm6           # save cur_lo in xmm6"
+
+  "\n\t" "     # high round"
+  "\n\t" "     call    .Laes_schedule_round"
+  "\n\t" "     dec     %rsi"
+  "\n\t" "     jz      .Laes_schedule_mangle_last"
+  "\n\t" "     call    .Laes_schedule_mangle   "
+
+  "\n\t" "     # low round. swap xmm7 and xmm6"
+  "\n\t" "     pshufd  $0xFF,  %xmm0,  %xmm0"
+  "\n\t" "     movdqa  %xmm7,  %xmm5"
+  "\n\t" "     movdqa  %xmm6,  %xmm7"
+  "\n\t" "     call    .Laes_schedule_low_round"
+  "\n\t" "     movdqa  %xmm5,  %xmm7"
+
+  "\n\t" "     jmp     .Laes_schedule_256_L"
+
+  "\n\t" "##"
+  "\n\t" "##  .Laes_schedule_round"
+  "\n\t" "##"
+  "\n\t" "##  Runs one main round of the key schedule on %xmm0, %xmm7"
+  "\n\t" "##"
+  "\n\t" "##  Specifically, runs subbytes on the high dword of %xmm0"
+  "\n\t" "##  then rotates it by one byte and xors into the low dword of"
+  "\n\t" "##  %xmm7."
+  "\n\t" "##"
+  "\n\t" "##  Adds rcon from low byte of %xmm8, then rotates %xmm8 for"
+  "\n\t" "##  next rcon."
+  "\n\t" "##"
+  "\n\t" "##  Smears the dwords of %xmm7 by xoring the low into the"
+  "\n\t" "##  second low, result into third, result into highest."
+  "\n\t" "##"
+  "\n\t" "##  Returns results in %xmm7 = %xmm0."
+  "\n\t" "##  Clobbers %xmm1-%xmm4, %r11."
+  "\n\t" "##"
+  "\n\t" ".Laes_schedule_round:"
+  "\n\t" "     # extract rcon from xmm8"
+  "\n\t" "     pxor    %xmm1,  %xmm1"
+  "\n\t" "     palignr $15,    %xmm8,  %xmm1"
+  "\n\t" "     palignr $15,    %xmm8,  %xmm8"
+  "\n\t" "     pxor    %xmm1,  %xmm7"
+
+  "\n\t" "     # rotate"
+  "\n\t" "     pshufd  $0xFF,  %xmm0,  %xmm0"
+  "\n\t" "     palignr $1,     %xmm0,  %xmm0"
+
+  "\n\t" "     # fall through..."
+
+  "\n\t" "     # low round: same as high round, but no rotation and no rcon."
+  "\n\t" ".Laes_schedule_low_round:"
+  "\n\t" "     # smear xmm7"
+  "\n\t" "     movdqa  %xmm7,  %xmm1"
+  "\n\t" "     pslldq  $4,     %xmm7"
+  "\n\t" "     pxor    %xmm1,  %xmm7"
+  "\n\t" "     movdqa  %xmm7,  %xmm1"
+  "\n\t" "     pslldq  $8,     %xmm7"
+  "\n\t" "     pxor    %xmm1,  %xmm7"
+  "\n\t" "     pxor    .Lk_s63(%r10), %xmm7"
+
+  "\n\t" "     # subbytes"
+  "\n\t" "     movdqa  %xmm9,  %xmm1"
+  "\n\t" "     pandn   %xmm0,  %xmm1"
+  "\n\t" "     psrld   $4,     %xmm1           # 1 = i"
+  "\n\t" "     pand    %xmm9,  %xmm0           # 0 = k"
+  "\n\t" "     movdqa  %xmm11, %xmm2           # 2 : a/k"
+  "\n\t" "     pshufb  %xmm0,  %xmm2           # 2 = a/k"
+  "\n\t" "     pxor    %xmm1,  %xmm0           # 0 = j"
+  "\n\t" "     movdqa  %xmm10, %xmm3           # 3 : 1/i"
+  "\n\t" "     pshufb  %xmm1,  %xmm3           # 3 = 1/i"
+  "\n\t" "     pxor    %xmm2,  %xmm3           # 3 = iak = 1/i + a/k"
+  "\n\t" "     movdqa  %xmm10, %xmm4           # 4 : 1/j"
+  "\n\t" "     pshufb  %xmm0,  %xmm4           # 4 = 1/j"
+  "\n\t" "     pxor    %xmm2,  %xmm4           # 4 = jak = 1/j + a/k"
+  "\n\t" "     movdqa  %xmm10, %xmm2           # 2 : 1/iak"
+  "\n\t" "     pshufb  %xmm3,  %xmm2           # 2 = 1/iak"
+  "\n\t" "     pxor    %xmm0,  %xmm2           # 2 = io"
+  "\n\t" "     movdqa  %xmm10, %xmm3           # 3 : 1/jak"
+  "\n\t" "     pshufb  %xmm4,  %xmm3           # 3 = 1/jak"
+  "\n\t" "     pxor    %xmm1,  %xmm3           # 3 = jo"
+  "\n\t" "     movdqa  .Lk_sb1(%r10), %xmm4    # 4 : sbou"
+  "\n\t" "     pshufb  %xmm2,  %xmm4           # 4 = sbou"
+  "\n\t" "     movdqa  .Lk_sb1+16(%r10), %xmm0 # 0 : sbot"
+  "\n\t" "     pshufb  %xmm3,  %xmm0           # 0 = sb1t"
+  "\n\t" "     pxor    %xmm4,  %xmm0           # 0 = sbox output"
+
+  "\n\t" "     # add in smeared stuff"
+  "\n\t" "     pxor    %xmm7,  %xmm0   "
+  "\n\t" "     movdqa  %xmm0,  %xmm7"
+  "\n\t" "     ret"
+
+  "\n\t" "##"
+  "\n\t" "##  .Laes_schedule_transform"
+  "\n\t" "##"
+  "\n\t" "##  Linear-transform %xmm0 according to tables at (%r11)"
+  "\n\t" "##"
+  "\n\t" "##  Requires that %xmm9 = 0x0F0F... as in preheat"
+  "\n\t" "##  Output in %xmm0"
+  "\n\t" "##  Clobbers %xmm1, %xmm2"
+  "\n\t" "##"
+  "\n\t" ".Laes_schedule_transform:"
+  "\n\t" "     movdqa  %xmm9,  %xmm1"
+  "\n\t" "     pandn   %xmm0,  %xmm1"
+  "\n\t" "     psrld   $4,     %xmm1"
+  "\n\t" "     pand    %xmm9,  %xmm0"
+  "\n\t" "     movdqa  (%r11), %xmm2   # lo"
+  "\n\t" "     pshufb  %xmm0,  %xmm2"
+  "\n\t" "     movdqa  16(%r11), %xmm0 # hi"
+  "\n\t" "     pshufb  %xmm1,  %xmm0"
+  "\n\t" "     pxor    %xmm2,  %xmm0"
+  "\n\t" "     ret"
+
+  "\n\t" "##"
+  "\n\t" "##  .Laes_schedule_mangle"
+  "\n\t" "##"
+  "\n\t" "##  Mangle xmm0 from (basis-transformed) standard version"
+  "\n\t" "##  to our version."
+  "\n\t" "##"
+  "\n\t" "##  On encrypt,"
+  "\n\t" "##    xor with 0x63"
+  "\n\t" "##    multiply by circulant 0,1,1,1"
+  "\n\t" "##    apply shiftrows transform"
+  "\n\t" "##"
+  "\n\t" "##  On decrypt,"
+  "\n\t" "##    xor with 0x63"
+  "\n\t" "##    multiply by 'inverse mixcolumns' circulant E,B,D,9"
+  "\n\t" "##    deskew"
+  "\n\t" "##    apply shiftrows transform"
+  "\n\t" "##"
+  "\n\t" "##"
+  "\n\t" "##  Writes out to (%rdx), and increments or decrements it"
+  "\n\t" "##  Keeps track of round number mod 4 in %r8"
+  "\n\t" "##  Preserves xmm0"
+  "\n\t" "##  Clobbers xmm1-xmm5"
+  "\n\t" "##"
+  "\n\t" ".Laes_schedule_mangle:"
+  "\n\t" "     movdqa  %xmm0,  %xmm4   # save xmm0 for later"
+  "\n\t" "     movdqa  .Lk_mc_forward(%r10),%xmm5"
+  "\n\t" "     test    %rcx,   %rcx"
+  "\n\t" "     jnz     .Laes_schedule_mangle_dec"
+
+  "\n\t" "     # encrypting"
+  "\n\t" "     add     $16,    %rdx"
+  "\n\t" "     pxor    .Lk_s63(%r10),%xmm4"
+  "\n\t" "     pshufb  %xmm5,  %xmm4"
+  "\n\t" "     movdqa  %xmm4,  %xmm3"
+  "\n\t" "     pshufb  %xmm5,  %xmm4"
+  "\n\t" "     pxor    %xmm4,  %xmm3"
+  "\n\t" "     pshufb  %xmm5,  %xmm4"
+  "\n\t" "     pxor    %xmm4,  %xmm3"
+
+  "\n\t" "     jmp     .Laes_schedule_mangle_both"
+
+  "\n\t" ".Laes_schedule_mangle_dec:"
+  "\n\t" "     lea     .Lk_dks_1(%r10), %r11   # first table: *9"
+  "\n\t" "     call    .Laes_schedule_transform"
+  "\n\t" "     movdqa  %xmm0,  %xmm3"
+  "\n\t" "     pshufb  %xmm5,  %xmm3"
+
+  "\n\t" "     add     $32,    %r11            # next table:  *B"
+  "\n\t" "     call    .Laes_schedule_transform"
+  "\n\t" "     pxor    %xmm0,  %xmm3"
+  "\n\t" "     pshufb  %xmm5,  %xmm3"
+
+  "\n\t" "     add     $32,    %r11            # next table:  *D"
+  "\n\t" "     call    .Laes_schedule_transform"
+  "\n\t" "     pxor    %xmm0,  %xmm3"
+  "\n\t" "     pshufb  %xmm5,  %xmm3"
+
+  "\n\t" "     add     $32,    %r11            # next table:  *E"
+  "\n\t" "     call    .Laes_schedule_transform"
+  "\n\t" "     pxor    %xmm0,  %xmm3"
+  "\n\t" "     pshufb  %xmm5,  %xmm3"
+
+  "\n\t" "     movdqa  %xmm4,  %xmm0           # restore %xmm0"
+  "\n\t" "     add     $-16,   %rdx"
+
+  "\n\t" ".Laes_schedule_mangle_both:"
+  "\n\t" "     pshufb  .Lk_sr(%r8,%r10),%xmm3"
+  "\n\t" "     add     $-16,   %r8"
+  "\n\t" "     and     $48,    %r8"
+  "\n\t" "     movdqa  %xmm3,  (%rdx)"
+  "\n\t" "     ret"
+
+  "\n\t" "##"
+  "\n\t" "##  .Laes_schedule_mangle_last"
+  "\n\t" "##"
+  "\n\t" "##  Mangler for last round of key schedule"
+  "\n\t" "##  Mangles %xmm0"
+  "\n\t" "##    when encrypting, outputs out(%xmm0) ^ 63"
+  "\n\t" "##    when decrypting, outputs unskew(%xmm0)"
+  "\n\t" "##"
+  "\n\t" "##  Always called right before return... jumps to cleanup and exits"
+  "\n\t" "##"
+  "\n\t" ".Laes_schedule_mangle_last:"
+  "\n\t" "     # schedule last round key from xmm0"
+  "\n\t" "     lea     .Lk_deskew(%r10),%r11   # prepare to deskew"
+  "\n\t" "     test    %rcx,   %rcx"
+  "\n\t" "     jnz     .Laes_schedule_mangle_last_dec"
+
+  "\n\t" "     # encrypting"
+  "\n\t" "     pshufb  .Lk_sr(%r8,%r10),%xmm0  # output permute"
+  "\n\t" "     lea     .Lk_opt(%r10),  %r11    # prepare to output transform"
+  "\n\t" "     add     $32,    %rdx"
+
+  "\n\t" ".Laes_schedule_mangle_last_dec:"
+  "\n\t" "     add     $-16,   %rdx"
+  "\n\t" "     pxor    .Lk_s63(%r10),  %xmm0"
+  "\n\t" "     call    .Laes_schedule_transform # output transform"
+  "\n\t" "     movdqa  %xmm0,  (%rdx)          # save last key"
+
+  "\n\t" "     #_aes_cleanup"
+  "\n\t" "     pxor    %xmm0,  %xmm0"
+  "\n\t" "     pxor    %xmm1,  %xmm1"
+  "\n\t" "     pxor    %xmm2,  %xmm2"
+  "\n\t" "     pxor    %xmm3,  %xmm3"
+  "\n\t" "     pxor    %xmm4,  %xmm4"
+  "\n\t" "     pxor    %xmm5,  %xmm5"
+  "\n\t" "     pxor    %xmm6,  %xmm6"
+  "\n\t" "     pxor    %xmm7,  %xmm7"
+  "\n\t" "     pxor    %xmm8,  %xmm8"
+  "\n\t" "     ret"
+X("\n\t" ".size _aes_schedule_core,.-_aes_schedule_core")
+
+  "\n\t" "########################################################"
+  "\n\t" "##                                                    ##"
+  "\n\t" "##                     Constants                      ##"
+  "\n\t" "##                                                    ##"
+  "\n\t" "########################################################"
+
+  "\n\t" ".align 16"
+X("\n\t" ".type _aes_consts,@object")
+  "\n\t" ".Laes_consts:"
+  "\n\t" "_aes_consts:"
+  "\n\t" "     # s0F"
+  "\n\t" "     .Lk_s0F = .-.Laes_consts"
+  "\n\t" "     .quad   0x0F0F0F0F0F0F0F0F"
+  "\n\t" "     .quad   0x0F0F0F0F0F0F0F0F"
+
+  "\n\t" "     # input transform (lo, hi)"
+  "\n\t" "     .Lk_ipt = .-.Laes_consts"
+  "\n\t" "     .quad   0xC2B2E8985A2A7000"
+  "\n\t" "     .quad   0xCABAE09052227808"
+  "\n\t" "     .quad   0x4C01307D317C4D00"
+  "\n\t" "     .quad   0xCD80B1FCB0FDCC81"
+
+  "\n\t" "     # inv, inva"
+  "\n\t" "     .Lk_inv = .-.Laes_consts"
+  "\n\t" "     .quad   0x0E05060F0D080180"
+  "\n\t" "     .quad   0x040703090A0B0C02"
+  "\n\t" "     .quad   0x01040A060F0B0780"
+  "\n\t" "     .quad   0x030D0E0C02050809"
+
+  "\n\t" "     # sb1u, sb1t"
+  "\n\t" "     .Lk_sb1 = .-.Laes_consts"
+  "\n\t" "     .quad   0xB19BE18FCB503E00"
+  "\n\t" "     .quad   0xA5DF7A6E142AF544"
+  "\n\t" "     .quad   0x3618D415FAE22300"
+  "\n\t" "     .quad   0x3BF7CCC10D2ED9EF"
+
+
+  "\n\t" "     # sb2u, sb2t"
+  "\n\t" "     .Lk_sb2 = .-.Laes_consts"
+  "\n\t" "     .quad   0xE27A93C60B712400"
+  "\n\t" "     .quad   0x5EB7E955BC982FCD"
+  "\n\t" "     .quad   0x69EB88400AE12900"
+  "\n\t" "     .quad   0xC2A163C8AB82234A"
+
+  "\n\t" "     # sbou, sbot"
+  "\n\t" "     .Lk_sbo = .-.Laes_consts"
+  "\n\t" "     .quad   0xD0D26D176FBDC700"
+  "\n\t" "     .quad   0x15AABF7AC502A878"
+  "\n\t" "     .quad   0xCFE474A55FBB6A00"
+  "\n\t" "     .quad   0x8E1E90D1412B35FA"
+
+  "\n\t" "     # mc_forward"
+  "\n\t" "     .Lk_mc_forward = .-.Laes_consts"
+  "\n\t" "     .quad   0x0407060500030201"
+  "\n\t" "     .quad   0x0C0F0E0D080B0A09"
+  "\n\t" "     .quad   0x080B0A0904070605"
+  "\n\t" "     .quad   0x000302010C0F0E0D"
+  "\n\t" "     .quad   0x0C0F0E0D080B0A09"
+  "\n\t" "     .quad   0x0407060500030201"
+  "\n\t" "     .quad   0x000302010C0F0E0D"
+  "\n\t" "     .quad   0x080B0A0904070605"
+
+  "\n\t" "     # mc_backward"
+  "\n\t" "     .Lk_mc_backward = .-.Laes_consts"
+  "\n\t" "     .quad   0x0605040702010003"
+  "\n\t" "     .quad   0x0E0D0C0F0A09080B"
+  "\n\t" "     .quad   0x020100030E0D0C0F"
+  "\n\t" "     .quad   0x0A09080B06050407"
+  "\n\t" "     .quad   0x0E0D0C0F0A09080B"
+  "\n\t" "     .quad   0x0605040702010003"
+  "\n\t" "     .quad   0x0A09080B06050407"
+  "\n\t" "     .quad   0x020100030E0D0C0F"
+
+  "\n\t" "     # sr"
+  "\n\t" "     .Lk_sr = .-.Laes_consts"
+  "\n\t" "     .quad   0x0706050403020100"
+  "\n\t" "     .quad   0x0F0E0D0C0B0A0908"
+  "\n\t" "     .quad   0x030E09040F0A0500"
+  "\n\t" "     .quad   0x0B06010C07020D08"
+  "\n\t" "     .quad   0x0F060D040B020900"
+  "\n\t" "     .quad   0x070E050C030A0108"
+  "\n\t" "     .quad   0x0B0E0104070A0D00"
+  "\n\t" "     .quad   0x0306090C0F020508"
+
+  "\n\t" "     # rcon"
+  "\n\t" "     .Lk_rcon = .-.Laes_consts"
+  "\n\t" "     .quad   0x1F8391B9AF9DEEB6"
+  "\n\t" "     .quad   0x702A98084D7C7D81"
+
+  "\n\t" "     # s63: all equal to 0x63 transformed"
+  "\n\t" "     .Lk_s63 = .-.Laes_consts"
+  "\n\t" "     .quad   0x5B5B5B5B5B5B5B5B"
+  "\n\t" "     .quad   0x5B5B5B5B5B5B5B5B"
+
+  "\n\t" "     # output transform"
+  "\n\t" "     .Lk_opt = .-.Laes_consts"
+  "\n\t" "     .quad   0xFF9F4929D6B66000"
+  "\n\t" "     .quad   0xF7974121DEBE6808"
+  "\n\t" "     .quad   0x01EDBD5150BCEC00"
+  "\n\t" "     .quad   0xE10D5DB1B05C0CE0"
+
+  "\n\t" "     # deskew tables: inverts the sbox's 'skew'"
+  "\n\t" "     .Lk_deskew = .-.Laes_consts"
+  "\n\t" "     .quad   0x07E4A34047A4E300"
+  "\n\t" "     .quad   0x1DFEB95A5DBEF91A"
+  "\n\t" "     .quad   0x5F36B5DC83EA6900"
+  "\n\t" "     .quad   0x2841C2ABF49D1E77"
+
+  "\n\t" "##"
+  "\n\t" "##  Decryption stuff"
+  "\n\t" "##  Key schedule constants"
+  "\n\t" "##"
+  "\n\t" "     # decryption key schedule: x -> invskew x*9"
+  "\n\t" "     .Lk_dks_1 = .-.Laes_consts"
+  "\n\t" "     .quad   0xB6116FC87ED9A700"
+  "\n\t" "     .quad   0x4AED933482255BFC"
+  "\n\t" "     .quad   0x4576516227143300"
+  "\n\t" "     .quad   0x8BB89FACE9DAFDCE"
+
+  "\n\t" "     # decryption key schedule: invskew x*9 -> invskew x*D"
+  "\n\t" "     .Lk_dks_2 = .-.Laes_consts"
+  "\n\t" "     .quad   0x27438FEBCCA86400"
+  "\n\t" "     .quad   0x4622EE8AADC90561"
+  "\n\t" "     .quad   0x815C13CE4F92DD00"
+  "\n\t" "     .quad   0x73AEE13CBD602FF2"
+
+  "\n\t" "     # decryption key schedule: invskew x*D -> invskew x*B"
+  "\n\t" "     .Lk_dks_3 = .-.Laes_consts"
+  "\n\t" "     .quad   0x03C4C50201C6C700"
+  "\n\t" "     .quad   0xF83F3EF9FA3D3CFB"
+  "\n\t" "     .quad   0xEE1921D638CFF700"
+  "\n\t" "     .quad   0xA5526A9D7384BC4B"
+
+  "\n\t" "     # decryption key schedule: invskew x*B -> invskew x*E + 0x63"
+  "\n\t" "     .Lk_dks_4 = .-.Laes_consts"
+  "\n\t" "     .quad   0xE3C390B053732000"
+  "\n\t" "     .quad   0xA080D3F310306343"
+  "\n\t" "     .quad   0xA0CA214B036982E8"
+  "\n\t" "     .quad   0x2F45AEC48CE60D67"
+
+  "\n\t" "##"
+  "\n\t" "##  Decryption stuff"
+  "\n\t" "##  Round function constants"
+  "\n\t" "##"
+  "\n\t" "     # decryption input transform"
+  "\n\t" "     .Lk_dipt = .-.Laes_consts"
+  "\n\t" "     .quad   0x0F505B040B545F00"
+  "\n\t" "     .quad   0x154A411E114E451A"
+  "\n\t" "     .quad   0x86E383E660056500"
+  "\n\t" "     .quad   0x12771772F491F194"
+
+  "\n\t" "     # decryption sbox output *9*u, *9*t"
+  "\n\t" "     .Lk_dsb9 = .-.Laes_consts"
+  "\n\t" "     .quad   0x851C03539A86D600"
+  "\n\t" "     .quad   0xCAD51F504F994CC9"
+  "\n\t" "     .quad   0xC03B1789ECD74900"
+  "\n\t" "     .quad   0x725E2C9EB2FBA565"
+
+  "\n\t" "     # decryption sbox output *D*u, *D*t"
+  "\n\t" "     .Lk_dsbd = .-.Laes_consts"
+  "\n\t" "     .quad   0x7D57CCDFE6B1A200"
+  "\n\t" "     .quad   0xF56E9B13882A4439"
+  "\n\t" "     .quad   0x3CE2FAF724C6CB00"
+  "\n\t" "     .quad   0x2931180D15DEEFD3"
+
+  "\n\t" "     # decryption sbox output *B*u, *B*t"
+  "\n\t" "     .Lk_dsbb = .-.Laes_consts"
+  "\n\t" "     .quad   0xD022649296B44200"
+  "\n\t" "     .quad   0x602646F6B0F2D404"
+  "\n\t" "     .quad   0xC19498A6CD596700"
+  "\n\t" "     .quad   0xF3FF0C3E3255AA6B"
+
+  "\n\t" "     # decryption sbox output *E*u, *E*t"
+  "\n\t" "     .Lk_dsbe = .-.Laes_consts"
+  "\n\t" "     .quad   0x46F2929626D4D000"
+  "\n\t" "     .quad   0x2242600464B4F6B0"
+  "\n\t" "     .quad   0x0C55A6CDFFAAC100"
+  "\n\t" "     .quad   0x9467F36B98593E32"
+
+  "\n\t" "     # decryption sbox final output"
+  "\n\t" "     .Lk_dsbo = .-.Laes_consts"
+  "\n\t" "     .quad   0x1387EA537EF94000"
+  "\n\t" "     .quad   0xC7AA6DB9D4943E2D"
+  "\n\t" "     .quad   0x12D7560F93441D00"
+  "\n\t" "     .quad   0xCA4B8159D8C58E9C"
+X("\n\t" ".size _aes_consts,.-_aes_consts")
+);
+
+#endif /* USE_SSSE3 */
index b6a5b15..8359470 100644 (file)
 /* To keep the actual implementation at a readable size we use this
    include file to define the tables.  */
 
-static const unsigned char S[256] =
+static const u32 encT[256] =
   {
-     99, 124, 119, 123, 242, 107, 111, 197,
-     48,   1, 103,  43, 254, 215, 171, 118,
-    202, 130, 201, 125, 250,  89,  71, 240,
-    173, 212, 162, 175, 156, 164, 114, 192,
-    183, 253, 147,  38,  54,  63, 247, 204,
-     52, 165, 229, 241, 113, 216,  49,  21,
-      4, 199,  35, 195,  24, 150,   5, 154,
-      7,  18, 128, 226, 235,  39, 178, 117,
-      9, 131,  44,  26,  27, 110,  90, 160,
-     82,  59, 214, 179,  41, 227,  47, 132,
-     83, 209,   0, 237,  32, 252, 177,  91,
-    106, 203, 190,  57,  74,  76,  88, 207,
-    208, 239, 170, 251,  67,  77,  51, 133,
-     69, 249,   2, 127,  80,  60, 159, 168,
-     81, 163,  64, 143, 146, 157,  56, 245,
-    188, 182, 218,  33,  16, 255, 243, 210,
-    205,  12,  19, 236,  95, 151,  68,  23,
-    196, 167, 126,  61, 100,  93,  25, 115,
-     96, 129,  79, 220,  34,  42, 144, 136,
-     70, 238, 184,  20, 222,  94,  11, 219,
-    224,  50,  58,  10,  73,   6,  36,  92,
-    194, 211, 172,  98, 145, 149, 228, 121,
-    231, 200,  55, 109, 141, 213,  78, 169,
-    108,  86, 244, 234, 101, 122, 174,   8,
-    186, 120,  37,  46,  28, 166, 180, 198,
-    232, 221, 116,  31,  75, 189, 139, 138,
-    112,  62, 181, 102,  72,   3, 246,  14,
-     97,  53,  87, 185, 134, 193,  29, 158,
-    225, 248, 152,  17, 105, 217, 142, 148,
-    155,  30, 135, 233, 206,  85,  40, 223,
-    140, 161, 137,  13, 191, 230,  66, 104,
-     65, 153,  45,  15, 176,  84, 187,  22
+    0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6,
+    0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591,
+    0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56,
+    0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec,
+    0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa,
+    0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb,
+    0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45,
+    0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b,
+    0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c,
+    0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83,
+    0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9,
+    0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a,
+    0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d,
+    0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f,
+    0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df,
+    0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea,
+    0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34,
+    0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b,
+    0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d,
+    0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413,
+    0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1,
+    0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6,
+    0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972,
+    0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85,
+    0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed,
+    0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511,
+    0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe,
+    0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b,
+    0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05,
+    0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1,
+    0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142,
+    0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf,
+    0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3,
+    0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e,
+    0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a,
+    0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6,
+    0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3,
+    0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b,
+    0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428,
+    0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad,
+    0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14,
+    0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8,
+    0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4,
+    0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2,
+    0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda,
+    0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949,
+    0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf,
+    0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810,
+    0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c,
+    0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697,
+    0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e,
+    0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f,
+    0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc,
+    0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c,
+    0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969,
+    0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27,
+    0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122,
+    0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433,
+    0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9,
+    0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5,
+    0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a,
+    0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0,
+    0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e,
+    0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c
   };
 
-
-static const unsigned char T1[256][4] =
-  {
-    { 0xc6,0x63,0x63,0xa5 }, { 0xf8,0x7c,0x7c,0x84 },
-    { 0xee,0x77,0x77,0x99 }, { 0xf6,0x7b,0x7b,0x8d },
-    { 0xff,0xf2,0xf2,0x0d }, { 0xd6,0x6b,0x6b,0xbd },
-    { 0xde,0x6f,0x6f,0xb1 }, { 0x91,0xc5,0xc5,0x54 },
-    { 0x60,0x30,0x30,0x50 }, { 0x02,0x01,0x01,0x03 },
-    { 0xce,0x67,0x67,0xa9 }, { 0x56,0x2b,0x2b,0x7d },
-    { 0xe7,0xfe,0xfe,0x19 }, { 0xb5,0xd7,0xd7,0x62 },
-    { 0x4d,0xab,0xab,0xe6 }, { 0xec,0x76,0x76,0x9a },
-    { 0x8f,0xca,0xca,0x45 }, { 0x1f,0x82,0x82,0x9d },
-    { 0x89,0xc9,0xc9,0x40 }, { 0xfa,0x7d,0x7d,0x87 },
-    { 0xef,0xfa,0xfa,0x15 }, { 0xb2,0x59,0x59,0xeb },
-    { 0x8e,0x47,0x47,0xc9 }, { 0xfb,0xf0,0xf0,0x0b },
-    { 0x41,0xad,0xad,0xec }, { 0xb3,0xd4,0xd4,0x67 },
-    { 0x5f,0xa2,0xa2,0xfd }, { 0x45,0xaf,0xaf,0xea },
-    { 0x23,0x9c,0x9c,0xbf }, { 0x53,0xa4,0xa4,0xf7 },
-    { 0xe4,0x72,0x72,0x96 }, { 0x9b,0xc0,0xc0,0x5b },
-    { 0x75,0xb7,0xb7,0xc2 }, { 0xe1,0xfd,0xfd,0x1c },
-    { 0x3d,0x93,0x93,0xae }, { 0x4c,0x26,0x26,0x6a },
-    { 0x6c,0x36,0x36,0x5a }, { 0x7e,0x3f,0x3f,0x41 },
-    { 0xf5,0xf7,0xf7,0x02 }, { 0x83,0xcc,0xcc,0x4f },
-    { 0x68,0x34,0x34,0x5c }, { 0x51,0xa5,0xa5,0xf4 },
-    { 0xd1,0xe5,0xe5,0x34 }, { 0xf9,0xf1,0xf1,0x08 },
-    { 0xe2,0x71,0x71,0x93 }, { 0xab,0xd8,0xd8,0x73 },
-    { 0x62,0x31,0x31,0x53 }, { 0x2a,0x15,0x15,0x3f },
-    { 0x08,0x04,0x04,0x0c }, { 0x95,0xc7,0xc7,0x52 },
-    { 0x46,0x23,0x23,0x65 }, { 0x9d,0xc3,0xc3,0x5e },
-    { 0x30,0x18,0x18,0x28 }, { 0x37,0x96,0x96,0xa1 },
-    { 0x0a,0x05,0x05,0x0f }, { 0x2f,0x9a,0x9a,0xb5 },
-    { 0x0e,0x07,0x07,0x09 }, { 0x24,0x12,0x12,0x36 },
-    { 0x1b,0x80,0x80,0x9b }, { 0xdf,0xe2,0xe2,0x3d },
-    { 0xcd,0xeb,0xeb,0x26 }, { 0x4e,0x27,0x27,0x69 },
-    { 0x7f,0xb2,0xb2,0xcd }, { 0xea,0x75,0x75,0x9f },
-    { 0x12,0x09,0x09,0x1b }, { 0x1d,0x83,0x83,0x9e },
-    { 0x58,0x2c,0x2c,0x74 }, { 0x34,0x1a,0x1a,0x2e },
-    { 0x36,0x1b,0x1b,0x2d }, { 0xdc,0x6e,0x6e,0xb2 },
-    { 0xb4,0x5a,0x5a,0xee }, { 0x5b,0xa0,0xa0,0xfb },
-    { 0xa4,0x52,0x52,0xf6 }, { 0x76,0x3b,0x3b,0x4d },
-    { 0xb7,0xd6,0xd6,0x61 }, { 0x7d,0xb3,0xb3,0xce },
-    { 0x52,0x29,0x29,0x7b }, { 0xdd,0xe3,0xe3,0x3e },
-    { 0x5e,0x2f,0x2f,0x71 }, { 0x13,0x84,0x84,0x97 },
-    { 0xa6,0x53,0x53,0xf5 }, { 0xb9,0xd1,0xd1,0x68 },
-    { 0x00,0x00,0x00,0x00 }, { 0xc1,0xed,0xed,0x2c },
-    { 0x40,0x20,0x20,0x60 }, { 0xe3,0xfc,0xfc,0x1f },
-    { 0x79,0xb1,0xb1,0xc8 }, { 0xb6,0x5b,0x5b,0xed },
-    { 0xd4,0x6a,0x6a,0xbe }, { 0x8d,0xcb,0xcb,0x46 },
-    { 0x67,0xbe,0xbe,0xd9 }, { 0x72,0x39,0x39,0x4b },
-    { 0x94,0x4a,0x4a,0xde }, { 0x98,0x4c,0x4c,0xd4 },
-    { 0xb0,0x58,0x58,0xe8 }, { 0x85,0xcf,0xcf,0x4a },
-    { 0xbb,0xd0,0xd0,0x6b }, { 0xc5,0xef,0xef,0x2a },
-    { 0x4f,0xaa,0xaa,0xe5 }, { 0xed,0xfb,0xfb,0x16 },
-    { 0x86,0x43,0x43,0xc5 }, { 0x9a,0x4d,0x4d,0xd7 },
-    { 0x66,0x33,0x33,0x55 }, { 0x11,0x85,0x85,0x94 },
-    { 0x8a,0x45,0x45,0xcf }, { 0xe9,0xf9,0xf9,0x10 },
-    { 0x04,0x02,0x02,0x06 }, { 0xfe,0x7f,0x7f,0x81 },
-    { 0xa0,0x50,0x50,0xf0 }, { 0x78,0x3c,0x3c,0x44 },
-    { 0x25,0x9f,0x9f,0xba }, { 0x4b,0xa8,0xa8,0xe3 },
-    { 0xa2,0x51,0x51,0xf3 }, { 0x5d,0xa3,0xa3,0xfe },
-    { 0x80,0x40,0x40,0xc0 }, { 0x05,0x8f,0x8f,0x8a },
-    { 0x3f,0x92,0x92,0xad }, { 0x21,0x9d,0x9d,0xbc },
-    { 0x70,0x38,0x38,0x48 }, { 0xf1,0xf5,0xf5,0x04 },
-    { 0x63,0xbc,0xbc,0xdf }, { 0x77,0xb6,0xb6,0xc1 },
-    { 0xaf,0xda,0xda,0x75 }, { 0x42,0x21,0x21,0x63 },
-    { 0x20,0x10,0x10,0x30 }, { 0xe5,0xff,0xff,0x1a },
-    { 0xfd,0xf3,0xf3,0x0e }, { 0xbf,0xd2,0xd2,0x6d },
-    { 0x81,0xcd,0xcd,0x4c }, { 0x18,0x0c,0x0c,0x14 },
-    { 0x26,0x13,0x13,0x35 }, { 0xc3,0xec,0xec,0x2f },
-    { 0xbe,0x5f,0x5f,0xe1 }, { 0x35,0x97,0x97,0xa2 },
-    { 0x88,0x44,0x44,0xcc }, { 0x2e,0x17,0x17,0x39 },
-    { 0x93,0xc4,0xc4,0x57 }, { 0x55,0xa7,0xa7,0xf2 },
-    { 0xfc,0x7e,0x7e,0x82 }, { 0x7a,0x3d,0x3d,0x47 },
-    { 0xc8,0x64,0x64,0xac }, { 0xba,0x5d,0x5d,0xe7 },
-    { 0x32,0x19,0x19,0x2b }, { 0xe6,0x73,0x73,0x95 },
-    { 0xc0,0x60,0x60,0xa0 }, { 0x19,0x81,0x81,0x98 },
-    { 0x9e,0x4f,0x4f,0xd1 }, { 0xa3,0xdc,0xdc,0x7f },
-    { 0x44,0x22,0x22,0x66 }, { 0x54,0x2a,0x2a,0x7e },
-    { 0x3b,0x90,0x90,0xab }, { 0x0b,0x88,0x88,0x83 },
-    { 0x8c,0x46,0x46,0xca }, { 0xc7,0xee,0xee,0x29 },
-    { 0x6b,0xb8,0xb8,0xd3 }, { 0x28,0x14,0x14,0x3c },
-    { 0xa7,0xde,0xde,0x79 }, { 0xbc,0x5e,0x5e,0xe2 },
-    { 0x16,0x0b,0x0b,0x1d }, { 0xad,0xdb,0xdb,0x76 },
-    { 0xdb,0xe0,0xe0,0x3b }, { 0x64,0x32,0x32,0x56 },
-    { 0x74,0x3a,0x3a,0x4e }, { 0x14,0x0a,0x0a,0x1e },
-    { 0x92,0x49,0x49,0xdb }, { 0x0c,0x06,0x06,0x0a },
-    { 0x48,0x24,0x24,0x6c }, { 0xb8,0x5c,0x5c,0xe4 },
-    { 0x9f,0xc2,0xc2,0x5d }, { 0xbd,0xd3,0xd3,0x6e },
-    { 0x43,0xac,0xac,0xef }, { 0xc4,0x62,0x62,0xa6 },
-    { 0x39,0x91,0x91,0xa8 }, { 0x31,0x95,0x95,0xa4 },
-    { 0xd3,0xe4,0xe4,0x37 }, { 0xf2,0x79,0x79,0x8b },
-    { 0xd5,0xe7,0xe7,0x32 }, { 0x8b,0xc8,0xc8,0x43 },
-    { 0x6e,0x37,0x37,0x59 }, { 0xda,0x6d,0x6d,0xb7 },
-    { 0x01,0x8d,0x8d,0x8c }, { 0xb1,0xd5,0xd5,0x64 },
-    { 0x9c,0x4e,0x4e,0xd2 }, { 0x49,0xa9,0xa9,0xe0 },
-    { 0xd8,0x6c,0x6c,0xb4 }, { 0xac,0x56,0x56,0xfa },
-    { 0xf3,0xf4,0xf4,0x07 }, { 0xcf,0xea,0xea,0x25 },
-    { 0xca,0x65,0x65,0xaf }, { 0xf4,0x7a,0x7a,0x8e },
-    { 0x47,0xae,0xae,0xe9 }, { 0x10,0x08,0x08,0x18 },
-    { 0x6f,0xba,0xba,0xd5 }, { 0xf0,0x78,0x78,0x88 },
-    { 0x4a,0x25,0x25,0x6f }, { 0x5c,0x2e,0x2e,0x72 },
-    { 0x38,0x1c,0x1c,0x24 }, { 0x57,0xa6,0xa6,0xf1 },
-    { 0x73,0xb4,0xb4,0xc7 }, { 0x97,0xc6,0xc6,0x51 },
-    { 0xcb,0xe8,0xe8,0x23 }, { 0xa1,0xdd,0xdd,0x7c },
-    { 0xe8,0x74,0x74,0x9c }, { 0x3e,0x1f,0x1f,0x21 },
-    { 0x96,0x4b,0x4b,0xdd }, { 0x61,0xbd,0xbd,0xdc },
-    { 0x0d,0x8b,0x8b,0x86 }, { 0x0f,0x8a,0x8a,0x85 },
-    { 0xe0,0x70,0x70,0x90 }, { 0x7c,0x3e,0x3e,0x42 },
-    { 0x71,0xb5,0xb5,0xc4 }, { 0xcc,0x66,0x66,0xaa },
-    { 0x90,0x48,0x48,0xd8 }, { 0x06,0x03,0x03,0x05 },
-    { 0xf7,0xf6,0xf6,0x01 }, { 0x1c,0x0e,0x0e,0x12 },
-    { 0xc2,0x61,0x61,0xa3 }, { 0x6a,0x35,0x35,0x5f },
-    { 0xae,0x57,0x57,0xf9 }, { 0x69,0xb9,0xb9,0xd0 },
-    { 0x17,0x86,0x86,0x91 }, { 0x99,0xc1,0xc1,0x58 },
-    { 0x3a,0x1d,0x1d,0x27 }, { 0x27,0x9e,0x9e,0xb9 },
-    { 0xd9,0xe1,0xe1,0x38 }, { 0xeb,0xf8,0xf8,0x13 },
-    { 0x2b,0x98,0x98,0xb3 }, { 0x22,0x11,0x11,0x33 },
-    { 0xd2,0x69,0x69,0xbb }, { 0xa9,0xd9,0xd9,0x70 },
-    { 0x07,0x8e,0x8e,0x89 }, { 0x33,0x94,0x94,0xa7 },
-    { 0x2d,0x9b,0x9b,0xb6 }, { 0x3c,0x1e,0x1e,0x22 },
-    { 0x15,0x87,0x87,0x92 }, { 0xc9,0xe9,0xe9,0x20 },
-    { 0x87,0xce,0xce,0x49 }, { 0xaa,0x55,0x55,0xff },
-    { 0x50,0x28,0x28,0x78 }, { 0xa5,0xdf,0xdf,0x7a },
-    { 0x03,0x8c,0x8c,0x8f }, { 0x59,0xa1,0xa1,0xf8 },
-    { 0x09,0x89,0x89,0x80 }, { 0x1a,0x0d,0x0d,0x17 },
-    { 0x65,0xbf,0xbf,0xda }, { 0xd7,0xe6,0xe6,0x31 },
-    { 0x84,0x42,0x42,0xc6 }, { 0xd0,0x68,0x68,0xb8 },
-    { 0x82,0x41,0x41,0xc3 }, { 0x29,0x99,0x99,0xb0 },
-    { 0x5a,0x2d,0x2d,0x77 }, { 0x1e,0x0f,0x0f,0x11 },
-    { 0x7b,0xb0,0xb0,0xcb }, { 0xa8,0x54,0x54,0xfc },
-    { 0x6d,0xbb,0xbb,0xd6 }, { 0x2c,0x16,0x16,0x3a }
-  };
-
-static const unsigned char T2[256][4] =
-  {
-    { 0xa5,0xc6,0x63,0x63 }, { 0x84,0xf8,0x7c,0x7c },
-    { 0x99,0xee,0x77,0x77 }, { 0x8d,0xf6,0x7b,0x7b },
-    { 0x0d,0xff,0xf2,0xf2 }, { 0xbd,0xd6,0x6b,0x6b },
-    { 0xb1,0xde,0x6f,0x6f }, { 0x54,0x91,0xc5,0xc5 },
-    { 0x50,0x60,0x30,0x30 }, { 0x03,0x02,0x01,0x01 },
-    { 0xa9,0xce,0x67,0x67 }, { 0x7d,0x56,0x2b,0x2b },
-    { 0x19,0xe7,0xfe,0xfe }, { 0x62,0xb5,0xd7,0xd7 },
-    { 0xe6,0x4d,0xab,0xab }, { 0x9a,0xec,0x76,0x76 },
-    { 0x45,0x8f,0xca,0xca }, { 0x9d,0x1f,0x82,0x82 },
-    { 0x40,0x89,0xc9,0xc9 }, { 0x87,0xfa,0x7d,0x7d },
-    { 0x15,0xef,0xfa,0xfa }, { 0xeb,0xb2,0x59,0x59 },
-    { 0xc9,0x8e,0x47,0x47 }, { 0x0b,0xfb,0xf0,0xf0 },
-    { 0xec,0x41,0xad,0xad }, { 0x67,0xb3,0xd4,0xd4 },
-    { 0xfd,0x5f,0xa2,0xa2 }, { 0xea,0x45,0xaf,0xaf },
-    { 0xbf,0x23,0x9c,0x9c }, { 0xf7,0x53,0xa4,0xa4 },
-    { 0x96,0xe4,0x72,0x72 }, { 0x5b,0x9b,0xc0,0xc0 },
-    { 0xc2,0x75,0xb7,0xb7 }, { 0x1c,0xe1,0xfd,0xfd },
-    { 0xae,0x3d,0x93,0x93 }, { 0x6a,0x4c,0x26,0x26 },
-    { 0x5a,0x6c,0x36,0x36 }, { 0x41,0x7e,0x3f,0x3f },
-    { 0x02,0xf5,0xf7,0xf7 }, { 0x4f,0x83,0xcc,0xcc },
-    { 0x5c,0x68,0x34,0x34 }, { 0xf4,0x51,0xa5,0xa5 },
-    { 0x34,0xd1,0xe5,0xe5 }, { 0x08,0xf9,0xf1,0xf1 },
-    { 0x93,0xe2,0x71,0x71 }, { 0x73,0xab,0xd8,0xd8 },
-    { 0x53,0x62,0x31,0x31 }, { 0x3f,0x2a,0x15,0x15 },
-    { 0x0c,0x08,0x04,0x04 }, { 0x52,0x95,0xc7,0xc7 },
-    { 0x65,0x46,0x23,0x23 }, { 0x5e,0x9d,0xc3,0xc3 },
-    { 0x28,0x30,0x18,0x18 }, { 0xa1,0x37,0x96,0x96 },
-    { 0x0f,0x0a,0x05,0x05 }, { 0xb5,0x2f,0x9a,0x9a },
-    { 0x09,0x0e,0x07,0x07 }, { 0x36,0x24,0x12,0x12 },
-    { 0x9b,0x1b,0x80,0x80 }, { 0x3d,0xdf,0xe2,0xe2 },
-    { 0x26,0xcd,0xeb,0xeb }, { 0x69,0x4e,0x27,0x27 },
-    { 0xcd,0x7f,0xb2,0xb2 }, { 0x9f,0xea,0x75,0x75 },
-    { 0x1b,0x12,0x09,0x09 }, { 0x9e,0x1d,0x83,0x83 },
-    { 0x74,0x58,0x2c,0x2c }, { 0x2e,0x34,0x1a,0x1a },
-    { 0x2d,0x36,0x1b,0x1b }, { 0xb2,0xdc,0x6e,0x6e },
-    { 0xee,0xb4,0x5a,0x5a }, { 0xfb,0x5b,0xa0,0xa0 },
-    { 0xf6,0xa4,0x52,0x52 }, { 0x4d,0x76,0x3b,0x3b },
-    { 0x61,0xb7,0xd6,0xd6 }, { 0xce,0x7d,0xb3,0xb3 },
-    { 0x7b,0x52,0x29,0x29 }, { 0x3e,0xdd,0xe3,0xe3 },
-    { 0x71,0x5e,0x2f,0x2f }, { 0x97,0x13,0x84,0x84 },
-    { 0xf5,0xa6,0x53,0x53 }, { 0x68,0xb9,0xd1,0xd1 },
-    { 0x00,0x00,0x00,0x00 }, { 0x2c,0xc1,0xed,0xed },
-    { 0x60,0x40,0x20,0x20 }, { 0x1f,0xe3,0xfc,0xfc },
-    { 0xc8,0x79,0xb1,0xb1 }, { 0xed,0xb6,0x5b,0x5b },
-    { 0xbe,0xd4,0x6a,0x6a }, { 0x46,0x8d,0xcb,0xcb },
-    { 0xd9,0x67,0xbe,0xbe }, { 0x4b,0x72,0x39,0x39 },
-    { 0xde,0x94,0x4a,0x4a }, { 0xd4,0x98,0x4c,0x4c },
-    { 0xe8,0xb0,0x58,0x58 }, { 0x4a,0x85,0xcf,0xcf },
-    { 0x6b,0xbb,0xd0,0xd0 }, { 0x2a,0xc5,0xef,0xef },
-    { 0xe5,0x4f,0xaa,0xaa }, { 0x16,0xed,0xfb,0xfb },
-    { 0xc5,0x86,0x43,0x43 }, { 0xd7,0x9a,0x4d,0x4d },
-    { 0x55,0x66,0x33,0x33 }, { 0x94,0x11,0x85,0x85 },
-    { 0xcf,0x8a,0x45,0x45 }, { 0x10,0xe9,0xf9,0xf9 },
-    { 0x06,0x04,0x02,0x02 }, { 0x81,0xfe,0x7f,0x7f },
-    { 0xf0,0xa0,0x50,0x50 }, { 0x44,0x78,0x3c,0x3c },
-    { 0xba,0x25,0x9f,0x9f }, { 0xe3,0x4b,0xa8,0xa8 },
-    { 0xf3,0xa2,0x51,0x51 }, { 0xfe,0x5d,0xa3,0xa3 },
-    { 0xc0,0x80,0x40,0x40 }, { 0x8a,0x05,0x8f,0x8f },
-    { 0xad,0x3f,0x92,0x92 }, { 0xbc,0x21,0x9d,0x9d },
-    { 0x48,0x70,0x38,0x38 }, { 0x04,0xf1,0xf5,0xf5 },
-    { 0xdf,0x63,0xbc,0xbc }, { 0xc1,0x77,0xb6,0xb6 },
-    { 0x75,0xaf,0xda,0xda }, { 0x63,0x42,0x21,0x21 },
-    { 0x30,0x20,0x10,0x10 }, { 0x1a,0xe5,0xff,0xff },
-    { 0x0e,0xfd,0xf3,0xf3 }, { 0x6d,0xbf,0xd2,0xd2 },
-    { 0x4c,0x81,0xcd,0xcd }, { 0x14,0x18,0x0c,0x0c },
-    { 0x35,0x26,0x13,0x13 }, { 0x2f,0xc3,0xec,0xec },
-    { 0xe1,0xbe,0x5f,0x5f }, { 0xa2,0x35,0x97,0x97 },
-    { 0xcc,0x88,0x44,0x44 }, { 0x39,0x2e,0x17,0x17 },
-    { 0x57,0x93,0xc4,0xc4 }, { 0xf2,0x55,0xa7,0xa7 },
-    { 0x82,0xfc,0x7e,0x7e }, { 0x47,0x7a,0x3d,0x3d },
-    { 0xac,0xc8,0x64,0x64 }, { 0xe7,0xba,0x5d,0x5d },
-    { 0x2b,0x32,0x19,0x19 }, { 0x95,0xe6,0x73,0x73 },
-    { 0xa0,0xc0,0x60,0x60 }, { 0x98,0x19,0x81,0x81 },
-    { 0xd1,0x9e,0x4f,0x4f }, { 0x7f,0xa3,0xdc,0xdc },
-    { 0x66,0x44,0x22,0x22 }, { 0x7e,0x54,0x2a,0x2a },
-    { 0xab,0x3b,0x90,0x90 }, { 0x83,0x0b,0x88,0x88 },
-    { 0xca,0x8c,0x46,0x46 }, { 0x29,0xc7,0xee,0xee },
-    { 0xd3,0x6b,0xb8,0xb8 }, { 0x3c,0x28,0x14,0x14 },
-    { 0x79,0xa7,0xde,0xde }, { 0xe2,0xbc,0x5e,0x5e },
-    { 0x1d,0x16,0x0b,0x0b }, { 0x76,0xad,0xdb,0xdb },
-    { 0x3b,0xdb,0xe0,0xe0 }, { 0x56,0x64,0x32,0x32 },
-    { 0x4e,0x74,0x3a,0x3a }, { 0x1e,0x14,0x0a,0x0a },
-    { 0xdb,0x92,0x49,0x49 }, { 0x0a,0x0c,0x06,0x06 },
-    { 0x6c,0x48,0x24,0x24 }, { 0xe4,0xb8,0x5c,0x5c },
-    { 0x5d,0x9f,0xc2,0xc2 }, { 0x6e,0xbd,0xd3,0xd3 },
-    { 0xef,0x43,0xac,0xac }, { 0xa6,0xc4,0x62,0x62 },
-    { 0xa8,0x39,0x91,0x91 }, { 0xa4,0x31,0x95,0x95 },
-    { 0x37,0xd3,0xe4,0xe4 }, { 0x8b,0xf2,0x79,0x79 },
-    { 0x32,0xd5,0xe7,0xe7 }, { 0x43,0x8b,0xc8,0xc8 },
-    { 0x59,0x6e,0x37,0x37 }, { 0xb7,0xda,0x6d,0x6d },
-    { 0x8c,0x01,0x8d,0x8d }, { 0x64,0xb1,0xd5,0xd5 },
-    { 0xd2,0x9c,0x4e,0x4e }, { 0xe0,0x49,0xa9,0xa9 },
-    { 0xb4,0xd8,0x6c,0x6c }, { 0xfa,0xac,0x56,0x56 },
-    { 0x07,0xf3,0xf4,0xf4 }, { 0x25,0xcf,0xea,0xea },
-    { 0xaf,0xca,0x65,0x65 }, { 0x8e,0xf4,0x7a,0x7a },
-    { 0xe9,0x47,0xae,0xae }, { 0x18,0x10,0x08,0x08 },
-    { 0xd5,0x6f,0xba,0xba }, { 0x88,0xf0,0x78,0x78 },
-    { 0x6f,0x4a,0x25,0x25 }, { 0x72,0x5c,0x2e,0x2e },
-    { 0x24,0x38,0x1c,0x1c }, { 0xf1,0x57,0xa6,0xa6 },
-    { 0xc7,0x73,0xb4,0xb4 }, { 0x51,0x97,0xc6,0xc6 },
-    { 0x23,0xcb,0xe8,0xe8 }, { 0x7c,0xa1,0xdd,0xdd },
-    { 0x9c,0xe8,0x74,0x74 }, { 0x21,0x3e,0x1f,0x1f },
-    { 0xdd,0x96,0x4b,0x4b }, { 0xdc,0x61,0xbd,0xbd },
-    { 0x86,0x0d,0x8b,0x8b }, { 0x85,0x0f,0x8a,0x8a },
-    { 0x90,0xe0,0x70,0x70 }, { 0x42,0x7c,0x3e,0x3e },
-    { 0xc4,0x71,0xb5,0xb5 }, { 0xaa,0xcc,0x66,0x66 },
-    { 0xd8,0x90,0x48,0x48 }, { 0x05,0x06,0x03,0x03 },
-    { 0x01,0xf7,0xf6,0xf6 }, { 0x12,0x1c,0x0e,0x0e },
-    { 0xa3,0xc2,0x61,0x61 }, { 0x5f,0x6a,0x35,0x35 },
-    { 0xf9,0xae,0x57,0x57 }, { 0xd0,0x69,0xb9,0xb9 },
-    { 0x91,0x17,0x86,0x86 }, { 0x58,0x99,0xc1,0xc1 },
-    { 0x27,0x3a,0x1d,0x1d }, { 0xb9,0x27,0x9e,0x9e },
-    { 0x38,0xd9,0xe1,0xe1 }, { 0x13,0xeb,0xf8,0xf8 },
-    { 0xb3,0x2b,0x98,0x98 }, { 0x33,0x22,0x11,0x11 },
-    { 0xbb,0xd2,0x69,0x69 }, { 0x70,0xa9,0xd9,0xd9 },
-    { 0x89,0x07,0x8e,0x8e }, { 0xa7,0x33,0x94,0x94 },
-    { 0xb6,0x2d,0x9b,0x9b }, { 0x22,0x3c,0x1e,0x1e },
-    { 0x92,0x15,0x87,0x87 }, { 0x20,0xc9,0xe9,0xe9 },
-    { 0x49,0x87,0xce,0xce }, { 0xff,0xaa,0x55,0x55 },
-    { 0x78,0x50,0x28,0x28 }, { 0x7a,0xa5,0xdf,0xdf },
-    { 0x8f,0x03,0x8c,0x8c }, { 0xf8,0x59,0xa1,0xa1 },
-    { 0x80,0x09,0x89,0x89 }, { 0x17,0x1a,0x0d,0x0d },
-    { 0xda,0x65,0xbf,0xbf }, { 0x31,0xd7,0xe6,0xe6 },
-    { 0xc6,0x84,0x42,0x42 }, { 0xb8,0xd0,0x68,0x68 },
-    { 0xc3,0x82,0x41,0x41 }, { 0xb0,0x29,0x99,0x99 },
-    { 0x77,0x5a,0x2d,0x2d }, { 0x11,0x1e,0x0f,0x0f },
-    { 0xcb,0x7b,0xb0,0xb0 }, { 0xfc,0xa8,0x54,0x54 },
-    { 0xd6,0x6d,0xbb,0xbb }, { 0x3a,0x2c,0x16,0x16 }
-  };
-
-static const unsigned char T3[256][4] =
-  {
-    { 0x63,0xa5,0xc6,0x63 }, { 0x7c,0x84,0xf8,0x7c },
-    { 0x77,0x99,0xee,0x77 }, { 0x7b,0x8d,0xf6,0x7b },
-    { 0xf2,0x0d,0xff,0xf2 }, { 0x6b,0xbd,0xd6,0x6b },
-    { 0x6f,0xb1,0xde,0x6f }, { 0xc5,0x54,0x91,0xc5 },
-    { 0x30,0x50,0x60,0x30 }, { 0x01,0x03,0x02,0x01 },
-    { 0x67,0xa9,0xce,0x67 }, { 0x2b,0x7d,0x56,0x2b },
-    { 0xfe,0x19,0xe7,0xfe }, { 0xd7,0x62,0xb5,0xd7 },
-    { 0xab,0xe6,0x4d,0xab }, { 0x76,0x9a,0xec,0x76 },
-    { 0xca,0x45,0x8f,0xca }, { 0x82,0x9d,0x1f,0x82 },
-    { 0xc9,0x40,0x89,0xc9 }, { 0x7d,0x87,0xfa,0x7d },
-    { 0xfa,0x15,0xef,0xfa }, { 0x59,0xeb,0xb2,0x59 },
-    { 0x47,0xc9,0x8e,0x47 }, { 0xf0,0x0b,0xfb,0xf0 },
-    { 0xad,0xec,0x41,0xad }, { 0xd4,0x67,0xb3,0xd4 },
-    { 0xa2,0xfd,0x5f,0xa2 }, { 0xaf,0xea,0x45,0xaf },
-    { 0x9c,0xbf,0x23,0x9c }, { 0xa4,0xf7,0x53,0xa4 },
-    { 0x72,0x96,0xe4,0x72 }, { 0xc0,0x5b,0x9b,0xc0 },
-    { 0xb7,0xc2,0x75,0xb7 }, { 0xfd,0x1c,0xe1,0xfd },
-    { 0x93,0xae,0x3d,0x93 }, { 0x26,0x6a,0x4c,0x26 },
-    { 0x36,0x5a,0x6c,0x36 }, { 0x3f,0x41,0x7e,0x3f },
-    { 0xf7,0x02,0xf5,0xf7 }, { 0xcc,0x4f,0x83,0xcc },
-    { 0x34,0x5c,0x68,0x34 }, { 0xa5,0xf4,0x51,0xa5 },
-    { 0xe5,0x34,0xd1,0xe5 }, { 0xf1,0x08,0xf9,0xf1 },
-    { 0x71,0x93,0xe2,0x71 }, { 0xd8,0x73,0xab,0xd8 },
-    { 0x31,0x53,0x62,0x31 }, { 0x15,0x3f,0x2a,0x15 },
-    { 0x04,0x0c,0x08,0x04 }, { 0xc7,0x52,0x95,0xc7 },
-    { 0x23,0x65,0x46,0x23 }, { 0xc3,0x5e,0x9d,0xc3 },
-    { 0x18,0x28,0x30,0x18 }, { 0x96,0xa1,0x37,0x96 },
-    { 0x05,0x0f,0x0a,0x05 }, { 0x9a,0xb5,0x2f,0x9a },
-    { 0x07,0x09,0x0e,0x07 }, { 0x12,0x36,0x24,0x12 },
-    { 0x80,0x9b,0x1b,0x80 }, { 0xe2,0x3d,0xdf,0xe2 },
-    { 0xeb,0x26,0xcd,0xeb }, { 0x27,0x69,0x4e,0x27 },
-    { 0xb2,0xcd,0x7f,0xb2 }, { 0x75,0x9f,0xea,0x75 },
-    { 0x09,0x1b,0x12,0x09 }, { 0x83,0x9e,0x1d,0x83 },
-    { 0x2c,0x74,0x58,0x2c }, { 0x1a,0x2e,0x34,0x1a },
-    { 0x1b,0x2d,0x36,0x1b }, { 0x6e,0xb2,0xdc,0x6e },
-    { 0x5a,0xee,0xb4,0x5a }, { 0xa0,0xfb,0x5b,0xa0 },
-    { 0x52,0xf6,0xa4,0x52 }, { 0x3b,0x4d,0x76,0x3b },
-    { 0xd6,0x61,0xb7,0xd6 }, { 0xb3,0xce,0x7d,0xb3 },
-    { 0x29,0x7b,0x52,0x29 }, { 0xe3,0x3e,0xdd,0xe3 },
-    { 0x2f,0x71,0x5e,0x2f }, { 0x84,0x97,0x13,0x84 },
-    { 0x53,0xf5,0xa6,0x53 }, { 0xd1,0x68,0xb9,0xd1 },
-    { 0x00,0x00,0x00,0x00 }, { 0xed,0x2c,0xc1,0xed },
-    { 0x20,0x60,0x40,0x20 }, { 0xfc,0x1f,0xe3,0xfc },
-    { 0xb1,0xc8,0x79,0xb1 }, { 0x5b,0xed,0xb6,0x5b },
-    { 0x6a,0xbe,0xd4,0x6a }, { 0xcb,0x46,0x8d,0xcb },
-    { 0xbe,0xd9,0x67,0xbe }, { 0x39,0x4b,0x72,0x39 },
-    { 0x4a,0xde,0x94,0x4a }, { 0x4c,0xd4,0x98,0x4c },
-    { 0x58,0xe8,0xb0,0x58 }, { 0xcf,0x4a,0x85,0xcf },
-    { 0xd0,0x6b,0xbb,0xd0 }, { 0xef,0x2a,0xc5,0xef },
-    { 0xaa,0xe5,0x4f,0xaa }, { 0xfb,0x16,0xed,0xfb },
-    { 0x43,0xc5,0x86,0x43 }, { 0x4d,0xd7,0x9a,0x4d },
-    { 0x33,0x55,0x66,0x33 }, { 0x85,0x94,0x11,0x85 },
-    { 0x45,0xcf,0x8a,0x45 }, { 0xf9,0x10,0xe9,0xf9 },
-    { 0x02,0x06,0x04,0x02 }, { 0x7f,0x81,0xfe,0x7f },
-    { 0x50,0xf0,0xa0,0x50 }, { 0x3c,0x44,0x78,0x3c },
-    { 0x9f,0xba,0x25,0x9f }, { 0xa8,0xe3,0x4b,0xa8 },
-    { 0x51,0xf3,0xa2,0x51 }, { 0xa3,0xfe,0x5d,0xa3 },
-    { 0x40,0xc0,0x80,0x40 }, { 0x8f,0x8a,0x05,0x8f },
-    { 0x92,0xad,0x3f,0x92 }, { 0x9d,0xbc,0x21,0x9d },
-    { 0x38,0x48,0x70,0x38 }, { 0xf5,0x04,0xf1,0xf5 },
-    { 0xbc,0xdf,0x63,0xbc }, { 0xb6,0xc1,0x77,0xb6 },
-    { 0xda,0x75,0xaf,0xda }, { 0x21,0x63,0x42,0x21 },
-    { 0x10,0x30,0x20,0x10 }, { 0xff,0x1a,0xe5,0xff },
-    { 0xf3,0x0e,0xfd,0xf3 }, { 0xd2,0x6d,0xbf,0xd2 },
-    { 0xcd,0x4c,0x81,0xcd }, { 0x0c,0x14,0x18,0x0c },
-    { 0x13,0x35,0x26,0x13 }, { 0xec,0x2f,0xc3,0xec },
-    { 0x5f,0xe1,0xbe,0x5f }, { 0x97,0xa2,0x35,0x97 },
-    { 0x44,0xcc,0x88,0x44 }, { 0x17,0x39,0x2e,0x17 },
-    { 0xc4,0x57,0x93,0xc4 }, { 0xa7,0xf2,0x55,0xa7 },
-    { 0x7e,0x82,0xfc,0x7e }, { 0x3d,0x47,0x7a,0x3d },
-    { 0x64,0xac,0xc8,0x64 }, { 0x5d,0xe7,0xba,0x5d },
-    { 0x19,0x2b,0x32,0x19 }, { 0x73,0x95,0xe6,0x73 },
-    { 0x60,0xa0,0xc0,0x60 }, { 0x81,0x98,0x19,0x81 },
-    { 0x4f,0xd1,0x9e,0x4f }, { 0xdc,0x7f,0xa3,0xdc },
-    { 0x22,0x66,0x44,0x22 }, { 0x2a,0x7e,0x54,0x2a },
-    { 0x90,0xab,0x3b,0x90 }, { 0x88,0x83,0x0b,0x88 },
-    { 0x46,0xca,0x8c,0x46 }, { 0xee,0x29,0xc7,0xee },
-    { 0xb8,0xd3,0x6b,0xb8 }, { 0x14,0x3c,0x28,0x14 },
-    { 0xde,0x79,0xa7,0xde }, { 0x5e,0xe2,0xbc,0x5e },
-    { 0x0b,0x1d,0x16,0x0b }, { 0xdb,0x76,0xad,0xdb },
-    { 0xe0,0x3b,0xdb,0xe0 }, { 0x32,0x56,0x64,0x32 },
-    { 0x3a,0x4e,0x74,0x3a }, { 0x0a,0x1e,0x14,0x0a },
-    { 0x49,0xdb,0x92,0x49 }, { 0x06,0x0a,0x0c,0x06 },
-    { 0x24,0x6c,0x48,0x24 }, { 0x5c,0xe4,0xb8,0x5c },
-    { 0xc2,0x5d,0x9f,0xc2 }, { 0xd3,0x6e,0xbd,0xd3 },
-    { 0xac,0xef,0x43,0xac }, { 0x62,0xa6,0xc4,0x62 },
-    { 0x91,0xa8,0x39,0x91 }, { 0x95,0xa4,0x31,0x95 },
-    { 0xe4,0x37,0xd3,0xe4 }, { 0x79,0x8b,0xf2,0x79 },
-    { 0xe7,0x32,0xd5,0xe7 }, { 0xc8,0x43,0x8b,0xc8 },
-    { 0x37,0x59,0x6e,0x37 }, { 0x6d,0xb7,0xda,0x6d },
-    { 0x8d,0x8c,0x01,0x8d }, { 0xd5,0x64,0xb1,0xd5 },
-    { 0x4e,0xd2,0x9c,0x4e }, { 0xa9,0xe0,0x49,0xa9 },
-    { 0x6c,0xb4,0xd8,0x6c }, { 0x56,0xfa,0xac,0x56 },
-    { 0xf4,0x07,0xf3,0xf4 }, { 0xea,0x25,0xcf,0xea },
-    { 0x65,0xaf,0xca,0x65 }, { 0x7a,0x8e,0xf4,0x7a },
-    { 0xae,0xe9,0x47,0xae }, { 0x08,0x18,0x10,0x08 },
-    { 0xba,0xd5,0x6f,0xba }, { 0x78,0x88,0xf0,0x78 },
-    { 0x25,0x6f,0x4a,0x25 }, { 0x2e,0x72,0x5c,0x2e },
-    { 0x1c,0x24,0x38,0x1c }, { 0xa6,0xf1,0x57,0xa6 },
-    { 0xb4,0xc7,0x73,0xb4 }, { 0xc6,0x51,0x97,0xc6 },
-    { 0xe8,0x23,0xcb,0xe8 }, { 0xdd,0x7c,0xa1,0xdd },
-    { 0x74,0x9c,0xe8,0x74 }, { 0x1f,0x21,0x3e,0x1f },
-    { 0x4b,0xdd,0x96,0x4b }, { 0xbd,0xdc,0x61,0xbd },
-    { 0x8b,0x86,0x0d,0x8b }, { 0x8a,0x85,0x0f,0x8a },
-    { 0x70,0x90,0xe0,0x70 }, { 0x3e,0x42,0x7c,0x3e },
-    { 0xb5,0xc4,0x71,0xb5 }, { 0x66,0xaa,0xcc,0x66 },
-    { 0x48,0xd8,0x90,0x48 }, { 0x03,0x05,0x06,0x03 },
-    { 0xf6,0x01,0xf7,0xf6 }, { 0x0e,0x12,0x1c,0x0e },
-    { 0x61,0xa3,0xc2,0x61 }, { 0x35,0x5f,0x6a,0x35 },
-    { 0x57,0xf9,0xae,0x57 }, { 0xb9,0xd0,0x69,0xb9 },
-    { 0x86,0x91,0x17,0x86 }, { 0xc1,0x58,0x99,0xc1 },
-    { 0x1d,0x27,0x3a,0x1d }, { 0x9e,0xb9,0x27,0x9e },
-    { 0xe1,0x38,0xd9,0xe1 }, { 0xf8,0x13,0xeb,0xf8 },
-    { 0x98,0xb3,0x2b,0x98 }, { 0x11,0x33,0x22,0x11 },
-    { 0x69,0xbb,0xd2,0x69 }, { 0xd9,0x70,0xa9,0xd9 },
-    { 0x8e,0x89,0x07,0x8e }, { 0x94,0xa7,0x33,0x94 },
-    { 0x9b,0xb6,0x2d,0x9b }, { 0x1e,0x22,0x3c,0x1e },
-    { 0x87,0x92,0x15,0x87 }, { 0xe9,0x20,0xc9,0xe9 },
-    { 0xce,0x49,0x87,0xce }, { 0x55,0xff,0xaa,0x55 },
-    { 0x28,0x78,0x50,0x28 }, { 0xdf,0x7a,0xa5,0xdf },
-    { 0x8c,0x8f,0x03,0x8c }, { 0xa1,0xf8,0x59,0xa1 },
-    { 0x89,0x80,0x09,0x89 }, { 0x0d,0x17,0x1a,0x0d },
-    { 0xbf,0xda,0x65,0xbf }, { 0xe6,0x31,0xd7,0xe6 },
-    { 0x42,0xc6,0x84,0x42 }, { 0x68,0xb8,0xd0,0x68 },
-    { 0x41,0xc3,0x82,0x41 }, { 0x99,0xb0,0x29,0x99 },
-    { 0x2d,0x77,0x5a,0x2d }, { 0x0f,0x11,0x1e,0x0f },
-    { 0xb0,0xcb,0x7b,0xb0 }, { 0x54,0xfc,0xa8,0x54 },
-    { 0xbb,0xd6,0x6d,0xbb }, { 0x16,0x3a,0x2c,0x16 }
-  };
-
-static const unsigned char T4[256][4] =
-  {
-    { 0x63,0x63,0xa5,0xc6 }, { 0x7c,0x7c,0x84,0xf8 },
-    { 0x77,0x77,0x99,0xee }, { 0x7b,0x7b,0x8d,0xf6 },
-    { 0xf2,0xf2,0x0d,0xff }, { 0x6b,0x6b,0xbd,0xd6 },
-    { 0x6f,0x6f,0xb1,0xde }, { 0xc5,0xc5,0x54,0x91 },
-    { 0x30,0x30,0x50,0x60 }, { 0x01,0x01,0x03,0x02 },
-    { 0x67,0x67,0xa9,0xce }, { 0x2b,0x2b,0x7d,0x56 },
-    { 0xfe,0xfe,0x19,0xe7 }, { 0xd7,0xd7,0x62,0xb5 },
-    { 0xab,0xab,0xe6,0x4d }, { 0x76,0x76,0x9a,0xec },
-    { 0xca,0xca,0x45,0x8f }, { 0x82,0x82,0x9d,0x1f },
-    { 0xc9,0xc9,0x40,0x89 }, { 0x7d,0x7d,0x87,0xfa },
-    { 0xfa,0xfa,0x15,0xef }, { 0x59,0x59,0xeb,0xb2 },
-    { 0x47,0x47,0xc9,0x8e }, { 0xf0,0xf0,0x0b,0xfb },
-    { 0xad,0xad,0xec,0x41 }, { 0xd4,0xd4,0x67,0xb3 },
-    { 0xa2,0xa2,0xfd,0x5f }, { 0xaf,0xaf,0xea,0x45 },
-    { 0x9c,0x9c,0xbf,0x23 }, { 0xa4,0xa4,0xf7,0x53 },
-    { 0x72,0x72,0x96,0xe4 }, { 0xc0,0xc0,0x5b,0x9b },
-    { 0xb7,0xb7,0xc2,0x75 }, { 0xfd,0xfd,0x1c,0xe1 },
-    { 0x93,0x93,0xae,0x3d }, { 0x26,0x26,0x6a,0x4c },
-    { 0x36,0x36,0x5a,0x6c }, { 0x3f,0x3f,0x41,0x7e },
-    { 0xf7,0xf7,0x02,0xf5 }, { 0xcc,0xcc,0x4f,0x83 },
-    { 0x34,0x34,0x5c,0x68 }, { 0xa5,0xa5,0xf4,0x51 },
-    { 0xe5,0xe5,0x34,0xd1 }, { 0xf1,0xf1,0x08,0xf9 },
-    { 0x71,0x71,0x93,0xe2 }, { 0xd8,0xd8,0x73,0xab },
-    { 0x31,0x31,0x53,0x62 }, { 0x15,0x15,0x3f,0x2a },
-    { 0x04,0x04,0x0c,0x08 }, { 0xc7,0xc7,0x52,0x95 },
-    { 0x23,0x23,0x65,0x46 }, { 0xc3,0xc3,0x5e,0x9d },
-    { 0x18,0x18,0x28,0x30 }, { 0x96,0x96,0xa1,0x37 },
-    { 0x05,0x05,0x0f,0x0a }, { 0x9a,0x9a,0xb5,0x2f },
-    { 0x07,0x07,0x09,0x0e }, { 0x12,0x12,0x36,0x24 },
-    { 0x80,0x80,0x9b,0x1b }, { 0xe2,0xe2,0x3d,0xdf },
-    { 0xeb,0xeb,0x26,0xcd }, { 0x27,0x27,0x69,0x4e },
-    { 0xb2,0xb2,0xcd,0x7f }, { 0x75,0x75,0x9f,0xea },
-    { 0x09,0x09,0x1b,0x12 }, { 0x83,0x83,0x9e,0x1d },
-    { 0x2c,0x2c,0x74,0x58 }, { 0x1a,0x1a,0x2e,0x34 },
-    { 0x1b,0x1b,0x2d,0x36 }, { 0x6e,0x6e,0xb2,0xdc },
-    { 0x5a,0x5a,0xee,0xb4 }, { 0xa0,0xa0,0xfb,0x5b },
-    { 0x52,0x52,0xf6,0xa4 }, { 0x3b,0x3b,0x4d,0x76 },
-    { 0xd6,0xd6,0x61,0xb7 }, { 0xb3,0xb3,0xce,0x7d },
-    { 0x29,0x29,0x7b,0x52 }, { 0xe3,0xe3,0x3e,0xdd },
-    { 0x2f,0x2f,0x71,0x5e }, { 0x84,0x84,0x97,0x13 },
-    { 0x53,0x53,0xf5,0xa6 }, { 0xd1,0xd1,0x68,0xb9 },
-    { 0x00,0x00,0x00,0x00 }, { 0xed,0xed,0x2c,0xc1 },
-    { 0x20,0x20,0x60,0x40 }, { 0xfc,0xfc,0x1f,0xe3 },
-    { 0xb1,0xb1,0xc8,0x79 }, { 0x5b,0x5b,0xed,0xb6 },
-    { 0x6a,0x6a,0xbe,0xd4 }, { 0xcb,0xcb,0x46,0x8d },
-    { 0xbe,0xbe,0xd9,0x67 }, { 0x39,0x39,0x4b,0x72 },
-    { 0x4a,0x4a,0xde,0x94 }, { 0x4c,0x4c,0xd4,0x98 },
-    { 0x58,0x58,0xe8,0xb0 }, { 0xcf,0xcf,0x4a,0x85 },
-    { 0xd0,0xd0,0x6b,0xbb }, { 0xef,0xef,0x2a,0xc5 },
-    { 0xaa,0xaa,0xe5,0x4f }, { 0xfb,0xfb,0x16,0xed },
-    { 0x43,0x43,0xc5,0x86 }, { 0x4d,0x4d,0xd7,0x9a },
-    { 0x33,0x33,0x55,0x66 }, { 0x85,0x85,0x94,0x11 },
-    { 0x45,0x45,0xcf,0x8a }, { 0xf9,0xf9,0x10,0xe9 },
-    { 0x02,0x02,0x06,0x04 }, { 0x7f,0x7f,0x81,0xfe },
-    { 0x50,0x50,0xf0,0xa0 }, { 0x3c,0x3c,0x44,0x78 },
-    { 0x9f,0x9f,0xba,0x25 }, { 0xa8,0xa8,0xe3,0x4b },
-    { 0x51,0x51,0xf3,0xa2 }, { 0xa3,0xa3,0xfe,0x5d },
-    { 0x40,0x40,0xc0,0x80 }, { 0x8f,0x8f,0x8a,0x05 },
-    { 0x92,0x92,0xad,0x3f }, { 0x9d,0x9d,0xbc,0x21 },
-    { 0x38,0x38,0x48,0x70 }, { 0xf5,0xf5,0x04,0xf1 },
-    { 0xbc,0xbc,0xdf,0x63 }, { 0xb6,0xb6,0xc1,0x77 },
-    { 0xda,0xda,0x75,0xaf }, { 0x21,0x21,0x63,0x42 },
-    { 0x10,0x10,0x30,0x20 }, { 0xff,0xff,0x1a,0xe5 },
-    { 0xf3,0xf3,0x0e,0xfd }, { 0xd2,0xd2,0x6d,0xbf },
-    { 0xcd,0xcd,0x4c,0x81 }, { 0x0c,0x0c,0x14,0x18 },
-    { 0x13,0x13,0x35,0x26 }, { 0xec,0xec,0x2f,0xc3 },
-    { 0x5f,0x5f,0xe1,0xbe }, { 0x97,0x97,0xa2,0x35 },
-    { 0x44,0x44,0xcc,0x88 }, { 0x17,0x17,0x39,0x2e },
-    { 0xc4,0xc4,0x57,0x93 }, { 0xa7,0xa7,0xf2,0x55 },
-    { 0x7e,0x7e,0x82,0xfc }, { 0x3d,0x3d,0x47,0x7a },
-    { 0x64,0x64,0xac,0xc8 }, { 0x5d,0x5d,0xe7,0xba },
-    { 0x19,0x19,0x2b,0x32 }, { 0x73,0x73,0x95,0xe6 },
-    { 0x60,0x60,0xa0,0xc0 }, { 0x81,0x81,0x98,0x19 },
-    { 0x4f,0x4f,0xd1,0x9e }, { 0xdc,0xdc,0x7f,0xa3 },
-    { 0x22,0x22,0x66,0x44 }, { 0x2a,0x2a,0x7e,0x54 },
-    { 0x90,0x90,0xab,0x3b }, { 0x88,0x88,0x83,0x0b },
-    { 0x46,0x46,0xca,0x8c }, { 0xee,0xee,0x29,0xc7 },
-    { 0xb8,0xb8,0xd3,0x6b }, { 0x14,0x14,0x3c,0x28 },
-    { 0xde,0xde,0x79,0xa7 }, { 0x5e,0x5e,0xe2,0xbc },
-    { 0x0b,0x0b,0x1d,0x16 }, { 0xdb,0xdb,0x76,0xad },
-    { 0xe0,0xe0,0x3b,0xdb }, { 0x32,0x32,0x56,0x64 },
-    { 0x3a,0x3a,0x4e,0x74 }, { 0x0a,0x0a,0x1e,0x14 },
-    { 0x49,0x49,0xdb,0x92 }, { 0x06,0x06,0x0a,0x0c },
-    { 0x24,0x24,0x6c,0x48 }, { 0x5c,0x5c,0xe4,0xb8 },
-    { 0xc2,0xc2,0x5d,0x9f }, { 0xd3,0xd3,0x6e,0xbd },
-    { 0xac,0xac,0xef,0x43 }, { 0x62,0x62,0xa6,0xc4 },
-    { 0x91,0x91,0xa8,0x39 }, { 0x95,0x95,0xa4,0x31 },
-    { 0xe4,0xe4,0x37,0xd3 }, { 0x79,0x79,0x8b,0xf2 },
-    { 0xe7,0xe7,0x32,0xd5 }, { 0xc8,0xc8,0x43,0x8b },
-    { 0x37,0x37,0x59,0x6e }, { 0x6d,0x6d,0xb7,0xda },
-    { 0x8d,0x8d,0x8c,0x01 }, { 0xd5,0xd5,0x64,0xb1 },
-    { 0x4e,0x4e,0xd2,0x9c }, { 0xa9,0xa9,0xe0,0x49 },
-    { 0x6c,0x6c,0xb4,0xd8 }, { 0x56,0x56,0xfa,0xac },
-    { 0xf4,0xf4,0x07,0xf3 }, { 0xea,0xea,0x25,0xcf },
-    { 0x65,0x65,0xaf,0xca }, { 0x7a,0x7a,0x8e,0xf4 },
-    { 0xae,0xae,0xe9,0x47 }, { 0x08,0x08,0x18,0x10 },
-    { 0xba,0xba,0xd5,0x6f }, { 0x78,0x78,0x88,0xf0 },
-    { 0x25,0x25,0x6f,0x4a }, { 0x2e,0x2e,0x72,0x5c },
-    { 0x1c,0x1c,0x24,0x38 }, { 0xa6,0xa6,0xf1,0x57 },
-    { 0xb4,0xb4,0xc7,0x73 }, { 0xc6,0xc6,0x51,0x97 },
-    { 0xe8,0xe8,0x23,0xcb }, { 0xdd,0xdd,0x7c,0xa1 },
-    { 0x74,0x74,0x9c,0xe8 }, { 0x1f,0x1f,0x21,0x3e },
-    { 0x4b,0x4b,0xdd,0x96 }, { 0xbd,0xbd,0xdc,0x61 },
-    { 0x8b,0x8b,0x86,0x0d }, { 0x8a,0x8a,0x85,0x0f },
-    { 0x70,0x70,0x90,0xe0 }, { 0x3e,0x3e,0x42,0x7c },
-    { 0xb5,0xb5,0xc4,0x71 }, { 0x66,0x66,0xaa,0xcc },
-    { 0x48,0x48,0xd8,0x90 }, { 0x03,0x03,0x05,0x06 },
-    { 0xf6,0xf6,0x01,0xf7 }, { 0x0e,0x0e,0x12,0x1c },
-    { 0x61,0x61,0xa3,0xc2 }, { 0x35,0x35,0x5f,0x6a },
-    { 0x57,0x57,0xf9,0xae }, { 0xb9,0xb9,0xd0,0x69 },
-    { 0x86,0x86,0x91,0x17 }, { 0xc1,0xc1,0x58,0x99 },
-    { 0x1d,0x1d,0x27,0x3a }, { 0x9e,0x9e,0xb9,0x27 },
-    { 0xe1,0xe1,0x38,0xd9 }, { 0xf8,0xf8,0x13,0xeb },
-    { 0x98,0x98,0xb3,0x2b }, { 0x11,0x11,0x33,0x22 },
-    { 0x69,0x69,0xbb,0xd2 }, { 0xd9,0xd9,0x70,0xa9 },
-    { 0x8e,0x8e,0x89,0x07 }, { 0x94,0x94,0xa7,0x33 },
-    { 0x9b,0x9b,0xb6,0x2d }, { 0x1e,0x1e,0x22,0x3c },
-    { 0x87,0x87,0x92,0x15 }, { 0xe9,0xe9,0x20,0xc9 },
-    { 0xce,0xce,0x49,0x87 }, { 0x55,0x55,0xff,0xaa },
-    { 0x28,0x28,0x78,0x50 }, { 0xdf,0xdf,0x7a,0xa5 },
-    { 0x8c,0x8c,0x8f,0x03 }, { 0xa1,0xa1,0xf8,0x59 },
-    { 0x89,0x89,0x80,0x09 }, { 0x0d,0x0d,0x17,0x1a },
-    { 0xbf,0xbf,0xda,0x65 }, { 0xe6,0xe6,0x31,0xd7 },
-    { 0x42,0x42,0xc6,0x84 }, { 0x68,0x68,0xb8,0xd0 },
-    { 0x41,0x41,0xc3,0x82 }, { 0x99,0x99,0xb0,0x29 },
-    { 0x2d,0x2d,0x77,0x5a }, { 0x0f,0x0f,0x11,0x1e },
-    { 0xb0,0xb0,0xcb,0x7b }, { 0x54,0x54,0xfc,0xa8 },
-    { 0xbb,0xbb,0xd6,0x6d }, { 0x16,0x16,0x3a,0x2c }
-  };
-
-static const unsigned char T5[256][4] =
-  {
-    { 0x51,0xf4,0xa7,0x50 }, { 0x7e,0x41,0x65,0x53 },
-    { 0x1a,0x17,0xa4,0xc3 }, { 0x3a,0x27,0x5e,0x96 },
-    { 0x3b,0xab,0x6b,0xcb }, { 0x1f,0x9d,0x45,0xf1 },
-    { 0xac,0xfa,0x58,0xab }, { 0x4b,0xe3,0x03,0x93 },
-    { 0x20,0x30,0xfa,0x55 }, { 0xad,0x76,0x6d,0xf6 },
-    { 0x88,0xcc,0x76,0x91 }, { 0xf5,0x02,0x4c,0x25 },
-    { 0x4f,0xe5,0xd7,0xfc }, { 0xc5,0x2a,0xcb,0xd7 },
-    { 0x26,0x35,0x44,0x80 }, { 0xb5,0x62,0xa3,0x8f },
-    { 0xde,0xb1,0x5a,0x49 }, { 0x25,0xba,0x1b,0x67 },
-    { 0x45,0xea,0x0e,0x98 }, { 0x5d,0xfe,0xc0,0xe1 },
-    { 0xc3,0x2f,0x75,0x02 }, { 0x81,0x4c,0xf0,0x12 },
-    { 0x8d,0x46,0x97,0xa3 }, { 0x6b,0xd3,0xf9,0xc6 },
-    { 0x03,0x8f,0x5f,0xe7 }, { 0x15,0x92,0x9c,0x95 },
-    { 0xbf,0x6d,0x7a,0xeb }, { 0x95,0x52,0x59,0xda },
-    { 0xd4,0xbe,0x83,0x2d }, { 0x58,0x74,0x21,0xd3 },
-    { 0x49,0xe0,0x69,0x29 }, { 0x8e,0xc9,0xc8,0x44 },
-    { 0x75,0xc2,0x89,0x6a }, { 0xf4,0x8e,0x79,0x78 },
-    { 0x99,0x58,0x3e,0x6b }, { 0x27,0xb9,0x71,0xdd },
-    { 0xbe,0xe1,0x4f,0xb6 }, { 0xf0,0x88,0xad,0x17 },
-    { 0xc9,0x20,0xac,0x66 }, { 0x7d,0xce,0x3a,0xb4 },
-    { 0x63,0xdf,0x4a,0x18 }, { 0xe5,0x1a,0x31,0x82 },
-    { 0x97,0x51,0x33,0x60 }, { 0x62,0x53,0x7f,0x45 },
-    { 0xb1,0x64,0x77,0xe0 }, { 0xbb,0x6b,0xae,0x84 },
-    { 0xfe,0x81,0xa0,0x1c }, { 0xf9,0x08,0x2b,0x94 },
-    { 0x70,0x48,0x68,0x58 }, { 0x8f,0x45,0xfd,0x19 },
-    { 0x94,0xde,0x6c,0x87 }, { 0x52,0x7b,0xf8,0xb7 },
-    { 0xab,0x73,0xd3,0x23 }, { 0x72,0x4b,0x02,0xe2 },
-    { 0xe3,0x1f,0x8f,0x57 }, { 0x66,0x55,0xab,0x2a },
-    { 0xb2,0xeb,0x28,0x07 }, { 0x2f,0xb5,0xc2,0x03 },
-    { 0x86,0xc5,0x7b,0x9a }, { 0xd3,0x37,0x08,0xa5 },
-    { 0x30,0x28,0x87,0xf2 }, { 0x23,0xbf,0xa5,0xb2 },
-    { 0x02,0x03,0x6a,0xba }, { 0xed,0x16,0x82,0x5c },
-    { 0x8a,0xcf,0x1c,0x2b }, { 0xa7,0x79,0xb4,0x92 },
-    { 0xf3,0x07,0xf2,0xf0 }, { 0x4e,0x69,0xe2,0xa1 },
-    { 0x65,0xda,0xf4,0xcd }, { 0x06,0x05,0xbe,0xd5 },
-    { 0xd1,0x34,0x62,0x1f }, { 0xc4,0xa6,0xfe,0x8a },
-    { 0x34,0x2e,0x53,0x9d }, { 0xa2,0xf3,0x55,0xa0 },
-    { 0x05,0x8a,0xe1,0x32 }, { 0xa4,0xf6,0xeb,0x75 },
-    { 0x0b,0x83,0xec,0x39 }, { 0x40,0x60,0xef,0xaa },
-    { 0x5e,0x71,0x9f,0x06 }, { 0xbd,0x6e,0x10,0x51 },
-    { 0x3e,0x21,0x8a,0xf9 }, { 0x96,0xdd,0x06,0x3d },
-    { 0xdd,0x3e,0x05,0xae }, { 0x4d,0xe6,0xbd,0x46 },
-    { 0x91,0x54,0x8d,0xb5 }, { 0x71,0xc4,0x5d,0x05 },
-    { 0x04,0x06,0xd4,0x6f }, { 0x60,0x50,0x15,0xff },
-    { 0x19,0x98,0xfb,0x24 }, { 0xd6,0xbd,0xe9,0x97 },
-    { 0x89,0x40,0x43,0xcc }, { 0x67,0xd9,0x9e,0x77 },
-    { 0xb0,0xe8,0x42,0xbd }, { 0x07,0x89,0x8b,0x88 },
-    { 0xe7,0x19,0x5b,0x38 }, { 0x79,0xc8,0xee,0xdb },
-    { 0xa1,0x7c,0x0a,0x47 }, { 0x7c,0x42,0x0f,0xe9 },
-    { 0xf8,0x84,0x1e,0xc9 }, { 0x00,0x00,0x00,0x00 },
-    { 0x09,0x80,0x86,0x83 }, { 0x32,0x2b,0xed,0x48 },
-    { 0x1e,0x11,0x70,0xac }, { 0x6c,0x5a,0x72,0x4e },
-    { 0xfd,0x0e,0xff,0xfb }, { 0x0f,0x85,0x38,0x56 },
-    { 0x3d,0xae,0xd5,0x1e }, { 0x36,0x2d,0x39,0x27 },
-    { 0x0a,0x0f,0xd9,0x64 }, { 0x68,0x5c,0xa6,0x21 },
-    { 0x9b,0x5b,0x54,0xd1 }, { 0x24,0x36,0x2e,0x3a },
-    { 0x0c,0x0a,0x67,0xb1 }, { 0x93,0x57,0xe7,0x0f },
-    { 0xb4,0xee,0x96,0xd2 }, { 0x1b,0x9b,0x91,0x9e },
-    { 0x80,0xc0,0xc5,0x4f }, { 0x61,0xdc,0x20,0xa2 },
-    { 0x5a,0x77,0x4b,0x69 }, { 0x1c,0x12,0x1a,0x16 },
-    { 0xe2,0x93,0xba,0x0a }, { 0xc0,0xa0,0x2a,0xe5 },
-    { 0x3c,0x22,0xe0,0x43 }, { 0x12,0x1b,0x17,0x1d },
-    { 0x0e,0x09,0x0d,0x0b }, { 0xf2,0x8b,0xc7,0xad },
-    { 0x2d,0xb6,0xa8,0xb9 }, { 0x14,0x1e,0xa9,0xc8 },
-    { 0x57,0xf1,0x19,0x85 }, { 0xaf,0x75,0x07,0x4c },
-    { 0xee,0x99,0xdd,0xbb }, { 0xa3,0x7f,0x60,0xfd },
-    { 0xf7,0x01,0x26,0x9f }, { 0x5c,0x72,0xf5,0xbc },
-    { 0x44,0x66,0x3b,0xc5 }, { 0x5b,0xfb,0x7e,0x34 },
-    { 0x8b,0x43,0x29,0x76 }, { 0xcb,0x23,0xc6,0xdc },
-    { 0xb6,0xed,0xfc,0x68 }, { 0xb8,0xe4,0xf1,0x63 },
-    { 0xd7,0x31,0xdc,0xca }, { 0x42,0x63,0x85,0x10 },
-    { 0x13,0x97,0x22,0x40 }, { 0x84,0xc6,0x11,0x20 },
-    { 0x85,0x4a,0x24,0x7d }, { 0xd2,0xbb,0x3d,0xf8 },
-    { 0xae,0xf9,0x32,0x11 }, { 0xc7,0x29,0xa1,0x6d },
-    { 0x1d,0x9e,0x2f,0x4b }, { 0xdc,0xb2,0x30,0xf3 },
-    { 0x0d,0x86,0x52,0xec }, { 0x77,0xc1,0xe3,0xd0 },
-    { 0x2b,0xb3,0x16,0x6c }, { 0xa9,0x70,0xb9,0x99 },
-    { 0x11,0x94,0x48,0xfa }, { 0x47,0xe9,0x64,0x22 },
-    { 0xa8,0xfc,0x8c,0xc4 }, { 0xa0,0xf0,0x3f,0x1a },
-    { 0x56,0x7d,0x2c,0xd8 }, { 0x22,0x33,0x90,0xef },
-    { 0x87,0x49,0x4e,0xc7 }, { 0xd9,0x38,0xd1,0xc1 },
-    { 0x8c,0xca,0xa2,0xfe }, { 0x98,0xd4,0x0b,0x36 },
-    { 0xa6,0xf5,0x81,0xcf }, { 0xa5,0x7a,0xde,0x28 },
-    { 0xda,0xb7,0x8e,0x26 }, { 0x3f,0xad,0xbf,0xa4 },
-    { 0x2c,0x3a,0x9d,0xe4 }, { 0x50,0x78,0x92,0x0d },
-    { 0x6a,0x5f,0xcc,0x9b }, { 0x54,0x7e,0x46,0x62 },
-    { 0xf6,0x8d,0x13,0xc2 }, { 0x90,0xd8,0xb8,0xe8 },
-    { 0x2e,0x39,0xf7,0x5e }, { 0x82,0xc3,0xaf,0xf5 },
-    { 0x9f,0x5d,0x80,0xbe }, { 0x69,0xd0,0x93,0x7c },
-    { 0x6f,0xd5,0x2d,0xa9 }, { 0xcf,0x25,0x12,0xb3 },
-    { 0xc8,0xac,0x99,0x3b }, { 0x10,0x18,0x7d,0xa7 },
-    { 0xe8,0x9c,0x63,0x6e }, { 0xdb,0x3b,0xbb,0x7b },
-    { 0xcd,0x26,0x78,0x09 }, { 0x6e,0x59,0x18,0xf4 },
-    { 0xec,0x9a,0xb7,0x01 }, { 0x83,0x4f,0x9a,0xa8 },
-    { 0xe6,0x95,0x6e,0x65 }, { 0xaa,0xff,0xe6,0x7e },
-    { 0x21,0xbc,0xcf,0x08 }, { 0xef,0x15,0xe8,0xe6 },
-    { 0xba,0xe7,0x9b,0xd9 }, { 0x4a,0x6f,0x36,0xce },
-    { 0xea,0x9f,0x09,0xd4 }, { 0x29,0xb0,0x7c,0xd6 },
-    { 0x31,0xa4,0xb2,0xaf }, { 0x2a,0x3f,0x23,0x31 },
-    { 0xc6,0xa5,0x94,0x30 }, { 0x35,0xa2,0x66,0xc0 },
-    { 0x74,0x4e,0xbc,0x37 }, { 0xfc,0x82,0xca,0xa6 },
-    { 0xe0,0x90,0xd0,0xb0 }, { 0x33,0xa7,0xd8,0x15 },
-    { 0xf1,0x04,0x98,0x4a }, { 0x41,0xec,0xda,0xf7 },
-    { 0x7f,0xcd,0x50,0x0e }, { 0x17,0x91,0xf6,0x2f },
-    { 0x76,0x4d,0xd6,0x8d }, { 0x43,0xef,0xb0,0x4d },
-    { 0xcc,0xaa,0x4d,0x54 }, { 0xe4,0x96,0x04,0xdf },
-    { 0x9e,0xd1,0xb5,0xe3 }, { 0x4c,0x6a,0x88,0x1b },
-    { 0xc1,0x2c,0x1f,0xb8 }, { 0x46,0x65,0x51,0x7f },
-    { 0x9d,0x5e,0xea,0x04 }, { 0x01,0x8c,0x35,0x5d },
-    { 0xfa,0x87,0x74,0x73 }, { 0xfb,0x0b,0x41,0x2e },
-    { 0xb3,0x67,0x1d,0x5a }, { 0x92,0xdb,0xd2,0x52 },
-    { 0xe9,0x10,0x56,0x33 }, { 0x6d,0xd6,0x47,0x13 },
-    { 0x9a,0xd7,0x61,0x8c }, { 0x37,0xa1,0x0c,0x7a },
-    { 0x59,0xf8,0x14,0x8e }, { 0xeb,0x13,0x3c,0x89 },
-    { 0xce,0xa9,0x27,0xee }, { 0xb7,0x61,0xc9,0x35 },
-    { 0xe1,0x1c,0xe5,0xed }, { 0x7a,0x47,0xb1,0x3c },
-    { 0x9c,0xd2,0xdf,0x59 }, { 0x55,0xf2,0x73,0x3f },
-    { 0x18,0x14,0xce,0x79 }, { 0x73,0xc7,0x37,0xbf },
-    { 0x53,0xf7,0xcd,0xea }, { 0x5f,0xfd,0xaa,0x5b },
-    { 0xdf,0x3d,0x6f,0x14 }, { 0x78,0x44,0xdb,0x86 },
-    { 0xca,0xaf,0xf3,0x81 }, { 0xb9,0x68,0xc4,0x3e },
-    { 0x38,0x24,0x34,0x2c }, { 0xc2,0xa3,0x40,0x5f },
-    { 0x16,0x1d,0xc3,0x72 }, { 0xbc,0xe2,0x25,0x0c },
-    { 0x28,0x3c,0x49,0x8b }, { 0xff,0x0d,0x95,0x41 },
-    { 0x39,0xa8,0x01,0x71 }, { 0x08,0x0c,0xb3,0xde },
-    { 0xd8,0xb4,0xe4,0x9c }, { 0x64,0x56,0xc1,0x90 },
-    { 0x7b,0xcb,0x84,0x61 }, { 0xd5,0x32,0xb6,0x70 },
-    { 0x48,0x6c,0x5c,0x74 }, { 0xd0,0xb8,0x57,0x42 }
-  };
-
-static const unsigned char T6[256][4] =
-  {
-    { 0x50,0x51,0xf4,0xa7 }, { 0x53,0x7e,0x41,0x65 },
-    { 0xc3,0x1a,0x17,0xa4 }, { 0x96,0x3a,0x27,0x5e },
-    { 0xcb,0x3b,0xab,0x6b }, { 0xf1,0x1f,0x9d,0x45 },
-    { 0xab,0xac,0xfa,0x58 }, { 0x93,0x4b,0xe3,0x03 },
-    { 0x55,0x20,0x30,0xfa }, { 0xf6,0xad,0x76,0x6d },
-    { 0x91,0x88,0xcc,0x76 }, { 0x25,0xf5,0x02,0x4c },
-    { 0xfc,0x4f,0xe5,0xd7 }, { 0xd7,0xc5,0x2a,0xcb },
-    { 0x80,0x26,0x35,0x44 }, { 0x8f,0xb5,0x62,0xa3 },
-    { 0x49,0xde,0xb1,0x5a }, { 0x67,0x25,0xba,0x1b },
-    { 0x98,0x45,0xea,0x0e }, { 0xe1,0x5d,0xfe,0xc0 },
-    { 0x02,0xc3,0x2f,0x75 }, { 0x12,0x81,0x4c,0xf0 },
-    { 0xa3,0x8d,0x46,0x97 }, { 0xc6,0x6b,0xd3,0xf9 },
-    { 0xe7,0x03,0x8f,0x5f }, { 0x95,0x15,0x92,0x9c },
-    { 0xeb,0xbf,0x6d,0x7a }, { 0xda,0x95,0x52,0x59 },
-    { 0x2d,0xd4,0xbe,0x83 }, { 0xd3,0x58,0x74,0x21 },
-    { 0x29,0x49,0xe0,0x69 }, { 0x44,0x8e,0xc9,0xc8 },
-    { 0x6a,0x75,0xc2,0x89 }, { 0x78,0xf4,0x8e,0x79 },
-    { 0x6b,0x99,0x58,0x3e }, { 0xdd,0x27,0xb9,0x71 },
-    { 0xb6,0xbe,0xe1,0x4f }, { 0x17,0xf0,0x88,0xad },
-    { 0x66,0xc9,0x20,0xac }, { 0xb4,0x7d,0xce,0x3a },
-    { 0x18,0x63,0xdf,0x4a }, { 0x82,0xe5,0x1a,0x31 },
-    { 0x60,0x97,0x51,0x33 }, { 0x45,0x62,0x53,0x7f },
-    { 0xe0,0xb1,0x64,0x77 }, { 0x84,0xbb,0x6b,0xae },
-    { 0x1c,0xfe,0x81,0xa0 }, { 0x94,0xf9,0x08,0x2b },
-    { 0x58,0x70,0x48,0x68 }, { 0x19,0x8f,0x45,0xfd },
-    { 0x87,0x94,0xde,0x6c }, { 0xb7,0x52,0x7b,0xf8 },
-    { 0x23,0xab,0x73,0xd3 }, { 0xe2,0x72,0x4b,0x02 },
-    { 0x57,0xe3,0x1f,0x8f }, { 0x2a,0x66,0x55,0xab },
-    { 0x07,0xb2,0xeb,0x28 }, { 0x03,0x2f,0xb5,0xc2 },
-    { 0x9a,0x86,0xc5,0x7b }, { 0xa5,0xd3,0x37,0x08 },
-    { 0xf2,0x30,0x28,0x87 }, { 0xb2,0x23,0xbf,0xa5 },
-    { 0xba,0x02,0x03,0x6a }, { 0x5c,0xed,0x16,0x82 },
-    { 0x2b,0x8a,0xcf,0x1c }, { 0x92,0xa7,0x79,0xb4 },
-    { 0xf0,0xf3,0x07,0xf2 }, { 0xa1,0x4e,0x69,0xe2 },
-    { 0xcd,0x65,0xda,0xf4 }, { 0xd5,0x06,0x05,0xbe },
-    { 0x1f,0xd1,0x34,0x62 }, { 0x8a,0xc4,0xa6,0xfe },
-    { 0x9d,0x34,0x2e,0x53 }, { 0xa0,0xa2,0xf3,0x55 },
-    { 0x32,0x05,0x8a,0xe1 }, { 0x75,0xa4,0xf6,0xeb },
-    { 0x39,0x0b,0x83,0xec }, { 0xaa,0x40,0x60,0xef },
-    { 0x06,0x5e,0x71,0x9f }, { 0x51,0xbd,0x6e,0x10 },
-    { 0xf9,0x3e,0x21,0x8a }, { 0x3d,0x96,0xdd,0x06 },
-    { 0xae,0xdd,0x3e,0x05 }, { 0x46,0x4d,0xe6,0xbd },
-    { 0xb5,0x91,0x54,0x8d }, { 0x05,0x71,0xc4,0x5d },
-    { 0x6f,0x04,0x06,0xd4 }, { 0xff,0x60,0x50,0x15 },
-    { 0x24,0x19,0x98,0xfb }, { 0x97,0xd6,0xbd,0xe9 },
-    { 0xcc,0x89,0x40,0x43 }, { 0x77,0x67,0xd9,0x9e },
-    { 0xbd,0xb0,0xe8,0x42 }, { 0x88,0x07,0x89,0x8b },
-    { 0x38,0xe7,0x19,0x5b }, { 0xdb,0x79,0xc8,0xee },
-    { 0x47,0xa1,0x7c,0x0a }, { 0xe9,0x7c,0x42,0x0f },
-    { 0xc9,0xf8,0x84,0x1e }, { 0x00,0x00,0x00,0x00 },
-    { 0x83,0x09,0x80,0x86 }, { 0x48,0x32,0x2b,0xed },
-    { 0xac,0x1e,0x11,0x70 }, { 0x4e,0x6c,0x5a,0x72 },
-    { 0xfb,0xfd,0x0e,0xff }, { 0x56,0x0f,0x85,0x38 },
-    { 0x1e,0x3d,0xae,0xd5 }, { 0x27,0x36,0x2d,0x39 },
-    { 0x64,0x0a,0x0f,0xd9 }, { 0x21,0x68,0x5c,0xa6 },
-    { 0xd1,0x9b,0x5b,0x54 }, { 0x3a,0x24,0x36,0x2e },
-    { 0xb1,0x0c,0x0a,0x67 }, { 0x0f,0x93,0x57,0xe7 },
-    { 0xd2,0xb4,0xee,0x96 }, { 0x9e,0x1b,0x9b,0x91 },
-    { 0x4f,0x80,0xc0,0xc5 }, { 0xa2,0x61,0xdc,0x20 },
-    { 0x69,0x5a,0x77,0x4b }, { 0x16,0x1c,0x12,0x1a },
-    { 0x0a,0xe2,0x93,0xba }, { 0xe5,0xc0,0xa0,0x2a },
-    { 0x43,0x3c,0x22,0xe0 }, { 0x1d,0x12,0x1b,0x17 },
-    { 0x0b,0x0e,0x09,0x0d }, { 0xad,0xf2,0x8b,0xc7 },
-    { 0xb9,0x2d,0xb6,0xa8 }, { 0xc8,0x14,0x1e,0xa9 },
-    { 0x85,0x57,0xf1,0x19 }, { 0x4c,0xaf,0x75,0x07 },
-    { 0xbb,0xee,0x99,0xdd }, { 0xfd,0xa3,0x7f,0x60 },
-    { 0x9f,0xf7,0x01,0x26 }, { 0xbc,0x5c,0x72,0xf5 },
-    { 0xc5,0x44,0x66,0x3b }, { 0x34,0x5b,0xfb,0x7e },
-    { 0x76,0x8b,0x43,0x29 }, { 0xdc,0xcb,0x23,0xc6 },
-    { 0x68,0xb6,0xed,0xfc }, { 0x63,0xb8,0xe4,0xf1 },
-    { 0xca,0xd7,0x31,0xdc }, { 0x10,0x42,0x63,0x85 },
-    { 0x40,0x13,0x97,0x22 }, { 0x20,0x84,0xc6,0x11 },
-    { 0x7d,0x85,0x4a,0x24 }, { 0xf8,0xd2,0xbb,0x3d },
-    { 0x11,0xae,0xf9,0x32 }, { 0x6d,0xc7,0x29,0xa1 },
-    { 0x4b,0x1d,0x9e,0x2f }, { 0xf3,0xdc,0xb2,0x30 },
-    { 0xec,0x0d,0x86,0x52 }, { 0xd0,0x77,0xc1,0xe3 },
-    { 0x6c,0x2b,0xb3,0x16 }, { 0x99,0xa9,0x70,0xb9 },
-    { 0xfa,0x11,0x94,0x48 }, { 0x22,0x47,0xe9,0x64 },
-    { 0xc4,0xa8,0xfc,0x8c }, { 0x1a,0xa0,0xf0,0x3f },
-    { 0xd8,0x56,0x7d,0x2c }, { 0xef,0x22,0x33,0x90 },
-    { 0xc7,0x87,0x49,0x4e }, { 0xc1,0xd9,0x38,0xd1 },
-    { 0xfe,0x8c,0xca,0xa2 }, { 0x36,0x98,0xd4,0x0b },
-    { 0xcf,0xa6,0xf5,0x81 }, { 0x28,0xa5,0x7a,0xde },
-    { 0x26,0xda,0xb7,0x8e }, { 0xa4,0x3f,0xad,0xbf },
-    { 0xe4,0x2c,0x3a,0x9d }, { 0x0d,0x50,0x78,0x92 },
-    { 0x9b,0x6a,0x5f,0xcc }, { 0x62,0x54,0x7e,0x46 },
-    { 0xc2,0xf6,0x8d,0x13 }, { 0xe8,0x90,0xd8,0xb8 },
-    { 0x5e,0x2e,0x39,0xf7 }, { 0xf5,0x82,0xc3,0xaf },
-    { 0xbe,0x9f,0x5d,0x80 }, { 0x7c,0x69,0xd0,0x93 },
-    { 0xa9,0x6f,0xd5,0x2d }, { 0xb3,0xcf,0x25,0x12 },
-    { 0x3b,0xc8,0xac,0x99 }, { 0xa7,0x10,0x18,0x7d },
-    { 0x6e,0xe8,0x9c,0x63 }, { 0x7b,0xdb,0x3b,0xbb },
-    { 0x09,0xcd,0x26,0x78 }, { 0xf4,0x6e,0x59,0x18 },
-    { 0x01,0xec,0x9a,0xb7 }, { 0xa8,0x83,0x4f,0x9a },
-    { 0x65,0xe6,0x95,0x6e }, { 0x7e,0xaa,0xff,0xe6 },
-    { 0x08,0x21,0xbc,0xcf }, { 0xe6,0xef,0x15,0xe8 },
-    { 0xd9,0xba,0xe7,0x9b }, { 0xce,0x4a,0x6f,0x36 },
-    { 0xd4,0xea,0x9f,0x09 }, { 0xd6,0x29,0xb0,0x7c },
-    { 0xaf,0x31,0xa4,0xb2 }, { 0x31,0x2a,0x3f,0x23 },
-    { 0x30,0xc6,0xa5,0x94 }, { 0xc0,0x35,0xa2,0x66 },
-    { 0x37,0x74,0x4e,0xbc }, { 0xa6,0xfc,0x82,0xca },
-    { 0xb0,0xe0,0x90,0xd0 }, { 0x15,0x33,0xa7,0xd8 },
-    { 0x4a,0xf1,0x04,0x98 }, { 0xf7,0x41,0xec,0xda },
-    { 0x0e,0x7f,0xcd,0x50 }, { 0x2f,0x17,0x91,0xf6 },
-    { 0x8d,0x76,0x4d,0xd6 }, { 0x4d,0x43,0xef,0xb0 },
-    { 0x54,0xcc,0xaa,0x4d }, { 0xdf,0xe4,0x96,0x04 },
-    { 0xe3,0x9e,0xd1,0xb5 }, { 0x1b,0x4c,0x6a,0x88 },
-    { 0xb8,0xc1,0x2c,0x1f }, { 0x7f,0x46,0x65,0x51 },
-    { 0x04,0x9d,0x5e,0xea }, { 0x5d,0x01,0x8c,0x35 },
-    { 0x73,0xfa,0x87,0x74 }, { 0x2e,0xfb,0x0b,0x41 },
-    { 0x5a,0xb3,0x67,0x1d }, { 0x52,0x92,0xdb,0xd2 },
-    { 0x33,0xe9,0x10,0x56 }, { 0x13,0x6d,0xd6,0x47 },
-    { 0x8c,0x9a,0xd7,0x61 }, { 0x7a,0x37,0xa1,0x0c },
-    { 0x8e,0x59,0xf8,0x14 }, { 0x89,0xeb,0x13,0x3c },
-    { 0xee,0xce,0xa9,0x27 }, { 0x35,0xb7,0x61,0xc9 },
-    { 0xed,0xe1,0x1c,0xe5 }, { 0x3c,0x7a,0x47,0xb1 },
-    { 0x59,0x9c,0xd2,0xdf }, { 0x3f,0x55,0xf2,0x73 },
-    { 0x79,0x18,0x14,0xce }, { 0xbf,0x73,0xc7,0x37 },
-    { 0xea,0x53,0xf7,0xcd }, { 0x5b,0x5f,0xfd,0xaa },
-    { 0x14,0xdf,0x3d,0x6f }, { 0x86,0x78,0x44,0xdb },
-    { 0x81,0xca,0xaf,0xf3 }, { 0x3e,0xb9,0x68,0xc4 },
-    { 0x2c,0x38,0x24,0x34 }, { 0x5f,0xc2,0xa3,0x40 },
-    { 0x72,0x16,0x1d,0xc3 }, { 0x0c,0xbc,0xe2,0x25 },
-    { 0x8b,0x28,0x3c,0x49 }, { 0x41,0xff,0x0d,0x95 },
-    { 0x71,0x39,0xa8,0x01 }, { 0xde,0x08,0x0c,0xb3 },
-    { 0x9c,0xd8,0xb4,0xe4 }, { 0x90,0x64,0x56,0xc1 },
-    { 0x61,0x7b,0xcb,0x84 }, { 0x70,0xd5,0x32,0xb6 },
-    { 0x74,0x48,0x6c,0x5c }, { 0x42,0xd0,0xb8,0x57 }
-  };
-
-static const unsigned char T7[256][4] =
-  {
-    { 0xa7,0x50,0x51,0xf4 }, { 0x65,0x53,0x7e,0x41 },
-    { 0xa4,0xc3,0x1a,0x17 }, { 0x5e,0x96,0x3a,0x27 },
-    { 0x6b,0xcb,0x3b,0xab }, { 0x45,0xf1,0x1f,0x9d },
-    { 0x58,0xab,0xac,0xfa }, { 0x03,0x93,0x4b,0xe3 },
-    { 0xfa,0x55,0x20,0x30 }, { 0x6d,0xf6,0xad,0x76 },
-    { 0x76,0x91,0x88,0xcc }, { 0x4c,0x25,0xf5,0x02 },
-    { 0xd7,0xfc,0x4f,0xe5 }, { 0xcb,0xd7,0xc5,0x2a },
-    { 0x44,0x80,0x26,0x35 }, { 0xa3,0x8f,0xb5,0x62 },
-    { 0x5a,0x49,0xde,0xb1 }, { 0x1b,0x67,0x25,0xba },
-    { 0x0e,0x98,0x45,0xea }, { 0xc0,0xe1,0x5d,0xfe },
-    { 0x75,0x02,0xc3,0x2f }, { 0xf0,0x12,0x81,0x4c },
-    { 0x97,0xa3,0x8d,0x46 }, { 0xf9,0xc6,0x6b,0xd3 },
-    { 0x5f,0xe7,0x03,0x8f }, { 0x9c,0x95,0x15,0x92 },
-    { 0x7a,0xeb,0xbf,0x6d }, { 0x59,0xda,0x95,0x52 },
-    { 0x83,0x2d,0xd4,0xbe }, { 0x21,0xd3,0x58,0x74 },
-    { 0x69,0x29,0x49,0xe0 }, { 0xc8,0x44,0x8e,0xc9 },
-    { 0x89,0x6a,0x75,0xc2 }, { 0x79,0x78,0xf4,0x8e },
-    { 0x3e,0x6b,0x99,0x58 }, { 0x71,0xdd,0x27,0xb9 },
-    { 0x4f,0xb6,0xbe,0xe1 }, { 0xad,0x17,0xf0,0x88 },
-    { 0xac,0x66,0xc9,0x20 }, { 0x3a,0xb4,0x7d,0xce },
-    { 0x4a,0x18,0x63,0xdf }, { 0x31,0x82,0xe5,0x1a },
-    { 0x33,0x60,0x97,0x51 }, { 0x7f,0x45,0x62,0x53 },
-    { 0x77,0xe0,0xb1,0x64 }, { 0xae,0x84,0xbb,0x6b },
-    { 0xa0,0x1c,0xfe,0x81 }, { 0x2b,0x94,0xf9,0x08 },
-    { 0x68,0x58,0x70,0x48 }, { 0xfd,0x19,0x8f,0x45 },
-    { 0x6c,0x87,0x94,0xde }, { 0xf8,0xb7,0x52,0x7b },
-    { 0xd3,0x23,0xab,0x73 }, { 0x02,0xe2,0x72,0x4b },
-    { 0x8f,0x57,0xe3,0x1f }, { 0xab,0x2a,0x66,0x55 },
-    { 0x28,0x07,0xb2,0xeb }, { 0xc2,0x03,0x2f,0xb5 },
-    { 0x7b,0x9a,0x86,0xc5 }, { 0x08,0xa5,0xd3,0x37 },
-    { 0x87,0xf2,0x30,0x28 }, { 0xa5,0xb2,0x23,0xbf },
-    { 0x6a,0xba,0x02,0x03 }, { 0x82,0x5c,0xed,0x16 },
-    { 0x1c,0x2b,0x8a,0xcf }, { 0xb4,0x92,0xa7,0x79 },
-    { 0xf2,0xf0,0xf3,0x07 }, { 0xe2,0xa1,0x4e,0x69 },
-    { 0xf4,0xcd,0x65,0xda }, { 0xbe,0xd5,0x06,0x05 },
-    { 0x62,0x1f,0xd1,0x34 }, { 0xfe,0x8a,0xc4,0xa6 },
-    { 0x53,0x9d,0x34,0x2e }, { 0x55,0xa0,0xa2,0xf3 },
-    { 0xe1,0x32,0x05,0x8a }, { 0xeb,0x75,0xa4,0xf6 },
-    { 0xec,0x39,0x0b,0x83 }, { 0xef,0xaa,0x40,0x60 },
-    { 0x9f,0x06,0x5e,0x71 }, { 0x10,0x51,0xbd,0x6e },
-    { 0x8a,0xf9,0x3e,0x21 }, { 0x06,0x3d,0x96,0xdd },
-    { 0x05,0xae,0xdd,0x3e }, { 0xbd,0x46,0x4d,0xe6 },
-    { 0x8d,0xb5,0x91,0x54 }, { 0x5d,0x05,0x71,0xc4 },
-    { 0xd4,0x6f,0x04,0x06 }, { 0x15,0xff,0x60,0x50 },
-    { 0xfb,0x24,0x19,0x98 }, { 0xe9,0x97,0xd6,0xbd },
-    { 0x43,0xcc,0x89,0x40 }, { 0x9e,0x77,0x67,0xd9 },
-    { 0x42,0xbd,0xb0,0xe8 }, { 0x8b,0x88,0x07,0x89 },
-    { 0x5b,0x38,0xe7,0x19 }, { 0xee,0xdb,0x79,0xc8 },
-    { 0x0a,0x47,0xa1,0x7c }, { 0x0f,0xe9,0x7c,0x42 },
-    { 0x1e,0xc9,0xf8,0x84 }, { 0x00,0x00,0x00,0x00 },
-    { 0x86,0x83,0x09,0x80 }, { 0xed,0x48,0x32,0x2b },
-    { 0x70,0xac,0x1e,0x11 }, { 0x72,0x4e,0x6c,0x5a },
-    { 0xff,0xfb,0xfd,0x0e }, { 0x38,0x56,0x0f,0x85 },
-    { 0xd5,0x1e,0x3d,0xae }, { 0x39,0x27,0x36,0x2d },
-    { 0xd9,0x64,0x0a,0x0f }, { 0xa6,0x21,0x68,0x5c },
-    { 0x54,0xd1,0x9b,0x5b }, { 0x2e,0x3a,0x24,0x36 },
-    { 0x67,0xb1,0x0c,0x0a }, { 0xe7,0x0f,0x93,0x57 },
-    { 0x96,0xd2,0xb4,0xee }, { 0x91,0x9e,0x1b,0x9b },
-    { 0xc5,0x4f,0x80,0xc0 }, { 0x20,0xa2,0x61,0xdc },
-    { 0x4b,0x69,0x5a,0x77 }, { 0x1a,0x16,0x1c,0x12 },
-    { 0xba,0x0a,0xe2,0x93 }, { 0x2a,0xe5,0xc0,0xa0 },
-    { 0xe0,0x43,0x3c,0x22 }, { 0x17,0x1d,0x12,0x1b },
-    { 0x0d,0x0b,0x0e,0x09 }, { 0xc7,0xad,0xf2,0x8b },
-    { 0xa8,0xb9,0x2d,0xb6 }, { 0xa9,0xc8,0x14,0x1e },
-    { 0x19,0x85,0x57,0xf1 }, { 0x07,0x4c,0xaf,0x75 },
-    { 0xdd,0xbb,0xee,0x99 }, { 0x60,0xfd,0xa3,0x7f },
-    { 0x26,0x9f,0xf7,0x01 }, { 0xf5,0xbc,0x5c,0x72 },
-    { 0x3b,0xc5,0x44,0x66 }, { 0x7e,0x34,0x5b,0xfb },
-    { 0x29,0x76,0x8b,0x43 }, { 0xc6,0xdc,0xcb,0x23 },
-    { 0xfc,0x68,0xb6,0xed }, { 0xf1,0x63,0xb8,0xe4 },
-    { 0xdc,0xca,0xd7,0x31 }, { 0x85,0x10,0x42,0x63 },
-    { 0x22,0x40,0x13,0x97 }, { 0x11,0x20,0x84,0xc6 },
-    { 0x24,0x7d,0x85,0x4a }, { 0x3d,0xf8,0xd2,0xbb },
-    { 0x32,0x11,0xae,0xf9 }, { 0xa1,0x6d,0xc7,0x29 },
-    { 0x2f,0x4b,0x1d,0x9e }, { 0x30,0xf3,0xdc,0xb2 },
-    { 0x52,0xec,0x0d,0x86 }, { 0xe3,0xd0,0x77,0xc1 },
-    { 0x16,0x6c,0x2b,0xb3 }, { 0xb9,0x99,0xa9,0x70 },
-    { 0x48,0xfa,0x11,0x94 }, { 0x64,0x22,0x47,0xe9 },
-    { 0x8c,0xc4,0xa8,0xfc }, { 0x3f,0x1a,0xa0,0xf0 },
-    { 0x2c,0xd8,0x56,0x7d }, { 0x90,0xef,0x22,0x33 },
-    { 0x4e,0xc7,0x87,0x49 }, { 0xd1,0xc1,0xd9,0x38 },
-    { 0xa2,0xfe,0x8c,0xca }, { 0x0b,0x36,0x98,0xd4 },
-    { 0x81,0xcf,0xa6,0xf5 }, { 0xde,0x28,0xa5,0x7a },
-    { 0x8e,0x26,0xda,0xb7 }, { 0xbf,0xa4,0x3f,0xad },
-    { 0x9d,0xe4,0x2c,0x3a }, { 0x92,0x0d,0x50,0x78 },
-    { 0xcc,0x9b,0x6a,0x5f }, { 0x46,0x62,0x54,0x7e },
-    { 0x13,0xc2,0xf6,0x8d }, { 0xb8,0xe8,0x90,0xd8 },
-    { 0xf7,0x5e,0x2e,0x39 }, { 0xaf,0xf5,0x82,0xc3 },
-    { 0x80,0xbe,0x9f,0x5d }, { 0x93,0x7c,0x69,0xd0 },
-    { 0x2d,0xa9,0x6f,0xd5 }, { 0x12,0xb3,0xcf,0x25 },
-    { 0x99,0x3b,0xc8,0xac }, { 0x7d,0xa7,0x10,0x18 },
-    { 0x63,0x6e,0xe8,0x9c }, { 0xbb,0x7b,0xdb,0x3b },
-    { 0x78,0x09,0xcd,0x26 }, { 0x18,0xf4,0x6e,0x59 },
-    { 0xb7,0x01,0xec,0x9a }, { 0x9a,0xa8,0x83,0x4f },
-    { 0x6e,0x65,0xe6,0x95 }, { 0xe6,0x7e,0xaa,0xff },
-    { 0xcf,0x08,0x21,0xbc }, { 0xe8,0xe6,0xef,0x15 },
-    { 0x9b,0xd9,0xba,0xe7 }, { 0x36,0xce,0x4a,0x6f },
-    { 0x09,0xd4,0xea,0x9f }, { 0x7c,0xd6,0x29,0xb0 },
-    { 0xb2,0xaf,0x31,0xa4 }, { 0x23,0x31,0x2a,0x3f },
-    { 0x94,0x30,0xc6,0xa5 }, { 0x66,0xc0,0x35,0xa2 },
-    { 0xbc,0x37,0x74,0x4e }, { 0xca,0xa6,0xfc,0x82 },
-    { 0xd0,0xb0,0xe0,0x90 }, { 0xd8,0x15,0x33,0xa7 },
-    { 0x98,0x4a,0xf1,0x04 }, { 0xda,0xf7,0x41,0xec },
-    { 0x50,0x0e,0x7f,0xcd }, { 0xf6,0x2f,0x17,0x91 },
-    { 0xd6,0x8d,0x76,0x4d }, { 0xb0,0x4d,0x43,0xef },
-    { 0x4d,0x54,0xcc,0xaa }, { 0x04,0xdf,0xe4,0x96 },
-    { 0xb5,0xe3,0x9e,0xd1 }, { 0x88,0x1b,0x4c,0x6a },
-    { 0x1f,0xb8,0xc1,0x2c }, { 0x51,0x7f,0x46,0x65 },
-    { 0xea,0x04,0x9d,0x5e }, { 0x35,0x5d,0x01,0x8c },
-    { 0x74,0x73,0xfa,0x87 }, { 0x41,0x2e,0xfb,0x0b },
-    { 0x1d,0x5a,0xb3,0x67 }, { 0xd2,0x52,0x92,0xdb },
-    { 0x56,0x33,0xe9,0x10 }, { 0x47,0x13,0x6d,0xd6 },
-    { 0x61,0x8c,0x9a,0xd7 }, { 0x0c,0x7a,0x37,0xa1 },
-    { 0x14,0x8e,0x59,0xf8 }, { 0x3c,0x89,0xeb,0x13 },
-    { 0x27,0xee,0xce,0xa9 }, { 0xc9,0x35,0xb7,0x61 },
-    { 0xe5,0xed,0xe1,0x1c }, { 0xb1,0x3c,0x7a,0x47 },
-    { 0xdf,0x59,0x9c,0xd2 }, { 0x73,0x3f,0x55,0xf2 },
-    { 0xce,0x79,0x18,0x14 }, { 0x37,0xbf,0x73,0xc7 },
-    { 0xcd,0xea,0x53,0xf7 }, { 0xaa,0x5b,0x5f,0xfd },
-    { 0x6f,0x14,0xdf,0x3d }, { 0xdb,0x86,0x78,0x44 },
-    { 0xf3,0x81,0xca,0xaf }, { 0xc4,0x3e,0xb9,0x68 },
-    { 0x34,0x2c,0x38,0x24 }, { 0x40,0x5f,0xc2,0xa3 },
-    { 0xc3,0x72,0x16,0x1d }, { 0x25,0x0c,0xbc,0xe2 },
-    { 0x49,0x8b,0x28,0x3c }, { 0x95,0x41,0xff,0x0d },
-    { 0x01,0x71,0x39,0xa8 }, { 0xb3,0xde,0x08,0x0c },
-    { 0xe4,0x9c,0xd8,0xb4 }, { 0xc1,0x90,0x64,0x56 },
-    { 0x84,0x61,0x7b,0xcb }, { 0xb6,0x70,0xd5,0x32 },
-    { 0x5c,0x74,0x48,0x6c }, { 0x57,0x42,0xd0,0xb8 }
-  };
-
-static const unsigned char T8[256][4] =
-  {
-    { 0xf4,0xa7,0x50,0x51 }, { 0x41,0x65,0x53,0x7e },
-    { 0x17,0xa4,0xc3,0x1a }, { 0x27,0x5e,0x96,0x3a },
-    { 0xab,0x6b,0xcb,0x3b }, { 0x9d,0x45,0xf1,0x1f },
-    { 0xfa,0x58,0xab,0xac }, { 0xe3,0x03,0x93,0x4b },
-    { 0x30,0xfa,0x55,0x20 }, { 0x76,0x6d,0xf6,0xad },
-    { 0xcc,0x76,0x91,0x88 }, { 0x02,0x4c,0x25,0xf5 },
-    { 0xe5,0xd7,0xfc,0x4f }, { 0x2a,0xcb,0xd7,0xc5 },
-    { 0x35,0x44,0x80,0x26 }, { 0x62,0xa3,0x8f,0xb5 },
-    { 0xb1,0x5a,0x49,0xde }, { 0xba,0x1b,0x67,0x25 },
-    { 0xea,0x0e,0x98,0x45 }, { 0xfe,0xc0,0xe1,0x5d },
-    { 0x2f,0x75,0x02,0xc3 }, { 0x4c,0xf0,0x12,0x81 },
-    { 0x46,0x97,0xa3,0x8d }, { 0xd3,0xf9,0xc6,0x6b },
-    { 0x8f,0x5f,0xe7,0x03 }, { 0x92,0x9c,0x95,0x15 },
-    { 0x6d,0x7a,0xeb,0xbf }, { 0x52,0x59,0xda,0x95 },
-    { 0xbe,0x83,0x2d,0xd4 }, { 0x74,0x21,0xd3,0x58 },
-    { 0xe0,0x69,0x29,0x49 }, { 0xc9,0xc8,0x44,0x8e },
-    { 0xc2,0x89,0x6a,0x75 }, { 0x8e,0x79,0x78,0xf4 },
-    { 0x58,0x3e,0x6b,0x99 }, { 0xb9,0x71,0xdd,0x27 },
-    { 0xe1,0x4f,0xb6,0xbe }, { 0x88,0xad,0x17,0xf0 },
-    { 0x20,0xac,0x66,0xc9 }, { 0xce,0x3a,0xb4,0x7d },
-    { 0xdf,0x4a,0x18,0x63 }, { 0x1a,0x31,0x82,0xe5 },
-    { 0x51,0x33,0x60,0x97 }, { 0x53,0x7f,0x45,0x62 },
-    { 0x64,0x77,0xe0,0xb1 }, { 0x6b,0xae,0x84,0xbb },
-    { 0x81,0xa0,0x1c,0xfe }, { 0x08,0x2b,0x94,0xf9 },
-    { 0x48,0x68,0x58,0x70 }, { 0x45,0xfd,0x19,0x8f },
-    { 0xde,0x6c,0x87,0x94 }, { 0x7b,0xf8,0xb7,0x52 },
-    { 0x73,0xd3,0x23,0xab }, { 0x4b,0x02,0xe2,0x72 },
-    { 0x1f,0x8f,0x57,0xe3 }, { 0x55,0xab,0x2a,0x66 },
-    { 0xeb,0x28,0x07,0xb2 }, { 0xb5,0xc2,0x03,0x2f },
-    { 0xc5,0x7b,0x9a,0x86 }, { 0x37,0x08,0xa5,0xd3 },
-    { 0x28,0x87,0xf2,0x30 }, { 0xbf,0xa5,0xb2,0x23 },
-    { 0x03,0x6a,0xba,0x02 }, { 0x16,0x82,0x5c,0xed },
-    { 0xcf,0x1c,0x2b,0x8a }, { 0x79,0xb4,0x92,0xa7 },
-    { 0x07,0xf2,0xf0,0xf3 }, { 0x69,0xe2,0xa1,0x4e },
-    { 0xda,0xf4,0xcd,0x65 }, { 0x05,0xbe,0xd5,0x06 },
-    { 0x34,0x62,0x1f,0xd1 }, { 0xa6,0xfe,0x8a,0xc4 },
-    { 0x2e,0x53,0x9d,0x34 }, { 0xf3,0x55,0xa0,0xa2 },
-    { 0x8a,0xe1,0x32,0x05 }, { 0xf6,0xeb,0x75,0xa4 },
-    { 0x83,0xec,0x39,0x0b }, { 0x60,0xef,0xaa,0x40 },
-    { 0x71,0x9f,0x06,0x5e }, { 0x6e,0x10,0x51,0xbd },
-    { 0x21,0x8a,0xf9,0x3e }, { 0xdd,0x06,0x3d,0x96 },
-    { 0x3e,0x05,0xae,0xdd }, { 0xe6,0xbd,0x46,0x4d },
-    { 0x54,0x8d,0xb5,0x91 }, { 0xc4,0x5d,0x05,0x71 },
-    { 0x06,0xd4,0x6f,0x04 }, { 0x50,0x15,0xff,0x60 },
-    { 0x98,0xfb,0x24,0x19 }, { 0xbd,0xe9,0x97,0xd6 },
-    { 0x40,0x43,0xcc,0x89 }, { 0xd9,0x9e,0x77,0x67 },
-    { 0xe8,0x42,0xbd,0xb0 }, { 0x89,0x8b,0x88,0x07 },
-    { 0x19,0x5b,0x38,0xe7 }, { 0xc8,0xee,0xdb,0x79 },
-    { 0x7c,0x0a,0x47,0xa1 }, { 0x42,0x0f,0xe9,0x7c },
-    { 0x84,0x1e,0xc9,0xf8 }, { 0x00,0x00,0x00,0x00 },
-    { 0x80,0x86,0x83,0x09 }, { 0x2b,0xed,0x48,0x32 },
-    { 0x11,0x70,0xac,0x1e }, { 0x5a,0x72,0x4e,0x6c },
-    { 0x0e,0xff,0xfb,0xfd }, { 0x85,0x38,0x56,0x0f },
-    { 0xae,0xd5,0x1e,0x3d }, { 0x2d,0x39,0x27,0x36 },
-    { 0x0f,0xd9,0x64,0x0a }, { 0x5c,0xa6,0x21,0x68 },
-    { 0x5b,0x54,0xd1,0x9b }, { 0x36,0x2e,0x3a,0x24 },
-    { 0x0a,0x67,0xb1,0x0c }, { 0x57,0xe7,0x0f,0x93 },
-    { 0xee,0x96,0xd2,0xb4 }, { 0x9b,0x91,0x9e,0x1b },
-    { 0xc0,0xc5,0x4f,0x80 }, { 0xdc,0x20,0xa2,0x61 },
-    { 0x77,0x4b,0x69,0x5a }, { 0x12,0x1a,0x16,0x1c },
-    { 0x93,0xba,0x0a,0xe2 }, { 0xa0,0x2a,0xe5,0xc0 },
-    { 0x22,0xe0,0x43,0x3c }, { 0x1b,0x17,0x1d,0x12 },
-    { 0x09,0x0d,0x0b,0x0e }, { 0x8b,0xc7,0xad,0xf2 },
-    { 0xb6,0xa8,0xb9,0x2d }, { 0x1e,0xa9,0xc8,0x14 },
-    { 0xf1,0x19,0x85,0x57 }, { 0x75,0x07,0x4c,0xaf },
-    { 0x99,0xdd,0xbb,0xee }, { 0x7f,0x60,0xfd,0xa3 },
-    { 0x01,0x26,0x9f,0xf7 }, { 0x72,0xf5,0xbc,0x5c },
-    { 0x66,0x3b,0xc5,0x44 }, { 0xfb,0x7e,0x34,0x5b },
-    { 0x43,0x29,0x76,0x8b }, { 0x23,0xc6,0xdc,0xcb },
-    { 0xed,0xfc,0x68,0xb6 }, { 0xe4,0xf1,0x63,0xb8 },
-    { 0x31,0xdc,0xca,0xd7 }, { 0x63,0x85,0x10,0x42 },
-    { 0x97,0x22,0x40,0x13 }, { 0xc6,0x11,0x20,0x84 },
-    { 0x4a,0x24,0x7d,0x85 }, { 0xbb,0x3d,0xf8,0xd2 },
-    { 0xf9,0x32,0x11,0xae }, { 0x29,0xa1,0x6d,0xc7 },
-    { 0x9e,0x2f,0x4b,0x1d }, { 0xb2,0x30,0xf3,0xdc },
-    { 0x86,0x52,0xec,0x0d }, { 0xc1,0xe3,0xd0,0x77 },
-    { 0xb3,0x16,0x6c,0x2b }, { 0x70,0xb9,0x99,0xa9 },
-    { 0x94,0x48,0xfa,0x11 }, { 0xe9,0x64,0x22,0x47 },
-    { 0xfc,0x8c,0xc4,0xa8 }, { 0xf0,0x3f,0x1a,0xa0 },
-    { 0x7d,0x2c,0xd8,0x56 }, { 0x33,0x90,0xef,0x22 },
-    { 0x49,0x4e,0xc7,0x87 }, { 0x38,0xd1,0xc1,0xd9 },
-    { 0xca,0xa2,0xfe,0x8c }, { 0xd4,0x0b,0x36,0x98 },
-    { 0xf5,0x81,0xcf,0xa6 }, { 0x7a,0xde,0x28,0xa5 },
-    { 0xb7,0x8e,0x26,0xda }, { 0xad,0xbf,0xa4,0x3f },
-    { 0x3a,0x9d,0xe4,0x2c }, { 0x78,0x92,0x0d,0x50 },
-    { 0x5f,0xcc,0x9b,0x6a }, { 0x7e,0x46,0x62,0x54 },
-    { 0x8d,0x13,0xc2,0xf6 }, { 0xd8,0xb8,0xe8,0x90 },
-    { 0x39,0xf7,0x5e,0x2e }, { 0xc3,0xaf,0xf5,0x82 },
-    { 0x5d,0x80,0xbe,0x9f }, { 0xd0,0x93,0x7c,0x69 },
-    { 0xd5,0x2d,0xa9,0x6f }, { 0x25,0x12,0xb3,0xcf },
-    { 0xac,0x99,0x3b,0xc8 }, { 0x18,0x7d,0xa7,0x10 },
-    { 0x9c,0x63,0x6e,0xe8 }, { 0x3b,0xbb,0x7b,0xdb },
-    { 0x26,0x78,0x09,0xcd }, { 0x59,0x18,0xf4,0x6e },
-    { 0x9a,0xb7,0x01,0xec }, { 0x4f,0x9a,0xa8,0x83 },
-    { 0x95,0x6e,0x65,0xe6 }, { 0xff,0xe6,0x7e,0xaa },
-    { 0xbc,0xcf,0x08,0x21 }, { 0x15,0xe8,0xe6,0xef },
-    { 0xe7,0x9b,0xd9,0xba }, { 0x6f,0x36,0xce,0x4a },
-    { 0x9f,0x09,0xd4,0xea }, { 0xb0,0x7c,0xd6,0x29 },
-    { 0xa4,0xb2,0xaf,0x31 }, { 0x3f,0x23,0x31,0x2a },
-    { 0xa5,0x94,0x30,0xc6 }, { 0xa2,0x66,0xc0,0x35 },
-    { 0x4e,0xbc,0x37,0x74 }, { 0x82,0xca,0xa6,0xfc },
-    { 0x90,0xd0,0xb0,0xe0 }, { 0xa7,0xd8,0x15,0x33 },
-    { 0x04,0x98,0x4a,0xf1 }, { 0xec,0xda,0xf7,0x41 },
-    { 0xcd,0x50,0x0e,0x7f }, { 0x91,0xf6,0x2f,0x17 },
-    { 0x4d,0xd6,0x8d,0x76 }, { 0xef,0xb0,0x4d,0x43 },
-    { 0xaa,0x4d,0x54,0xcc }, { 0x96,0x04,0xdf,0xe4 },
-    { 0xd1,0xb5,0xe3,0x9e }, { 0x6a,0x88,0x1b,0x4c },
-    { 0x2c,0x1f,0xb8,0xc1 }, { 0x65,0x51,0x7f,0x46 },
-    { 0x5e,0xea,0x04,0x9d }, { 0x8c,0x35,0x5d,0x01 },
-    { 0x87,0x74,0x73,0xfa }, { 0x0b,0x41,0x2e,0xfb },
-    { 0x67,0x1d,0x5a,0xb3 }, { 0xdb,0xd2,0x52,0x92 },
-    { 0x10,0x56,0x33,0xe9 }, { 0xd6,0x47,0x13,0x6d },
-    { 0xd7,0x61,0x8c,0x9a }, { 0xa1,0x0c,0x7a,0x37 },
-    { 0xf8,0x14,0x8e,0x59 }, { 0x13,0x3c,0x89,0xeb },
-    { 0xa9,0x27,0xee,0xce }, { 0x61,0xc9,0x35,0xb7 },
-    { 0x1c,0xe5,0xed,0xe1 }, { 0x47,0xb1,0x3c,0x7a },
-    { 0xd2,0xdf,0x59,0x9c }, { 0xf2,0x73,0x3f,0x55 },
-    { 0x14,0xce,0x79,0x18 }, { 0xc7,0x37,0xbf,0x73 },
-    { 0xf7,0xcd,0xea,0x53 }, { 0xfd,0xaa,0x5b,0x5f },
-    { 0x3d,0x6f,0x14,0xdf }, { 0x44,0xdb,0x86,0x78 },
-    { 0xaf,0xf3,0x81,0xca }, { 0x68,0xc4,0x3e,0xb9 },
-    { 0x24,0x34,0x2c,0x38 }, { 0xa3,0x40,0x5f,0xc2 },
-    { 0x1d,0xc3,0x72,0x16 }, { 0xe2,0x25,0x0c,0xbc },
-    { 0x3c,0x49,0x8b,0x28 }, { 0x0d,0x95,0x41,0xff },
-    { 0xa8,0x01,0x71,0x39 }, { 0x0c,0xb3,0xde,0x08 },
-    { 0xb4,0xe4,0x9c,0xd8 }, { 0x56,0xc1,0x90,0x64 },
-    { 0xcb,0x84,0x61,0x7b }, { 0x32,0xb6,0x70,0xd5 },
-    { 0x6c,0x5c,0x74,0x48 }, { 0xb8,0x57,0x42,0xd0 }
-  };
-
-static const unsigned char S5[256] =
-  {
-    0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,
-    0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,
-    0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,
-    0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb,
-    0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,
-    0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e,
-    0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,
-    0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25,
-    0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,
-    0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92,
-    0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,
-    0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84,
-    0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,
-    0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06,
-    0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,
-    0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b,
-    0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,
-    0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73,
-    0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,
-    0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e,
-    0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,
-    0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b,
-    0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,
-    0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4,
-    0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,
-    0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f,
-    0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,
-    0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef,
-    0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,
-    0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61,
-    0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,
-    0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
-  };
-
-static const unsigned char U1[256][4] =
+static const struct
+{
+  u32 T[256];
+  byte inv_sbox[256];
+} dec_tables =
   {
-    { 0x00,0x00,0x00,0x00 }, { 0x0e,0x09,0x0d,0x0b },
-    { 0x1c,0x12,0x1a,0x16 }, { 0x12,0x1b,0x17,0x1d },
-    { 0x38,0x24,0x34,0x2c }, { 0x36,0x2d,0x39,0x27 },
-    { 0x24,0x36,0x2e,0x3a }, { 0x2a,0x3f,0x23,0x31 },
-    { 0x70,0x48,0x68,0x58 }, { 0x7e,0x41,0x65,0x53 },
-    { 0x6c,0x5a,0x72,0x4e }, { 0x62,0x53,0x7f,0x45 },
-    { 0x48,0x6c,0x5c,0x74 }, { 0x46,0x65,0x51,0x7f },
-    { 0x54,0x7e,0x46,0x62 }, { 0x5a,0x77,0x4b,0x69 },
-    { 0xe0,0x90,0xd0,0xb0 }, { 0xee,0x99,0xdd,0xbb },
-    { 0xfc,0x82,0xca,0xa6 }, { 0xf2,0x8b,0xc7,0xad },
-    { 0xd8,0xb4,0xe4,0x9c }, { 0xd6,0xbd,0xe9,0x97 },
-    { 0xc4,0xa6,0xfe,0x8a }, { 0xca,0xaf,0xf3,0x81 },
-    { 0x90,0xd8,0xb8,0xe8 }, { 0x9e,0xd1,0xb5,0xe3 },
-    { 0x8c,0xca,0xa2,0xfe }, { 0x82,0xc3,0xaf,0xf5 },
-    { 0xa8,0xfc,0x8c,0xc4 }, { 0xa6,0xf5,0x81,0xcf },
-    { 0xb4,0xee,0x96,0xd2 }, { 0xba,0xe7,0x9b,0xd9 },
-    { 0xdb,0x3b,0xbb,0x7b }, { 0xd5,0x32,0xb6,0x70 },
-    { 0xc7,0x29,0xa1,0x6d }, { 0xc9,0x20,0xac,0x66 },
-    { 0xe3,0x1f,0x8f,0x57 }, { 0xed,0x16,0x82,0x5c },
-    { 0xff,0x0d,0x95,0x41 }, { 0xf1,0x04,0x98,0x4a },
-    { 0xab,0x73,0xd3,0x23 }, { 0xa5,0x7a,0xde,0x28 },
-    { 0xb7,0x61,0xc9,0x35 }, { 0xb9,0x68,0xc4,0x3e },
-    { 0x93,0x57,0xe7,0x0f }, { 0x9d,0x5e,0xea,0x04 },
-    { 0x8f,0x45,0xfd,0x19 }, { 0x81,0x4c,0xf0,0x12 },
-    { 0x3b,0xab,0x6b,0xcb }, { 0x35,0xa2,0x66,0xc0 },
-    { 0x27,0xb9,0x71,0xdd }, { 0x29,0xb0,0x7c,0xd6 },
-    { 0x03,0x8f,0x5f,0xe7 }, { 0x0d,0x86,0x52,0xec },
-    { 0x1f,0x9d,0x45,0xf1 }, { 0x11,0x94,0x48,0xfa },
-    { 0x4b,0xe3,0x03,0x93 }, { 0x45,0xea,0x0e,0x98 },
-    { 0x57,0xf1,0x19,0x85 }, { 0x59,0xf8,0x14,0x8e },
-    { 0x73,0xc7,0x37,0xbf }, { 0x7d,0xce,0x3a,0xb4 },
-    { 0x6f,0xd5,0x2d,0xa9 }, { 0x61,0xdc,0x20,0xa2 },
-    { 0xad,0x76,0x6d,0xf6 }, { 0xa3,0x7f,0x60,0xfd },
-    { 0xb1,0x64,0x77,0xe0 }, { 0xbf,0x6d,0x7a,0xeb },
-    { 0x95,0x52,0x59,0xda }, { 0x9b,0x5b,0x54,0xd1 },
-    { 0x89,0x40,0x43,0xcc }, { 0x87,0x49,0x4e,0xc7 },
-    { 0xdd,0x3e,0x05,0xae }, { 0xd3,0x37,0x08,0xa5 },
-    { 0xc1,0x2c,0x1f,0xb8 }, { 0xcf,0x25,0x12,0xb3 },
-    { 0xe5,0x1a,0x31,0x82 }, { 0xeb,0x13,0x3c,0x89 },
-    { 0xf9,0x08,0x2b,0x94 }, { 0xf7,0x01,0x26,0x9f },
-    { 0x4d,0xe6,0xbd,0x46 }, { 0x43,0xef,0xb0,0x4d },
-    { 0x51,0xf4,0xa7,0x50 }, { 0x5f,0xfd,0xaa,0x5b },
-    { 0x75,0xc2,0x89,0x6a }, { 0x7b,0xcb,0x84,0x61 },
-    { 0x69,0xd0,0x93,0x7c }, { 0x67,0xd9,0x9e,0x77 },
-    { 0x3d,0xae,0xd5,0x1e }, { 0x33,0xa7,0xd8,0x15 },
-    { 0x21,0xbc,0xcf,0x08 }, { 0x2f,0xb5,0xc2,0x03 },
-    { 0x05,0x8a,0xe1,0x32 }, { 0x0b,0x83,0xec,0x39 },
-    { 0x19,0x98,0xfb,0x24 }, { 0x17,0x91,0xf6,0x2f },
-    { 0x76,0x4d,0xd6,0x8d }, { 0x78,0x44,0xdb,0x86 },
-    { 0x6a,0x5f,0xcc,0x9b }, { 0x64,0x56,0xc1,0x90 },
-    { 0x4e,0x69,0xe2,0xa1 }, { 0x40,0x60,0xef,0xaa },
-    { 0x52,0x7b,0xf8,0xb7 }, { 0x5c,0x72,0xf5,0xbc },
-    { 0x06,0x05,0xbe,0xd5 }, { 0x08,0x0c,0xb3,0xde },
-    { 0x1a,0x17,0xa4,0xc3 }, { 0x14,0x1e,0xa9,0xc8 },
-    { 0x3e,0x21,0x8a,0xf9 }, { 0x30,0x28,0x87,0xf2 },
-    { 0x22,0x33,0x90,0xef }, { 0x2c,0x3a,0x9d,0xe4 },
-    { 0x96,0xdd,0x06,0x3d }, { 0x98,0xd4,0x0b,0x36 },
-    { 0x8a,0xcf,0x1c,0x2b }, { 0x84,0xc6,0x11,0x20 },
-    { 0xae,0xf9,0x32,0x11 }, { 0xa0,0xf0,0x3f,0x1a },
-    { 0xb2,0xeb,0x28,0x07 }, { 0xbc,0xe2,0x25,0x0c },
-    { 0xe6,0x95,0x6e,0x65 }, { 0xe8,0x9c,0x63,0x6e },
-    { 0xfa,0x87,0x74,0x73 }, { 0xf4,0x8e,0x79,0x78 },
-    { 0xde,0xb1,0x5a,0x49 }, { 0xd0,0xb8,0x57,0x42 },
-    { 0xc2,0xa3,0x40,0x5f }, { 0xcc,0xaa,0x4d,0x54 },
-    { 0x41,0xec,0xda,0xf7 }, { 0x4f,0xe5,0xd7,0xfc },
-    { 0x5d,0xfe,0xc0,0xe1 }, { 0x53,0xf7,0xcd,0xea },
-    { 0x79,0xc8,0xee,0xdb }, { 0x77,0xc1,0xe3,0xd0 },
-    { 0x65,0xda,0xf4,0xcd }, { 0x6b,0xd3,0xf9,0xc6 },
-    { 0x31,0xa4,0xb2,0xaf }, { 0x3f,0xad,0xbf,0xa4 },
-    { 0x2d,0xb6,0xa8,0xb9 }, { 0x23,0xbf,0xa5,0xb2 },
-    { 0x09,0x80,0x86,0x83 }, { 0x07,0x89,0x8b,0x88 },
-    { 0x15,0x92,0x9c,0x95 }, { 0x1b,0x9b,0x91,0x9e },
-    { 0xa1,0x7c,0x0a,0x47 }, { 0xaf,0x75,0x07,0x4c },
-    { 0xbd,0x6e,0x10,0x51 }, { 0xb3,0x67,0x1d,0x5a },
-    { 0x99,0x58,0x3e,0x6b }, { 0x97,0x51,0x33,0x60 },
-    { 0x85,0x4a,0x24,0x7d }, { 0x8b,0x43,0x29,0x76 },
-    { 0xd1,0x34,0x62,0x1f }, { 0xdf,0x3d,0x6f,0x14 },
-    { 0xcd,0x26,0x78,0x09 }, { 0xc3,0x2f,0x75,0x02 },
-    { 0xe9,0x10,0x56,0x33 }, { 0xe7,0x19,0x5b,0x38 },
-    { 0xf5,0x02,0x4c,0x25 }, { 0xfb,0x0b,0x41,0x2e },
-    { 0x9a,0xd7,0x61,0x8c }, { 0x94,0xde,0x6c,0x87 },
-    { 0x86,0xc5,0x7b,0x9a }, { 0x88,0xcc,0x76,0x91 },
-    { 0xa2,0xf3,0x55,0xa0 }, { 0xac,0xfa,0x58,0xab },
-    { 0xbe,0xe1,0x4f,0xb6 }, { 0xb0,0xe8,0x42,0xbd },
-    { 0xea,0x9f,0x09,0xd4 }, { 0xe4,0x96,0x04,0xdf },
-    { 0xf6,0x8d,0x13,0xc2 }, { 0xf8,0x84,0x1e,0xc9 },
-    { 0xd2,0xbb,0x3d,0xf8 }, { 0xdc,0xb2,0x30,0xf3 },
-    { 0xce,0xa9,0x27,0xee }, { 0xc0,0xa0,0x2a,0xe5 },
-    { 0x7a,0x47,0xb1,0x3c }, { 0x74,0x4e,0xbc,0x37 },
-    { 0x66,0x55,0xab,0x2a }, { 0x68,0x5c,0xa6,0x21 },
-    { 0x42,0x63,0x85,0x10 }, { 0x4c,0x6a,0x88,0x1b },
-    { 0x5e,0x71,0x9f,0x06 }, { 0x50,0x78,0x92,0x0d },
-    { 0x0a,0x0f,0xd9,0x64 }, { 0x04,0x06,0xd4,0x6f },
-    { 0x16,0x1d,0xc3,0x72 }, { 0x18,0x14,0xce,0x79 },
-    { 0x32,0x2b,0xed,0x48 }, { 0x3c,0x22,0xe0,0x43 },
-    { 0x2e,0x39,0xf7,0x5e }, { 0x20,0x30,0xfa,0x55 },
-    { 0xec,0x9a,0xb7,0x01 }, { 0xe2,0x93,0xba,0x0a },
-    { 0xf0,0x88,0xad,0x17 }, { 0xfe,0x81,0xa0,0x1c },
-    { 0xd4,0xbe,0x83,0x2d }, { 0xda,0xb7,0x8e,0x26 },
-    { 0xc8,0xac,0x99,0x3b }, { 0xc6,0xa5,0x94,0x30 },
-    { 0x9c,0xd2,0xdf,0x59 }, { 0x92,0xdb,0xd2,0x52 },
-    { 0x80,0xc0,0xc5,0x4f }, { 0x8e,0xc9,0xc8,0x44 },
-    { 0xa4,0xf6,0xeb,0x75 }, { 0xaa,0xff,0xe6,0x7e },
-    { 0xb8,0xe4,0xf1,0x63 }, { 0xb6,0xed,0xfc,0x68 },
-    { 0x0c,0x0a,0x67,0xb1 }, { 0x02,0x03,0x6a,0xba },
-    { 0x10,0x18,0x7d,0xa7 }, { 0x1e,0x11,0x70,0xac },
-    { 0x34,0x2e,0x53,0x9d }, { 0x3a,0x27,0x5e,0x96 },
-    { 0x28,0x3c,0x49,0x8b }, { 0x26,0x35,0x44,0x80 },
-    { 0x7c,0x42,0x0f,0xe9 }, { 0x72,0x4b,0x02,0xe2 },
-    { 0x60,0x50,0x15,0xff }, { 0x6e,0x59,0x18,0xf4 },
-    { 0x44,0x66,0x3b,0xc5 }, { 0x4a,0x6f,0x36,0xce },
-    { 0x58,0x74,0x21,0xd3 }, { 0x56,0x7d,0x2c,0xd8 },
-    { 0x37,0xa1,0x0c,0x7a }, { 0x39,0xa8,0x01,0x71 },
-    { 0x2b,0xb3,0x16,0x6c }, { 0x25,0xba,0x1b,0x67 },
-    { 0x0f,0x85,0x38,0x56 }, { 0x01,0x8c,0x35,0x5d },
-    { 0x13,0x97,0x22,0x40 }, { 0x1d,0x9e,0x2f,0x4b },
-    { 0x47,0xe9,0x64,0x22 }, { 0x49,0xe0,0x69,0x29 },
-    { 0x5b,0xfb,0x7e,0x34 }, { 0x55,0xf2,0x73,0x3f },
-    { 0x7f,0xcd,0x50,0x0e }, { 0x71,0xc4,0x5d,0x05 },
-    { 0x63,0xdf,0x4a,0x18 }, { 0x6d,0xd6,0x47,0x13 },
-    { 0xd7,0x31,0xdc,0xca }, { 0xd9,0x38,0xd1,0xc1 },
-    { 0xcb,0x23,0xc6,0xdc }, { 0xc5,0x2a,0xcb,0xd7 },
-    { 0xef,0x15,0xe8,0xe6 }, { 0xe1,0x1c,0xe5,0xed },
-    { 0xf3,0x07,0xf2,0xf0 }, { 0xfd,0x0e,0xff,0xfb },
-    { 0xa7,0x79,0xb4,0x92 }, { 0xa9,0x70,0xb9,0x99 },
-    { 0xbb,0x6b,0xae,0x84 }, { 0xb5,0x62,0xa3,0x8f },
-    { 0x9f,0x5d,0x80,0xbe }, { 0x91,0x54,0x8d,0xb5 },
-    { 0x83,0x4f,0x9a,0xa8 }, { 0x8d,0x46,0x97,0xa3 }
+    {
+      0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a,
+      0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b,
+      0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5,
+      0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5,
+      0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d,
+      0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b,
+      0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295,
+      0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e,
+      0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927,
+      0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d,
+      0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362,
+      0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9,
+      0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52,
+      0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566,
+      0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3,
+      0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed,
+      0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e,
+      0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4,
+      0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4,
+      0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd,
+      0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d,
+      0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060,
+      0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967,
+      0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879,
+      0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000,
+      0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c,
+      0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36,
+      0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624,
+      0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b,
+      0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c,
+      0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12,
+      0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14,
+      0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3,
+      0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b,
+      0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8,
+      0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684,
+      0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7,
+      0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177,
+      0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947,
+      0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322,
+      0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498,
+      0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f,
+      0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54,
+      0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382,
+      0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf,
+      0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb,
+      0x097826cd, 0xf418596e, 0x01b79aec, 0xa89a4f83,
+      0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef,
+      0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029,
+      0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235,
+      0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733,
+      0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117,
+      0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4,
+      0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546,
+      0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb,
+      0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d,
+      0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb,
+      0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a,
+      0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773,
+      0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478,
+      0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2,
+      0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff,
+      0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664,
+      0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0
+    },
+    {
+      0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,
+      0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,
+      0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,
+      0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb,
+      0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,
+      0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e,
+      0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,
+      0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25,
+      0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,
+      0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92,
+      0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,
+      0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84,
+      0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,
+      0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06,
+      0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,
+      0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b,
+      0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,
+      0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73,
+      0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,
+      0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e,
+      0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,
+      0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b,
+      0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,
+      0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4,
+      0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,
+      0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f,
+      0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,
+      0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef,
+      0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,
+      0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61,
+      0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,
+      0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
+    }
   };
 
-static const unsigned char U2[256][4] =
-  {
-    { 0x00,0x00,0x00,0x00 }, { 0x0b,0x0e,0x09,0x0d },
-    { 0x16,0x1c,0x12,0x1a }, { 0x1d,0x12,0x1b,0x17 },
-    { 0x2c,0x38,0x24,0x34 }, { 0x27,0x36,0x2d,0x39 },
-    { 0x3a,0x24,0x36,0x2e }, { 0x31,0x2a,0x3f,0x23 },
-    { 0x58,0x70,0x48,0x68 }, { 0x53,0x7e,0x41,0x65 },
-    { 0x4e,0x6c,0x5a,0x72 }, { 0x45,0x62,0x53,0x7f },
-    { 0x74,0x48,0x6c,0x5c }, { 0x7f,0x46,0x65,0x51 },
-    { 0x62,0x54,0x7e,0x46 }, { 0x69,0x5a,0x77,0x4b },
-    { 0xb0,0xe0,0x90,0xd0 }, { 0xbb,0xee,0x99,0xdd },
-    { 0xa6,0xfc,0x82,0xca }, { 0xad,0xf2,0x8b,0xc7 },
-    { 0x9c,0xd8,0xb4,0xe4 }, { 0x97,0xd6,0xbd,0xe9 },
-    { 0x8a,0xc4,0xa6,0xfe }, { 0x81,0xca,0xaf,0xf3 },
-    { 0xe8,0x90,0xd8,0xb8 }, { 0xe3,0x9e,0xd1,0xb5 },
-    { 0xfe,0x8c,0xca,0xa2 }, { 0xf5,0x82,0xc3,0xaf },
-    { 0xc4,0xa8,0xfc,0x8c }, { 0xcf,0xa6,0xf5,0x81 },
-    { 0xd2,0xb4,0xee,0x96 }, { 0xd9,0xba,0xe7,0x9b },
-    { 0x7b,0xdb,0x3b,0xbb }, { 0x70,0xd5,0x32,0xb6 },
-    { 0x6d,0xc7,0x29,0xa1 }, { 0x66,0xc9,0x20,0xac },
-    { 0x57,0xe3,0x1f,0x8f }, { 0x5c,0xed,0x16,0x82 },
-    { 0x41,0xff,0x0d,0x95 }, { 0x4a,0xf1,0x04,0x98 },
-    { 0x23,0xab,0x73,0xd3 }, { 0x28,0xa5,0x7a,0xde },
-    { 0x35,0xb7,0x61,0xc9 }, { 0x3e,0xb9,0x68,0xc4 },
-    { 0x0f,0x93,0x57,0xe7 }, { 0x04,0x9d,0x5e,0xea },
-    { 0x19,0x8f,0x45,0xfd }, { 0x12,0x81,0x4c,0xf0 },
-    { 0xcb,0x3b,0xab,0x6b }, { 0xc0,0x35,0xa2,0x66 },
-    { 0xdd,0x27,0xb9,0x71 }, { 0xd6,0x29,0xb0,0x7c },
-    { 0xe7,0x03,0x8f,0x5f }, { 0xec,0x0d,0x86,0x52 },
-    { 0xf1,0x1f,0x9d,0x45 }, { 0xfa,0x11,0x94,0x48 },
-    { 0x93,0x4b,0xe3,0x03 }, { 0x98,0x45,0xea,0x0e },
-    { 0x85,0x57,0xf1,0x19 }, { 0x8e,0x59,0xf8,0x14 },
-    { 0xbf,0x73,0xc7,0x37 }, { 0xb4,0x7d,0xce,0x3a },
-    { 0xa9,0x6f,0xd5,0x2d }, { 0xa2,0x61,0xdc,0x20 },
-    { 0xf6,0xad,0x76,0x6d }, { 0xfd,0xa3,0x7f,0x60 },
-    { 0xe0,0xb1,0x64,0x77 }, { 0xeb,0xbf,0x6d,0x7a },
-    { 0xda,0x95,0x52,0x59 }, { 0xd1,0x9b,0x5b,0x54 },
-    { 0xcc,0x89,0x40,0x43 }, { 0xc7,0x87,0x49,0x4e },
-    { 0xae,0xdd,0x3e,0x05 }, { 0xa5,0xd3,0x37,0x08 },
-    { 0xb8,0xc1,0x2c,0x1f }, { 0xb3,0xcf,0x25,0x12 },
-    { 0x82,0xe5,0x1a,0x31 }, { 0x89,0xeb,0x13,0x3c },
-    { 0x94,0xf9,0x08,0x2b }, { 0x9f,0xf7,0x01,0x26 },
-    { 0x46,0x4d,0xe6,0xbd }, { 0x4d,0x43,0xef,0xb0 },
-    { 0x50,0x51,0xf4,0xa7 }, { 0x5b,0x5f,0xfd,0xaa },
-    { 0x6a,0x75,0xc2,0x89 }, { 0x61,0x7b,0xcb,0x84 },
-    { 0x7c,0x69,0xd0,0x93 }, { 0x77,0x67,0xd9,0x9e },
-    { 0x1e,0x3d,0xae,0xd5 }, { 0x15,0x33,0xa7,0xd8 },
-    { 0x08,0x21,0xbc,0xcf }, { 0x03,0x2f,0xb5,0xc2 },
-    { 0x32,0x05,0x8a,0xe1 }, { 0x39,0x0b,0x83,0xec },
-    { 0x24,0x19,0x98,0xfb }, { 0x2f,0x17,0x91,0xf6 },
-    { 0x8d,0x76,0x4d,0xd6 }, { 0x86,0x78,0x44,0xdb },
-    { 0x9b,0x6a,0x5f,0xcc }, { 0x90,0x64,0x56,0xc1 },
-    { 0xa1,0x4e,0x69,0xe2 }, { 0xaa,0x40,0x60,0xef },
-    { 0xb7,0x52,0x7b,0xf8 }, { 0xbc,0x5c,0x72,0xf5 },
-    { 0xd5,0x06,0x05,0xbe }, { 0xde,0x08,0x0c,0xb3 },
-    { 0xc3,0x1a,0x17,0xa4 }, { 0xc8,0x14,0x1e,0xa9 },
-    { 0xf9,0x3e,0x21,0x8a }, { 0xf2,0x30,0x28,0x87 },
-    { 0xef,0x22,0x33,0x90 }, { 0xe4,0x2c,0x3a,0x9d },
-    { 0x3d,0x96,0xdd,0x06 }, { 0x36,0x98,0xd4,0x0b },
-    { 0x2b,0x8a,0xcf,0x1c }, { 0x20,0x84,0xc6,0x11 },
-    { 0x11,0xae,0xf9,0x32 }, { 0x1a,0xa0,0xf0,0x3f },
-    { 0x07,0xb2,0xeb,0x28 }, { 0x0c,0xbc,0xe2,0x25 },
-    { 0x65,0xe6,0x95,0x6e }, { 0x6e,0xe8,0x9c,0x63 },
-    { 0x73,0xfa,0x87,0x74 }, { 0x78,0xf4,0x8e,0x79 },
-    { 0x49,0xde,0xb1,0x5a }, { 0x42,0xd0,0xb8,0x57 },
-    { 0x5f,0xc2,0xa3,0x40 }, { 0x54,0xcc,0xaa,0x4d },
-    { 0xf7,0x41,0xec,0xda }, { 0xfc,0x4f,0xe5,0xd7 },
-    { 0xe1,0x5d,0xfe,0xc0 }, { 0xea,0x53,0xf7,0xcd },
-    { 0xdb,0x79,0xc8,0xee }, { 0xd0,0x77,0xc1,0xe3 },
-    { 0xcd,0x65,0xda,0xf4 }, { 0xc6,0x6b,0xd3,0xf9 },
-    { 0xaf,0x31,0xa4,0xb2 }, { 0xa4,0x3f,0xad,0xbf },
-    { 0xb9,0x2d,0xb6,0xa8 }, { 0xb2,0x23,0xbf,0xa5 },
-    { 0x83,0x09,0x80,0x86 }, { 0x88,0x07,0x89,0x8b },
-    { 0x95,0x15,0x92,0x9c }, { 0x9e,0x1b,0x9b,0x91 },
-    { 0x47,0xa1,0x7c,0x0a }, { 0x4c,0xaf,0x75,0x07 },
-    { 0x51,0xbd,0x6e,0x10 }, { 0x5a,0xb3,0x67,0x1d },
-    { 0x6b,0x99,0x58,0x3e }, { 0x60,0x97,0x51,0x33 },
-    { 0x7d,0x85,0x4a,0x24 }, { 0x76,0x8b,0x43,0x29 },
-    { 0x1f,0xd1,0x34,0x62 }, { 0x14,0xdf,0x3d,0x6f },
-    { 0x09,0xcd,0x26,0x78 }, { 0x02,0xc3,0x2f,0x75 },
-    { 0x33,0xe9,0x10,0x56 }, { 0x38,0xe7,0x19,0x5b },
-    { 0x25,0xf5,0x02,0x4c }, { 0x2e,0xfb,0x0b,0x41 },
-    { 0x8c,0x9a,0xd7,0x61 }, { 0x87,0x94,0xde,0x6c },
-    { 0x9a,0x86,0xc5,0x7b }, { 0x91,0x88,0xcc,0x76 },
-    { 0xa0,0xa2,0xf3,0x55 }, { 0xab,0xac,0xfa,0x58 },
-    { 0xb6,0xbe,0xe1,0x4f }, { 0xbd,0xb0,0xe8,0x42 },
-    { 0xd4,0xea,0x9f,0x09 }, { 0xdf,0xe4,0x96,0x04 },
-    { 0xc2,0xf6,0x8d,0x13 }, { 0xc9,0xf8,0x84,0x1e },
-    { 0xf8,0xd2,0xbb,0x3d }, { 0xf3,0xdc,0xb2,0x30 },
-    { 0xee,0xce,0xa9,0x27 }, { 0xe5,0xc0,0xa0,0x2a },
-    { 0x3c,0x7a,0x47,0xb1 }, { 0x37,0x74,0x4e,0xbc },
-    { 0x2a,0x66,0x55,0xab }, { 0x21,0x68,0x5c,0xa6 },
-    { 0x10,0x42,0x63,0x85 }, { 0x1b,0x4c,0x6a,0x88 },
-    { 0x06,0x5e,0x71,0x9f }, { 0x0d,0x50,0x78,0x92 },
-    { 0x64,0x0a,0x0f,0xd9 }, { 0x6f,0x04,0x06,0xd4 },
-    { 0x72,0x16,0x1d,0xc3 }, { 0x79,0x18,0x14,0xce },
-    { 0x48,0x32,0x2b,0xed }, { 0x43,0x3c,0x22,0xe0 },
-    { 0x5e,0x2e,0x39,0xf7 }, { 0x55,0x20,0x30,0xfa },
-    { 0x01,0xec,0x9a,0xb7 }, { 0x0a,0xe2,0x93,0xba },
-    { 0x17,0xf0,0x88,0xad }, { 0x1c,0xfe,0x81,0xa0 },
-    { 0x2d,0xd4,0xbe,0x83 }, { 0x26,0xda,0xb7,0x8e },
-    { 0x3b,0xc8,0xac,0x99 }, { 0x30,0xc6,0xa5,0x94 },
-    { 0x59,0x9c,0xd2,0xdf }, { 0x52,0x92,0xdb,0xd2 },
-    { 0x4f,0x80,0xc0,0xc5 }, { 0x44,0x8e,0xc9,0xc8 },
-    { 0x75,0xa4,0xf6,0xeb }, { 0x7e,0xaa,0xff,0xe6 },
-    { 0x63,0xb8,0xe4,0xf1 }, { 0x68,0xb6,0xed,0xfc },
-    { 0xb1,0x0c,0x0a,0x67 }, { 0xba,0x02,0x03,0x6a },
-    { 0xa7,0x10,0x18,0x7d }, { 0xac,0x1e,0x11,0x70 },
-    { 0x9d,0x34,0x2e,0x53 }, { 0x96,0x3a,0x27,0x5e },
-    { 0x8b,0x28,0x3c,0x49 }, { 0x80,0x26,0x35,0x44 },
-    { 0xe9,0x7c,0x42,0x0f }, { 0xe2,0x72,0x4b,0x02 },
-    { 0xff,0x60,0x50,0x15 }, { 0xf4,0x6e,0x59,0x18 },
-    { 0xc5,0x44,0x66,0x3b }, { 0xce,0x4a,0x6f,0x36 },
-    { 0xd3,0x58,0x74,0x21 }, { 0xd8,0x56,0x7d,0x2c },
-    { 0x7a,0x37,0xa1,0x0c }, { 0x71,0x39,0xa8,0x01 },
-    { 0x6c,0x2b,0xb3,0x16 }, { 0x67,0x25,0xba,0x1b },
-    { 0x56,0x0f,0x85,0x38 }, { 0x5d,0x01,0x8c,0x35 },
-    { 0x40,0x13,0x97,0x22 }, { 0x4b,0x1d,0x9e,0x2f },
-    { 0x22,0x47,0xe9,0x64 }, { 0x29,0x49,0xe0,0x69 },
-    { 0x34,0x5b,0xfb,0x7e }, { 0x3f,0x55,0xf2,0x73 },
-    { 0x0e,0x7f,0xcd,0x50 }, { 0x05,0x71,0xc4,0x5d },
-    { 0x18,0x63,0xdf,0x4a }, { 0x13,0x6d,0xd6,0x47 },
-    { 0xca,0xd7,0x31,0xdc }, { 0xc1,0xd9,0x38,0xd1 },
-    { 0xdc,0xcb,0x23,0xc6 }, { 0xd7,0xc5,0x2a,0xcb },
-    { 0xe6,0xef,0x15,0xe8 }, { 0xed,0xe1,0x1c,0xe5 },
-    { 0xf0,0xf3,0x07,0xf2 }, { 0xfb,0xfd,0x0e,0xff },
-    { 0x92,0xa7,0x79,0xb4 }, { 0x99,0xa9,0x70,0xb9 },
-    { 0x84,0xbb,0x6b,0xae }, { 0x8f,0xb5,0x62,0xa3 },
-    { 0xbe,0x9f,0x5d,0x80 }, { 0xb5,0x91,0x54,0x8d },
-    { 0xa8,0x83,0x4f,0x9a }, { 0xa3,0x8d,0x46,0x97 }
-  };
-
-static const unsigned char U3[256][4] =
-  {
-    { 0x00,0x00,0x00,0x00 }, { 0x0d,0x0b,0x0e,0x09 },
-    { 0x1a,0x16,0x1c,0x12 }, { 0x17,0x1d,0x12,0x1b },
-    { 0x34,0x2c,0x38,0x24 }, { 0x39,0x27,0x36,0x2d },
-    { 0x2e,0x3a,0x24,0x36 }, { 0x23,0x31,0x2a,0x3f },
-    { 0x68,0x58,0x70,0x48 }, { 0x65,0x53,0x7e,0x41 },
-    { 0x72,0x4e,0x6c,0x5a }, { 0x7f,0x45,0x62,0x53 },
-    { 0x5c,0x74,0x48,0x6c }, { 0x51,0x7f,0x46,0x65 },
-    { 0x46,0x62,0x54,0x7e }, { 0x4b,0x69,0x5a,0x77 },
-    { 0xd0,0xb0,0xe0,0x90 }, { 0xdd,0xbb,0xee,0x99 },
-    { 0xca,0xa6,0xfc,0x82 }, { 0xc7,0xad,0xf2,0x8b },
-    { 0xe4,0x9c,0xd8,0xb4 }, { 0xe9,0x97,0xd6,0xbd },
-    { 0xfe,0x8a,0xc4,0xa6 }, { 0xf3,0x81,0xca,0xaf },
-    { 0xb8,0xe8,0x90,0xd8 }, { 0xb5,0xe3,0x9e,0xd1 },
-    { 0xa2,0xfe,0x8c,0xca }, { 0xaf,0xf5,0x82,0xc3 },
-    { 0x8c,0xc4,0xa8,0xfc }, { 0x81,0xcf,0xa6,0xf5 },
-    { 0x96,0xd2,0xb4,0xee }, { 0x9b,0xd9,0xba,0xe7 },
-    { 0xbb,0x7b,0xdb,0x3b }, { 0xb6,0x70,0xd5,0x32 },
-    { 0xa1,0x6d,0xc7,0x29 }, { 0xac,0x66,0xc9,0x20 },
-    { 0x8f,0x57,0xe3,0x1f }, { 0x82,0x5c,0xed,0x16 },
-    { 0x95,0x41,0xff,0x0d }, { 0x98,0x4a,0xf1,0x04 },
-    { 0xd3,0x23,0xab,0x73 }, { 0xde,0x28,0xa5,0x7a },
-    { 0xc9,0x35,0xb7,0x61 }, { 0xc4,0x3e,0xb9,0x68 },
-    { 0xe7,0x0f,0x93,0x57 }, { 0xea,0x04,0x9d,0x5e },
-    { 0xfd,0x19,0x8f,0x45 }, { 0xf0,0x12,0x81,0x4c },
-    { 0x6b,0xcb,0x3b,0xab }, { 0x66,0xc0,0x35,0xa2 },
-    { 0x71,0xdd,0x27,0xb9 }, { 0x7c,0xd6,0x29,0xb0 },
-    { 0x5f,0xe7,0x03,0x8f }, { 0x52,0xec,0x0d,0x86 },
-    { 0x45,0xf1,0x1f,0x9d }, { 0x48,0xfa,0x11,0x94 },
-    { 0x03,0x93,0x4b,0xe3 }, { 0x0e,0x98,0x45,0xea },
-    { 0x19,0x85,0x57,0xf1 }, { 0x14,0x8e,0x59,0xf8 },
-    { 0x37,0xbf,0x73,0xc7 }, { 0x3a,0xb4,0x7d,0xce },
-    { 0x2d,0xa9,0x6f,0xd5 }, { 0x20,0xa2,0x61,0xdc },
-    { 0x6d,0xf6,0xad,0x76 }, { 0x60,0xfd,0xa3,0x7f },
-    { 0x77,0xe0,0xb1,0x64 }, { 0x7a,0xeb,0xbf,0x6d },
-    { 0x59,0xda,0x95,0x52 }, { 0x54,0xd1,0x9b,0x5b },
-    { 0x43,0xcc,0x89,0x40 }, { 0x4e,0xc7,0x87,0x49 },
-    { 0x05,0xae,0xdd,0x3e }, { 0x08,0xa5,0xd3,0x37 },
-    { 0x1f,0xb8,0xc1,0x2c }, { 0x12,0xb3,0xcf,0x25 },
-    { 0x31,0x82,0xe5,0x1a }, { 0x3c,0x89,0xeb,0x13 },
-    { 0x2b,0x94,0xf9,0x08 }, { 0x26,0x9f,0xf7,0x01 },
-    { 0xbd,0x46,0x4d,0xe6 }, { 0xb0,0x4d,0x43,0xef },
-    { 0xa7,0x50,0x51,0xf4 }, { 0xaa,0x5b,0x5f,0xfd },
-    { 0x89,0x6a,0x75,0xc2 }, { 0x84,0x61,0x7b,0xcb },
-    { 0x93,0x7c,0x69,0xd0 }, { 0x9e,0x77,0x67,0xd9 },
-    { 0xd5,0x1e,0x3d,0xae }, { 0xd8,0x15,0x33,0xa7 },
-    { 0xcf,0x08,0x21,0xbc }, { 0xc2,0x03,0x2f,0xb5 },
-    { 0xe1,0x32,0x05,0x8a }, { 0xec,0x39,0x0b,0x83 },
-    { 0xfb,0x24,0x19,0x98 }, { 0xf6,0x2f,0x17,0x91 },
-    { 0xd6,0x8d,0x76,0x4d }, { 0xdb,0x86,0x78,0x44 },
-    { 0xcc,0x9b,0x6a,0x5f }, { 0xc1,0x90,0x64,0x56 },
-    { 0xe2,0xa1,0x4e,0x69 }, { 0xef,0xaa,0x40,0x60 },
-    { 0xf8,0xb7,0x52,0x7b }, { 0xf5,0xbc,0x5c,0x72 },
-    { 0xbe,0xd5,0x06,0x05 }, { 0xb3,0xde,0x08,0x0c },
-    { 0xa4,0xc3,0x1a,0x17 }, { 0xa9,0xc8,0x14,0x1e },
-    { 0x8a,0xf9,0x3e,0x21 }, { 0x87,0xf2,0x30,0x28 },
-    { 0x90,0xef,0x22,0x33 }, { 0x9d,0xe4,0x2c,0x3a },
-    { 0x06,0x3d,0x96,0xdd }, { 0x0b,0x36,0x98,0xd4 },
-    { 0x1c,0x2b,0x8a,0xcf }, { 0x11,0x20,0x84,0xc6 },
-    { 0x32,0x11,0xae,0xf9 }, { 0x3f,0x1a,0xa0,0xf0 },
-    { 0x28,0x07,0xb2,0xeb }, { 0x25,0x0c,0xbc,0xe2 },
-    { 0x6e,0x65,0xe6,0x95 }, { 0x63,0x6e,0xe8,0x9c },
-    { 0x74,0x73,0xfa,0x87 }, { 0x79,0x78,0xf4,0x8e },
-    { 0x5a,0x49,0xde,0xb1 }, { 0x57,0x42,0xd0,0xb8 },
-    { 0x40,0x5f,0xc2,0xa3 }, { 0x4d,0x54,0xcc,0xaa },
-    { 0xda,0xf7,0x41,0xec }, { 0xd7,0xfc,0x4f,0xe5 },
-    { 0xc0,0xe1,0x5d,0xfe }, { 0xcd,0xea,0x53,0xf7 },
-    { 0xee,0xdb,0x79,0xc8 }, { 0xe3,0xd0,0x77,0xc1 },
-    { 0xf4,0xcd,0x65,0xda }, { 0xf9,0xc6,0x6b,0xd3 },
-    { 0xb2,0xaf,0x31,0xa4 }, { 0xbf,0xa4,0x3f,0xad },
-    { 0xa8,0xb9,0x2d,0xb6 }, { 0xa5,0xb2,0x23,0xbf },
-    { 0x86,0x83,0x09,0x80 }, { 0x8b,0x88,0x07,0x89 },
-    { 0x9c,0x95,0x15,0x92 }, { 0x91,0x9e,0x1b,0x9b },
-    { 0x0a,0x47,0xa1,0x7c }, { 0x07,0x4c,0xaf,0x75 },
-    { 0x10,0x51,0xbd,0x6e }, { 0x1d,0x5a,0xb3,0x67 },
-    { 0x3e,0x6b,0x99,0x58 }, { 0x33,0x60,0x97,0x51 },
-    { 0x24,0x7d,0x85,0x4a }, { 0x29,0x76,0x8b,0x43 },
-    { 0x62,0x1f,0xd1,0x34 }, { 0x6f,0x14,0xdf,0x3d },
-    { 0x78,0x09,0xcd,0x26 }, { 0x75,0x02,0xc3,0x2f },
-    { 0x56,0x33,0xe9,0x10 }, { 0x5b,0x38,0xe7,0x19 },
-    { 0x4c,0x25,0xf5,0x02 }, { 0x41,0x2e,0xfb,0x0b },
-    { 0x61,0x8c,0x9a,0xd7 }, { 0x6c,0x87,0x94,0xde },
-    { 0x7b,0x9a,0x86,0xc5 }, { 0x76,0x91,0x88,0xcc },
-    { 0x55,0xa0,0xa2,0xf3 }, { 0x58,0xab,0xac,0xfa },
-    { 0x4f,0xb6,0xbe,0xe1 }, { 0x42,0xbd,0xb0,0xe8 },
-    { 0x09,0xd4,0xea,0x9f }, { 0x04,0xdf,0xe4,0x96 },
-    { 0x13,0xc2,0xf6,0x8d }, { 0x1e,0xc9,0xf8,0x84 },
-    { 0x3d,0xf8,0xd2,0xbb }, { 0x30,0xf3,0xdc,0xb2 },
-    { 0x27,0xee,0xce,0xa9 }, { 0x2a,0xe5,0xc0,0xa0 },
-    { 0xb1,0x3c,0x7a,0x47 }, { 0xbc,0x37,0x74,0x4e },
-    { 0xab,0x2a,0x66,0x55 }, { 0xa6,0x21,0x68,0x5c },
-    { 0x85,0x10,0x42,0x63 }, { 0x88,0x1b,0x4c,0x6a },
-    { 0x9f,0x06,0x5e,0x71 }, { 0x92,0x0d,0x50,0x78 },
-    { 0xd9,0x64,0x0a,0x0f }, { 0xd4,0x6f,0x04,0x06 },
-    { 0xc3,0x72,0x16,0x1d }, { 0xce,0x79,0x18,0x14 },
-    { 0xed,0x48,0x32,0x2b }, { 0xe0,0x43,0x3c,0x22 },
-    { 0xf7,0x5e,0x2e,0x39 }, { 0xfa,0x55,0x20,0x30 },
-    { 0xb7,0x01,0xec,0x9a }, { 0xba,0x0a,0xe2,0x93 },
-    { 0xad,0x17,0xf0,0x88 }, { 0xa0,0x1c,0xfe,0x81 },
-    { 0x83,0x2d,0xd4,0xbe }, { 0x8e,0x26,0xda,0xb7 },
-    { 0x99,0x3b,0xc8,0xac }, { 0x94,0x30,0xc6,0xa5 },
-    { 0xdf,0x59,0x9c,0xd2 }, { 0xd2,0x52,0x92,0xdb },
-    { 0xc5,0x4f,0x80,0xc0 }, { 0xc8,0x44,0x8e,0xc9 },
-    { 0xeb,0x75,0xa4,0xf6 }, { 0xe6,0x7e,0xaa,0xff },
-    { 0xf1,0x63,0xb8,0xe4 }, { 0xfc,0x68,0xb6,0xed },
-    { 0x67,0xb1,0x0c,0x0a }, { 0x6a,0xba,0x02,0x03 },
-    { 0x7d,0xa7,0x10,0x18 }, { 0x70,0xac,0x1e,0x11 },
-    { 0x53,0x9d,0x34,0x2e }, { 0x5e,0x96,0x3a,0x27 },
-    { 0x49,0x8b,0x28,0x3c }, { 0x44,0x80,0x26,0x35 },
-    { 0x0f,0xe9,0x7c,0x42 }, { 0x02,0xe2,0x72,0x4b },
-    { 0x15,0xff,0x60,0x50 }, { 0x18,0xf4,0x6e,0x59 },
-    { 0x3b,0xc5,0x44,0x66 }, { 0x36,0xce,0x4a,0x6f },
-    { 0x21,0xd3,0x58,0x74 }, { 0x2c,0xd8,0x56,0x7d },
-    { 0x0c,0x7a,0x37,0xa1 }, { 0x01,0x71,0x39,0xa8 },
-    { 0x16,0x6c,0x2b,0xb3 }, { 0x1b,0x67,0x25,0xba },
-    { 0x38,0x56,0x0f,0x85 }, { 0x35,0x5d,0x01,0x8c },
-    { 0x22,0x40,0x13,0x97 }, { 0x2f,0x4b,0x1d,0x9e },
-    { 0x64,0x22,0x47,0xe9 }, { 0x69,0x29,0x49,0xe0 },
-    { 0x7e,0x34,0x5b,0xfb }, { 0x73,0x3f,0x55,0xf2 },
-    { 0x50,0x0e,0x7f,0xcd }, { 0x5d,0x05,0x71,0xc4 },
-    { 0x4a,0x18,0x63,0xdf }, { 0x47,0x13,0x6d,0xd6 },
-    { 0xdc,0xca,0xd7,0x31 }, { 0xd1,0xc1,0xd9,0x38 },
-    { 0xc6,0xdc,0xcb,0x23 }, { 0xcb,0xd7,0xc5,0x2a },
-    { 0xe8,0xe6,0xef,0x15 }, { 0xe5,0xed,0xe1,0x1c },
-    { 0xf2,0xf0,0xf3,0x07 }, { 0xff,0xfb,0xfd,0x0e },
-    { 0xb4,0x92,0xa7,0x79 }, { 0xb9,0x99,0xa9,0x70 },
-    { 0xae,0x84,0xbb,0x6b }, { 0xa3,0x8f,0xb5,0x62 },
-    { 0x80,0xbe,0x9f,0x5d }, { 0x8d,0xb5,0x91,0x54 },
-    { 0x9a,0xa8,0x83,0x4f }, { 0x97,0xa3,0x8d,0x46 }
-  };
-
-static const unsigned char U4[256][4] =
-  {
-    { 0x00,0x00,0x00,0x00 }, { 0x09,0x0d,0x0b,0x0e },
-    { 0x12,0x1a,0x16,0x1c }, { 0x1b,0x17,0x1d,0x12 },
-    { 0x24,0x34,0x2c,0x38 }, { 0x2d,0x39,0x27,0x36 },
-    { 0x36,0x2e,0x3a,0x24 }, { 0x3f,0x23,0x31,0x2a },
-    { 0x48,0x68,0x58,0x70 }, { 0x41,0x65,0x53,0x7e },
-    { 0x5a,0x72,0x4e,0x6c }, { 0x53,0x7f,0x45,0x62 },
-    { 0x6c,0x5c,0x74,0x48 }, { 0x65,0x51,0x7f,0x46 },
-    { 0x7e,0x46,0x62,0x54 }, { 0x77,0x4b,0x69,0x5a },
-    { 0x90,0xd0,0xb0,0xe0 }, { 0x99,0xdd,0xbb,0xee },
-    { 0x82,0xca,0xa6,0xfc }, { 0x8b,0xc7,0xad,0xf2 },
-    { 0xb4,0xe4,0x9c,0xd8 }, { 0xbd,0xe9,0x97,0xd6 },
-    { 0xa6,0xfe,0x8a,0xc4 }, { 0xaf,0xf3,0x81,0xca },
-    { 0xd8,0xb8,0xe8,0x90 }, { 0xd1,0xb5,0xe3,0x9e },
-    { 0xca,0xa2,0xfe,0x8c }, { 0xc3,0xaf,0xf5,0x82 },
-    { 0xfc,0x8c,0xc4,0xa8 }, { 0xf5,0x81,0xcf,0xa6 },
-    { 0xee,0x96,0xd2,0xb4 }, { 0xe7,0x9b,0xd9,0xba },
-    { 0x3b,0xbb,0x7b,0xdb }, { 0x32,0xb6,0x70,0xd5 },
-    { 0x29,0xa1,0x6d,0xc7 }, { 0x20,0xac,0x66,0xc9 },
-    { 0x1f,0x8f,0x57,0xe3 }, { 0x16,0x82,0x5c,0xed },
-    { 0x0d,0x95,0x41,0xff }, { 0x04,0x98,0x4a,0xf1 },
-    { 0x73,0xd3,0x23,0xab }, { 0x7a,0xde,0x28,0xa5 },
-    { 0x61,0xc9,0x35,0xb7 }, { 0x68,0xc4,0x3e,0xb9 },
-    { 0x57,0xe7,0x0f,0x93 }, { 0x5e,0xea,0x04,0x9d },
-    { 0x45,0xfd,0x19,0x8f }, { 0x4c,0xf0,0x12,0x81 },
-    { 0xab,0x6b,0xcb,0x3b }, { 0xa2,0x66,0xc0,0x35 },
-    { 0xb9,0x71,0xdd,0x27 }, { 0xb0,0x7c,0xd6,0x29 },
-    { 0x8f,0x5f,0xe7,0x03 }, { 0x86,0x52,0xec,0x0d },
-    { 0x9d,0x45,0xf1,0x1f }, { 0x94,0x48,0xfa,0x11 },
-    { 0xe3,0x03,0x93,0x4b }, { 0xea,0x0e,0x98,0x45 },
-    { 0xf1,0x19,0x85,0x57 }, { 0xf8,0x14,0x8e,0x59 },
-    { 0xc7,0x37,0xbf,0x73 }, { 0xce,0x3a,0xb4,0x7d },
-    { 0xd5,0x2d,0xa9,0x6f }, { 0xdc,0x20,0xa2,0x61 },
-    { 0x76,0x6d,0xf6,0xad }, { 0x7f,0x60,0xfd,0xa3 },
-    { 0x64,0x77,0xe0,0xb1 }, { 0x6d,0x7a,0xeb,0xbf },
-    { 0x52,0x59,0xda,0x95 }, { 0x5b,0x54,0xd1,0x9b },
-    { 0x40,0x43,0xcc,0x89 }, { 0x49,0x4e,0xc7,0x87 },
-    { 0x3e,0x05,0xae,0xdd }, { 0x37,0x08,0xa5,0xd3 },
-    { 0x2c,0x1f,0xb8,0xc1 }, { 0x25,0x12,0xb3,0xcf },
-    { 0x1a,0x31,0x82,0xe5 }, { 0x13,0x3c,0x89,0xeb },
-    { 0x08,0x2b,0x94,0xf9 }, { 0x01,0x26,0x9f,0xf7 },
-    { 0xe6,0xbd,0x46,0x4d }, { 0xef,0xb0,0x4d,0x43 },
-    { 0xf4,0xa7,0x50,0x51 }, { 0xfd,0xaa,0x5b,0x5f },
-    { 0xc2,0x89,0x6a,0x75 }, { 0xcb,0x84,0x61,0x7b },
-    { 0xd0,0x93,0x7c,0x69 }, { 0xd9,0x9e,0x77,0x67 },
-    { 0xae,0xd5,0x1e,0x3d }, { 0xa7,0xd8,0x15,0x33 },
-    { 0xbc,0xcf,0x08,0x21 }, { 0xb5,0xc2,0x03,0x2f },
-    { 0x8a,0xe1,0x32,0x05 }, { 0x83,0xec,0x39,0x0b },
-    { 0x98,0xfb,0x24,0x19 }, { 0x91,0xf6,0x2f,0x17 },
-    { 0x4d,0xd6,0x8d,0x76 }, { 0x44,0xdb,0x86,0x78 },
-    { 0x5f,0xcc,0x9b,0x6a }, { 0x56,0xc1,0x90,0x64 },
-    { 0x69,0xe2,0xa1,0x4e }, { 0x60,0xef,0xaa,0x40 },
-    { 0x7b,0xf8,0xb7,0x52 }, { 0x72,0xf5,0xbc,0x5c },
-    { 0x05,0xbe,0xd5,0x06 }, { 0x0c,0xb3,0xde,0x08 },
-    { 0x17,0xa4,0xc3,0x1a }, { 0x1e,0xa9,0xc8,0x14 },
-    { 0x21,0x8a,0xf9,0x3e }, { 0x28,0x87,0xf2,0x30 },
-    { 0x33,0x90,0xef,0x22 }, { 0x3a,0x9d,0xe4,0x2c },
-    { 0xdd,0x06,0x3d,0x96 }, { 0xd4,0x0b,0x36,0x98 },
-    { 0xcf,0x1c,0x2b,0x8a }, { 0xc6,0x11,0x20,0x84 },
-    { 0xf9,0x32,0x11,0xae }, { 0xf0,0x3f,0x1a,0xa0 },
-    { 0xeb,0x28,0x07,0xb2 }, { 0xe2,0x25,0x0c,0xbc },
-    { 0x95,0x6e,0x65,0xe6 }, { 0x9c,0x63,0x6e,0xe8 },
-    { 0x87,0x74,0x73,0xfa }, { 0x8e,0x79,0x78,0xf4 },
-    { 0xb1,0x5a,0x49,0xde }, { 0xb8,0x57,0x42,0xd0 },
-    { 0xa3,0x40,0x5f,0xc2 }, { 0xaa,0x4d,0x54,0xcc },
-    { 0xec,0xda,0xf7,0x41 }, { 0xe5,0xd7,0xfc,0x4f },
-    { 0xfe,0xc0,0xe1,0x5d }, { 0xf7,0xcd,0xea,0x53 },
-    { 0xc8,0xee,0xdb,0x79 }, { 0xc1,0xe3,0xd0,0x77 },
-    { 0xda,0xf4,0xcd,0x65 }, { 0xd3,0xf9,0xc6,0x6b },
-    { 0xa4,0xb2,0xaf,0x31 }, { 0xad,0xbf,0xa4,0x3f },
-    { 0xb6,0xa8,0xb9,0x2d }, { 0xbf,0xa5,0xb2,0x23 },
-    { 0x80,0x86,0x83,0x09 }, { 0x89,0x8b,0x88,0x07 },
-    { 0x92,0x9c,0x95,0x15 }, { 0x9b,0x91,0x9e,0x1b },
-    { 0x7c,0x0a,0x47,0xa1 }, { 0x75,0x07,0x4c,0xaf },
-    { 0x6e,0x10,0x51,0xbd }, { 0x67,0x1d,0x5a,0xb3 },
-    { 0x58,0x3e,0x6b,0x99 }, { 0x51,0x33,0x60,0x97 },
-    { 0x4a,0x24,0x7d,0x85 }, { 0x43,0x29,0x76,0x8b },
-    { 0x34,0x62,0x1f,0xd1 }, { 0x3d,0x6f,0x14,0xdf },
-    { 0x26,0x78,0x09,0xcd }, { 0x2f,0x75,0x02,0xc3 },
-    { 0x10,0x56,0x33,0xe9 }, { 0x19,0x5b,0x38,0xe7 },
-    { 0x02,0x4c,0x25,0xf5 }, { 0x0b,0x41,0x2e,0xfb },
-    { 0xd7,0x61,0x8c,0x9a }, { 0xde,0x6c,0x87,0x94 },
-    { 0xc5,0x7b,0x9a,0x86 }, { 0xcc,0x76,0x91,0x88 },
-    { 0xf3,0x55,0xa0,0xa2 }, { 0xfa,0x58,0xab,0xac },
-    { 0xe1,0x4f,0xb6,0xbe }, { 0xe8,0x42,0xbd,0xb0 },
-    { 0x9f,0x09,0xd4,0xea }, { 0x96,0x04,0xdf,0xe4 },
-    { 0x8d,0x13,0xc2,0xf6 }, { 0x84,0x1e,0xc9,0xf8 },
-    { 0xbb,0x3d,0xf8,0xd2 }, { 0xb2,0x30,0xf3,0xdc },
-    { 0xa9,0x27,0xee,0xce }, { 0xa0,0x2a,0xe5,0xc0 },
-    { 0x47,0xb1,0x3c,0x7a }, { 0x4e,0xbc,0x37,0x74 },
-    { 0x55,0xab,0x2a,0x66 }, { 0x5c,0xa6,0x21,0x68 },
-    { 0x63,0x85,0x10,0x42 }, { 0x6a,0x88,0x1b,0x4c },
-    { 0x71,0x9f,0x06,0x5e }, { 0x78,0x92,0x0d,0x50 },
-    { 0x0f,0xd9,0x64,0x0a }, { 0x06,0xd4,0x6f,0x04 },
-    { 0x1d,0xc3,0x72,0x16 }, { 0x14,0xce,0x79,0x18 },
-    { 0x2b,0xed,0x48,0x32 }, { 0x22,0xe0,0x43,0x3c },
-    { 0x39,0xf7,0x5e,0x2e }, { 0x30,0xfa,0x55,0x20 },
-    { 0x9a,0xb7,0x01,0xec }, { 0x93,0xba,0x0a,0xe2 },
-    { 0x88,0xad,0x17,0xf0 }, { 0x81,0xa0,0x1c,0xfe },
-    { 0xbe,0x83,0x2d,0xd4 }, { 0xb7,0x8e,0x26,0xda },
-    { 0xac,0x99,0x3b,0xc8 }, { 0xa5,0x94,0x30,0xc6 },
-    { 0xd2,0xdf,0x59,0x9c }, { 0xdb,0xd2,0x52,0x92 },
-    { 0xc0,0xc5,0x4f,0x80 }, { 0xc9,0xc8,0x44,0x8e },
-    { 0xf6,0xeb,0x75,0xa4 }, { 0xff,0xe6,0x7e,0xaa },
-    { 0xe4,0xf1,0x63,0xb8 }, { 0xed,0xfc,0x68,0xb6 },
-    { 0x0a,0x67,0xb1,0x0c }, { 0x03,0x6a,0xba,0x02 },
-    { 0x18,0x7d,0xa7,0x10 }, { 0x11,0x70,0xac,0x1e },
-    { 0x2e,0x53,0x9d,0x34 }, { 0x27,0x5e,0x96,0x3a },
-    { 0x3c,0x49,0x8b,0x28 }, { 0x35,0x44,0x80,0x26 },
-    { 0x42,0x0f,0xe9,0x7c }, { 0x4b,0x02,0xe2,0x72 },
-    { 0x50,0x15,0xff,0x60 }, { 0x59,0x18,0xf4,0x6e },
-    { 0x66,0x3b,0xc5,0x44 }, { 0x6f,0x36,0xce,0x4a },
-    { 0x74,0x21,0xd3,0x58 }, { 0x7d,0x2c,0xd8,0x56 },
-    { 0xa1,0x0c,0x7a,0x37 }, { 0xa8,0x01,0x71,0x39 },
-    { 0xb3,0x16,0x6c,0x2b }, { 0xba,0x1b,0x67,0x25 },
-    { 0x85,0x38,0x56,0x0f }, { 0x8c,0x35,0x5d,0x01 },
-    { 0x97,0x22,0x40,0x13 }, { 0x9e,0x2f,0x4b,0x1d },
-    { 0xe9,0x64,0x22,0x47 }, { 0xe0,0x69,0x29,0x49 },
-    { 0xfb,0x7e,0x34,0x5b }, { 0xf2,0x73,0x3f,0x55 },
-    { 0xcd,0x50,0x0e,0x7f }, { 0xc4,0x5d,0x05,0x71 },
-    { 0xdf,0x4a,0x18,0x63 }, { 0xd6,0x47,0x13,0x6d },
-    { 0x31,0xdc,0xca,0xd7 }, { 0x38,0xd1,0xc1,0xd9 },
-    { 0x23,0xc6,0xdc,0xcb }, { 0x2a,0xcb,0xd7,0xc5 },
-    { 0x15,0xe8,0xe6,0xef }, { 0x1c,0xe5,0xed,0xe1 },
-    { 0x07,0xf2,0xf0,0xf3 }, { 0x0e,0xff,0xfb,0xfd },
-    { 0x79,0xb4,0x92,0xa7 }, { 0x70,0xb9,0x99,0xa9 },
-    { 0x6b,0xae,0x84,0xbb }, { 0x62,0xa3,0x8f,0xb5 },
-    { 0x5d,0x80,0xbe,0x9f }, { 0x54,0x8d,0xb5,0x91 },
-    { 0x4f,0x9a,0xa8,0x83 }, { 0x46,0x97,0xa3,0x8d }
-  };
+#define decT dec_tables.T
+#define inv_sbox dec_tables.inv_sbox
 
 static const u32 rcon[30] =
   {
index 8019f0a..0130924 100644 (file)
 #include "cipher.h"
 #include "bufhelp.h"
 #include "cipher-selftest.h"
+#include "rijndael-internal.h"
+#include "./cipher-internal.h"
 
-#define MAXKC                  (256/32)
-#define MAXROUNDS              14
-#define BLOCKSIZE               (128/8)
-
-
-/* Helper macro to force alignment to 16 bytes.  */
-#ifdef HAVE_GCC_ATTRIBUTE_ALIGNED
-# define ATTR_ALIGNED_16  __attribute__ ((aligned (16)))
-#else
-# define ATTR_ALIGNED_16
-#endif
 
+#ifdef USE_AMD64_ASM
+/* AMD64 assembly implementations of AES */
+extern unsigned int _gcry_aes_amd64_encrypt_block(const void *keysched_enc,
+                                                  unsigned char *out,
+                                                  const unsigned char *in,
+                                                  int rounds,
+                                                  const void *encT);
+
+extern unsigned int _gcry_aes_amd64_decrypt_block(const void *keysched_dec,
+                                                  unsigned char *out,
+                                                  const unsigned char *in,
+                                                  int rounds,
+                                                  const void *decT);
+#endif /*USE_AMD64_ASM*/
 
-/* 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
+#ifdef USE_AESNI
+/* AES-NI (AMD64 & i386) accelerated implementations of AES */
+extern void _gcry_aes_aesni_do_setkey(RIJNDAEL_context *ctx, const byte *key);
+extern void _gcry_aes_aesni_prepare_decryption(RIJNDAEL_context *ctx);
+
+extern unsigned int _gcry_aes_aesni_encrypt (const RIJNDAEL_context *ctx,
+                                             unsigned char *dst,
+                                             const unsigned char *src);
+extern unsigned int _gcry_aes_aesni_decrypt (const RIJNDAEL_context *ctx,
+                                             unsigned char *dst,
+                                             const unsigned char *src);
+extern void _gcry_aes_aesni_cfb_enc (RIJNDAEL_context *ctx,
+                                     unsigned char *outbuf,
+                                     const unsigned char *inbuf,
+                                     unsigned char *iv, size_t nblocks);
+extern void _gcry_aes_aesni_cbc_enc (RIJNDAEL_context *ctx,
+                                     unsigned char *outbuf,
+                                     const unsigned char *inbuf,
+                                     unsigned char *iv, size_t nblocks,
+                                     int cbc_mac);
+extern void _gcry_aes_aesni_ctr_enc (RIJNDAEL_context *ctx,
+                                     unsigned char *outbuf,
+                                     const unsigned char *inbuf,
+                                     unsigned char *ctr, size_t nblocks);
+extern void _gcry_aes_aesni_cfb_dec (RIJNDAEL_context *ctx,
+                                     unsigned char *outbuf,
+                                     const unsigned char *inbuf,
+                                     unsigned char *iv, size_t nblocks);
+extern void _gcry_aes_aesni_cbc_dec (RIJNDAEL_context *ctx,
+                                     unsigned char *outbuf,
+                                     const unsigned char *inbuf,
+                                     unsigned char *iv, size_t nblocks);
+extern void _gcry_aes_aesni_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
+                                       const void *inbuf_arg, size_t nblocks,
+                                       int encrypt);
+extern void _gcry_aes_aesni_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
+                                      size_t nblocks);
 #endif
 
-/* USE_ARM_ASM indicates whether to use ARM assembly code. */
-#undef USE_ARM_ASM
-#if defined(__ARMEL__)
-# ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS
-#  define USE_ARM_ASM 1
-# endif
+#ifdef USE_SSSE3
+/* SSSE3 (AMD64) vector permutation implementation of AES */
+extern void _gcry_aes_ssse3_do_setkey(RIJNDAEL_context *ctx, const byte *key);
+extern void _gcry_aes_ssse3_prepare_decryption(RIJNDAEL_context *ctx);
+
+extern unsigned int _gcry_aes_ssse3_encrypt (const RIJNDAEL_context *ctx,
+                                             unsigned char *dst,
+                                             const unsigned char *src);
+extern unsigned int _gcry_aes_ssse3_decrypt (const RIJNDAEL_context *ctx,
+                                             unsigned char *dst,
+                                             const unsigned char *src);
+extern void _gcry_aes_ssse3_cfb_enc (RIJNDAEL_context *ctx,
+                                     unsigned char *outbuf,
+                                     const unsigned char *inbuf,
+                                     unsigned char *iv, size_t nblocks);
+extern void _gcry_aes_ssse3_cbc_enc (RIJNDAEL_context *ctx,
+                                     unsigned char *outbuf,
+                                     const unsigned char *inbuf,
+                                     unsigned char *iv, size_t nblocks,
+                                     int cbc_mac);
+extern void _gcry_aes_ssse3_ctr_enc (RIJNDAEL_context *ctx,
+                                     unsigned char *outbuf,
+                                     const unsigned char *inbuf,
+                                     unsigned char *ctr, size_t nblocks);
+extern void _gcry_aes_ssse3_cfb_dec (RIJNDAEL_context *ctx,
+                                     unsigned char *outbuf,
+                                     const unsigned char *inbuf,
+                                     unsigned char *iv, size_t nblocks);
+extern void _gcry_aes_ssse3_cbc_dec (RIJNDAEL_context *ctx,
+                                     unsigned char *outbuf,
+                                     const unsigned char *inbuf,
+                                     unsigned char *iv, size_t nblocks);
+extern void _gcry_aes_ssse3_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
+                                       const void *inbuf_arg, size_t nblocks,
+                                       int encrypt);
+extern void _gcry_aes_ssse3_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
+                                      size_t nblocks);
 #endif
 
-/* USE_PADLOCK indicates whether to compile the padlock specific
-   code.  */
-#undef USE_PADLOCK
-#ifdef ENABLE_PADLOCK_SUPPORT
-# ifdef HAVE_GCC_ATTRIBUTE_ALIGNED
-#  if (defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__)
-#   define USE_PADLOCK 1
-#  endif
-# endif
-#endif /*ENABLE_PADLOCK_SUPPORT*/
-
-/* USE_AESNI inidicates whether to compile with Intel AES-NI code.  We
-   need the vector-size attribute which seems to be available since
-   gcc 3.  However, to be on the safe side we require at least gcc 4.  */
-#undef USE_AESNI
-#ifdef ENABLE_AESNI_SUPPORT
-# if ((defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__))
-#  if __GNUC__ >= 4
-#   define USE_AESNI 1
-#  endif
-# endif
-#endif /* ENABLE_AESNI_SUPPORT */
-
-#ifdef USE_AESNI
-  typedef struct u128_s { u32 a, b, c, d; } u128_t;
-#endif /*USE_AESNI*/
-
-/* Define an u32 variant for the sake of gcc 4.4's strict aliasing.  */
-#if __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 4 )
-typedef u32           __attribute__ ((__may_alias__)) u32_a_t;
-#else
-typedef u32           u32_a_t;
+#ifdef USE_PADLOCK
+extern unsigned int _gcry_aes_padlock_encrypt (const RIJNDAEL_context *ctx,
+                                               unsigned char *bx,
+                                               const unsigned char *ax);
+extern unsigned int _gcry_aes_padlock_decrypt (const RIJNDAEL_context *ctx,
+                                               unsigned char *bx,
+                                               const unsigned char *ax);
 #endif
 
-
-#ifdef USE_AMD64_ASM
-/* AMD64 assembly implementations of AES */
-extern void _gcry_aes_amd64_encrypt_block(const void *keysched_enc,
-                                         unsigned char *out,
-                                         const unsigned char *in,
-                                         int rounds);
-
-extern void _gcry_aes_amd64_decrypt_block(const void *keysched_dec,
-                                         unsigned char *out,
-                                         const unsigned char *in,
-                                         int rounds);
-#endif /*USE_AMD64_ASM*/
-
 #ifdef USE_ARM_ASM
 /* ARM assembly implementations of AES */
-extern void _gcry_aes_arm_encrypt_block(const void *keysched_enc,
-                                         unsigned char *out,
-                                         const unsigned char *in,
-                                         int rounds);
-
-extern void _gcry_aes_arm_decrypt_block(const void *keysched_dec,
-                                         unsigned char *out,
-                                         const unsigned char *in,
-                                         int rounds);
+extern unsigned int _gcry_aes_arm_encrypt_block(const void *keysched_enc,
+                                                unsigned char *out,
+                                                const unsigned char *in,
+                                                int rounds,
+                                                const void *encT);
+
+extern unsigned int _gcry_aes_arm_decrypt_block(const void *keysched_dec,
+                                                unsigned char *out,
+                                                const unsigned char *in,
+                                                int rounds,
+                                                const void *decT);
 #endif /*USE_ARM_ASM*/
 
+static unsigned int do_encrypt (const RIJNDAEL_context *ctx, unsigned char *bx,
+                                const unsigned char *ax);
+static unsigned int do_decrypt (const RIJNDAEL_context *ctx, unsigned char *bx,
+                                const unsigned char *ax);
 
 \f
-/* Our context object.  */
-typedef struct
-{
-  /* The first fields are the keyschedule arrays.  This is so that
-     they are aligned on a 16 byte boundary if using gcc.  This
-     alignment is required for the AES-NI code and a good idea in any
-     case.  The alignment is guaranteed due to the way cipher.c
-     allocates the space for the context.  The PROPERLY_ALIGNED_TYPE
-     hack is used to force a minimal alignment if not using gcc of if
-     the alignment requirement is higher that 16 bytes.  */
-  union
-  {
-    PROPERLY_ALIGNED_TYPE dummy;
-    byte keyschedule[MAXROUNDS+1][4][4];
-#ifdef USE_PADLOCK
-    /* The key as passed to the padlock engine.  It is only used if
-       the padlock engine is used (USE_PADLOCK, below).  */
-    unsigned char padlock_key[16] __attribute__ ((aligned (16)));
-#endif /*USE_PADLOCK*/
-  } u1;
-  union
-  {
-    PROPERLY_ALIGNED_TYPE dummy;
-    byte keyschedule[MAXROUNDS+1][4][4];
-  } u2;
-  int rounds;                /* Key-length-dependent number of rounds.  */
-  unsigned int decryption_prepared:1; /* The decryption key schedule is available.  */
-#ifdef USE_PADLOCK
-  unsigned int use_padlock:1;         /* Padlock shall be used.  */
-#endif /*USE_PADLOCK*/
-#ifdef USE_AESNI
-  unsigned int use_aesni:1;           /* AES-NI shall be used.  */
-#endif /*USE_AESNI*/
-} RIJNDAEL_context ATTR_ALIGNED_16;
-
-/* Macros defining alias for the keyschedules.  */
-#define keyschenc  u1.keyschedule
-#define keyschdec  u2.keyschedule
-#define padlockkey u1.padlock_key
-
-/* Two macros to be called prior and after the use of AESNI
-   instructions.  There should be no external function calls between
-   the use of these macros.  There purpose is to make sure that the
-   SSE regsiters are cleared and won't reveal any information about
-   the key or the data.  */
-#ifdef USE_AESNI
-# define aesni_prepare() do { } while (0)
-# define aesni_cleanup()                                                \
-  do { asm volatile ("pxor %%xmm0, %%xmm0\n\t"                          \
-                     "pxor %%xmm1, %%xmm1\n" :: );                      \
-  } while (0)
-# define aesni_cleanup_2_6()                                            \
-  do { asm volatile ("pxor %%xmm2, %%xmm2\n\t"                          \
-                     "pxor %%xmm3, %%xmm3\n"                            \
-                     "pxor %%xmm4, %%xmm4\n"                            \
-                     "pxor %%xmm5, %%xmm5\n"                            \
-                     "pxor %%xmm6, %%xmm6\n":: );                       \
-  } while (0)
-#else
-# define aesni_prepare() do { } while (0)
-# define aesni_cleanup() do { } while (0)
-#endif
-
 
 /* All the numbers.  */
 #include "rijndael-tables.h"
 
 
 \f
-/* Function prototypes.  */
-#if defined(__i386__) && defined(USE_AESNI)
-/* We don't want to inline these functions on i386 to help gcc allocate enough
-   registers.  */
-static void do_aesni_ctr (const RIJNDAEL_context *ctx, unsigned char *ctr,
-                          unsigned char *b, const unsigned char *a)
-  __attribute__ ((__noinline__));
-static void do_aesni_ctr_4 (const RIJNDAEL_context *ctx, unsigned char *ctr,
-                            unsigned char *b, const unsigned char *a)
-  __attribute__ ((__noinline__));
-#endif /*USE_AESNI*/
 
+/* Function prototypes.  */
 static const char *selftest(void);
 
 
 \f
-#ifdef USE_AESNI
-static void
-aesni_do_setkey (RIJNDAEL_context *ctx, const byte *key)
+/* Prefetching for encryption/decryption tables. */
+static void prefetch_table(const volatile byte *tab, size_t len)
 {
-  aesni_prepare();
+  size_t i;
 
-  if (ctx->rounds < 12)
-    {
-      /* 128-bit key */
-#define AESKEYGENASSIST_xmm1_xmm2(imm8) \
-       ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd1, " #imm8 " \n\t"
-#define AESKEY_EXPAND128 \
-       "pshufd $0xff, %%xmm2, %%xmm2\n\t" \
-       "movdqa %%xmm1, %%xmm3\n\t" \
-       "pslldq $4, %%xmm3\n\t" \
-       "pxor   %%xmm3, %%xmm1\n\t" \
-       "pslldq $4, %%xmm3\n\t" \
-       "pxor   %%xmm3, %%xmm1\n\t" \
-       "pslldq $4, %%xmm3\n\t" \
-       "pxor   %%xmm3, %%xmm2\n\t" \
-       "pxor   %%xmm2, %%xmm1\n\t"
-
-      asm volatile ("movdqu (%[key]), %%xmm1\n\t"     /* xmm1 := key   */
-                    "movdqa %%xmm1, (%[ksch])\n\t"     /* ksch[0] := xmm1  */
-                    AESKEYGENASSIST_xmm1_xmm2(0x01)
-                    AESKEY_EXPAND128
-                    "movdqa %%xmm1, 0x10(%[ksch])\n\t" /* ksch[1] := xmm1  */
-                    AESKEYGENASSIST_xmm1_xmm2(0x02)
-                    AESKEY_EXPAND128
-                    "movdqa %%xmm1, 0x20(%[ksch])\n\t" /* ksch[2] := xmm1  */
-                    AESKEYGENASSIST_xmm1_xmm2(0x04)
-                    AESKEY_EXPAND128
-                    "movdqa %%xmm1, 0x30(%[ksch])\n\t" /* ksch[3] := xmm1  */
-                    AESKEYGENASSIST_xmm1_xmm2(0x08)
-                    AESKEY_EXPAND128
-                    "movdqa %%xmm1, 0x40(%[ksch])\n\t" /* ksch[4] := xmm1  */
-                    AESKEYGENASSIST_xmm1_xmm2(0x10)
-                    AESKEY_EXPAND128
-                    "movdqa %%xmm1, 0x50(%[ksch])\n\t" /* ksch[5] := xmm1  */
-                    AESKEYGENASSIST_xmm1_xmm2(0x20)
-                    AESKEY_EXPAND128
-                    "movdqa %%xmm1, 0x60(%[ksch])\n\t" /* ksch[6] := xmm1  */
-                    AESKEYGENASSIST_xmm1_xmm2(0x40)
-                    AESKEY_EXPAND128
-                    "movdqa %%xmm1, 0x70(%[ksch])\n\t" /* ksch[7] := xmm1  */
-                    AESKEYGENASSIST_xmm1_xmm2(0x80)
-                    AESKEY_EXPAND128
-                    "movdqa %%xmm1, 0x80(%[ksch])\n\t" /* ksch[8] := xmm1  */
-                    AESKEYGENASSIST_xmm1_xmm2(0x1b)
-                    AESKEY_EXPAND128
-                    "movdqa %%xmm1, 0x90(%[ksch])\n\t" /* ksch[9] := xmm1  */
-                    AESKEYGENASSIST_xmm1_xmm2(0x36)
-                    AESKEY_EXPAND128
-                    "movdqa %%xmm1, 0xa0(%[ksch])\n\t" /* ksch[10] := xmm1  */
-                    :
-                    : [key] "r" (key), [ksch] "r" (ctx->keyschenc)
-                    : "cc", "memory" );
-#undef AESKEYGENASSIST_xmm1_xmm2
-#undef AESKEY_EXPAND128
-    }
-  else if (ctx->rounds == 12)
+  for (i = 0; i < len; i += 8 * 32)
     {
-      /* 192-bit key */
-#define AESKEYGENASSIST_xmm3_xmm2(imm8) \
-       ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd3, " #imm8 " \n\t"
-#define AESKEY_EXPAND192 \
-       "pshufd $0x55, %%xmm2, %%xmm2\n\t" \
-       "movdqu %%xmm1, %%xmm4\n\t" \
-       "pslldq $4, %%xmm4\n\t" \
-       "pxor %%xmm4, %%xmm1\n\t" \
-       "pslldq $4, %%xmm4\n\t" \
-       "pxor %%xmm4, %%xmm1\n\t" \
-       "pslldq $4, %%xmm4\n\t" \
-       "pxor %%xmm4, %%xmm1\n\t" \
-       "pxor %%xmm2, %%xmm1\n\t" \
-       "pshufd $0xff, %%xmm1, %%xmm2\n\t" \
-       "movdqu %%xmm3, %%xmm4\n\t" \
-       "pslldq $4, %%xmm4\n\t" \
-       "pxor %%xmm4, %%xmm3\n\t" \
-       "pxor %%xmm2, %%xmm3\n\t"
-
-      asm volatile ("movdqu (%[key]), %%xmm1\n\t"     /* xmm1 := key[0..15]   */
-                    "movq 16(%[key]), %%xmm3\n\t"     /* xmm3 := key[16..23]  */
-                    "movdqa %%xmm1, (%[ksch])\n\t"    /* ksch[0] := xmm1  */
-                    "movdqa %%xmm3, %%xmm5\n\t"
-
-                    AESKEYGENASSIST_xmm3_xmm2(0x01)
-                    AESKEY_EXPAND192
-                    "shufpd $0, %%xmm1, %%xmm5\n\t"
-                    "movdqa %%xmm5, 0x10(%[ksch])\n\t" /* ksch[1] := xmm5  */
-                    "movdqa %%xmm1, %%xmm6\n\t"
-                    "shufpd $1, %%xmm3, %%xmm6\n\t"
-                    "movdqa %%xmm6, 0x20(%[ksch])\n\t" /* ksch[2] := xmm6  */
-                    AESKEYGENASSIST_xmm3_xmm2(0x02)
-                    AESKEY_EXPAND192
-                    "movdqa %%xmm1, 0x30(%[ksch])\n\t" /* ksch[3] := xmm1  */
-                    "movdqa %%xmm3, %%xmm5\n\t"
-
-                    AESKEYGENASSIST_xmm3_xmm2(0x04)
-                    AESKEY_EXPAND192
-                    "shufpd $0, %%xmm1, %%xmm5\n\t"
-                    "movdqa %%xmm5, 0x40(%[ksch])\n\t" /* ksch[4] := xmm5  */
-                    "movdqa %%xmm1, %%xmm6\n\t"
-                    "shufpd $1, %%xmm3, %%xmm6\n\t"
-                    "movdqa %%xmm6, 0x50(%[ksch])\n\t" /* ksch[5] := xmm6  */
-                    AESKEYGENASSIST_xmm3_xmm2(0x08)
-                    AESKEY_EXPAND192
-                    "movdqa %%xmm1, 0x60(%[ksch])\n\t" /* ksch[6] := xmm1  */
-                    "movdqa %%xmm3, %%xmm5\n\t"
-
-                    AESKEYGENASSIST_xmm3_xmm2(0x10)
-                    AESKEY_EXPAND192
-                    "shufpd $0, %%xmm1, %%xmm5\n\t"
-                    "movdqa %%xmm5, 0x70(%[ksch])\n\t" /* ksch[7] := xmm5  */
-                    "movdqa %%xmm1, %%xmm6\n\t"
-                    "shufpd $1, %%xmm3, %%xmm6\n\t"
-                    "movdqa %%xmm6, 0x80(%[ksch])\n\t" /* ksch[8] := xmm6  */
-                    AESKEYGENASSIST_xmm3_xmm2(0x20)
-                    AESKEY_EXPAND192
-                    "movdqa %%xmm1, 0x90(%[ksch])\n\t" /* ksch[9] := xmm1  */
-                    "movdqa %%xmm3, %%xmm5\n\t"
-
-                    AESKEYGENASSIST_xmm3_xmm2(0x40)
-                    AESKEY_EXPAND192
-                    "shufpd $0, %%xmm1, %%xmm5\n\t"
-                    "movdqa %%xmm5, 0xa0(%[ksch])\n\t" /* ksch[10] := xmm5  */
-                    "movdqa %%xmm1, %%xmm6\n\t"
-                    "shufpd $1, %%xmm3, %%xmm6\n\t"
-                    "movdqa %%xmm6, 0xb0(%[ksch])\n\t" /* ksch[11] := xmm6  */
-                    AESKEYGENASSIST_xmm3_xmm2(0x80)
-                    AESKEY_EXPAND192
-                    "movdqa %%xmm1, 0xc0(%[ksch])\n\t" /* ksch[12] := xmm1  */
-                    :
-                    : [key] "r" (key), [ksch] "r" (ctx->keyschenc)
-                    : "cc", "memory" );
-#undef AESKEYGENASSIST_xmm3_xmm2
-#undef AESKEY_EXPAND192
-    }
-  else if (ctx->rounds > 12)
-    {
-      /* 256-bit key */
-#define AESKEYGENASSIST_xmm1_xmm2(imm8) \
-       ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd1, " #imm8 " \n\t"
-#define AESKEYGENASSIST_xmm3_xmm2(imm8) \
-       ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd3, " #imm8 " \n\t"
-#define AESKEY_EXPAND256_A \
-       "pshufd $0xff, %%xmm2, %%xmm2\n\t" \
-       "movdqa %%xmm1, %%xmm4\n\t" \
-       "pslldq $4, %%xmm4\n\t" \
-       "pxor %%xmm4, %%xmm1\n\t" \
-       "pslldq $4, %%xmm4\n\t" \
-       "pxor %%xmm4, %%xmm1\n\t" \
-       "pslldq $4, %%xmm4\n\t" \
-       "pxor %%xmm4, %%xmm1\n\t" \
-       "pxor %%xmm2, %%xmm1\n\t"
-#define AESKEY_EXPAND256_B \
-       "pshufd $0xaa, %%xmm2, %%xmm2\n\t" \
-       "movdqa %%xmm3, %%xmm4\n\t" \
-       "pslldq $4, %%xmm4\n\t" \
-       "pxor %%xmm4, %%xmm3\n\t" \
-       "pslldq $4, %%xmm4\n\t" \
-       "pxor %%xmm4, %%xmm3\n\t" \
-       "pslldq $4, %%xmm4\n\t" \
-       "pxor %%xmm4, %%xmm3\n\t" \
-       "pxor %%xmm2, %%xmm3\n\t"
-
-      asm volatile ("movdqu (%[key]), %%xmm1\n\t"     /* xmm1 := key[0..15]   */
-                    "movdqu 16(%[key]), %%xmm3\n\t"   /* xmm3 := key[16..31]  */
-                    "movdqa %%xmm1, (%[ksch])\n\t"     /* ksch[0] := xmm1  */
-                    "movdqa %%xmm3, 0x10(%[ksch])\n\t" /* ksch[1] := xmm3  */
-
-                    AESKEYGENASSIST_xmm3_xmm2(0x01)
-                    AESKEY_EXPAND256_A
-                    "movdqa %%xmm1, 0x20(%[ksch])\n\t" /* ksch[2] := xmm1  */
-                    AESKEYGENASSIST_xmm1_xmm2(0x00)
-                    AESKEY_EXPAND256_B
-                    "movdqa %%xmm3, 0x30(%[ksch])\n\t" /* ksch[3] := xmm3  */
-
-                    AESKEYGENASSIST_xmm3_xmm2(0x02)
-                    AESKEY_EXPAND256_A
-                    "movdqa %%xmm1, 0x40(%[ksch])\n\t" /* ksch[4] := xmm1  */
-                    AESKEYGENASSIST_xmm1_xmm2(0x00)
-                    AESKEY_EXPAND256_B
-                    "movdqa %%xmm3, 0x50(%[ksch])\n\t" /* ksch[5] := xmm3  */
-
-                    AESKEYGENASSIST_xmm3_xmm2(0x04)
-                    AESKEY_EXPAND256_A
-                    "movdqa %%xmm1, 0x60(%[ksch])\n\t" /* ksch[6] := xmm1  */
-                    AESKEYGENASSIST_xmm1_xmm2(0x00)
-                    AESKEY_EXPAND256_B
-                    "movdqa %%xmm3, 0x70(%[ksch])\n\t" /* ksch[7] := xmm3  */
-
-                    AESKEYGENASSIST_xmm3_xmm2(0x08)
-                    AESKEY_EXPAND256_A
-                    "movdqa %%xmm1, 0x80(%[ksch])\n\t" /* ksch[8] := xmm1  */
-                    AESKEYGENASSIST_xmm1_xmm2(0x00)
-                    AESKEY_EXPAND256_B
-                    "movdqa %%xmm3, 0x90(%[ksch])\n\t" /* ksch[9] := xmm3  */
-
-                    AESKEYGENASSIST_xmm3_xmm2(0x10)
-                    AESKEY_EXPAND256_A
-                    "movdqa %%xmm1, 0xa0(%[ksch])\n\t" /* ksch[10] := xmm1  */
-                    AESKEYGENASSIST_xmm1_xmm2(0x00)
-                    AESKEY_EXPAND256_B
-                    "movdqa %%xmm3, 0xb0(%[ksch])\n\t" /* ksch[11] := xmm3  */
-
-                    AESKEYGENASSIST_xmm3_xmm2(0x20)
-                    AESKEY_EXPAND256_A
-                    "movdqa %%xmm1, 0xc0(%[ksch])\n\t" /* ksch[12] := xmm1  */
-                    AESKEYGENASSIST_xmm1_xmm2(0x00)
-                    AESKEY_EXPAND256_B
-                    "movdqa %%xmm3, 0xd0(%[ksch])\n\t" /* ksch[13] := xmm3  */
-
-                    AESKEYGENASSIST_xmm3_xmm2(0x40)
-                    AESKEY_EXPAND256_A
-                    "movdqa %%xmm1, 0xe0(%[ksch])\n\t" /* ksch[14] := xmm1  */
-
-                    :
-                    : [key] "r" (key), [ksch] "r" (ctx->keyschenc)
-                    : "cc", "memory" );
-#undef AESKEYGENASSIST_xmm1_xmm2
-#undef AESKEYGENASSIST_xmm3_xmm2
-#undef AESKEY_EXPAND256_A
-#undef AESKEY_EXPAND256_B
+      (void)tab[i + 0 * 32];
+      (void)tab[i + 1 * 32];
+      (void)tab[i + 2 * 32];
+      (void)tab[i + 3 * 32];
+      (void)tab[i + 4 * 32];
+      (void)tab[i + 5 * 32];
+      (void)tab[i + 6 * 32];
+      (void)tab[i + 7 * 32];
     }
 
-  aesni_cleanup();
-  aesni_cleanup_2_6();
+  (void)tab[len - 1];
+}
+
+static void prefetch_enc(void)
+{
+  prefetch_table((const void *)encT, sizeof(encT));
+}
+
+static void prefetch_dec(void)
+{
+  prefetch_table((const void *)&dec_tables, sizeof(dec_tables));
 }
-#endif /*USE_AESNI*/
 
 
 \f
@@ -465,7 +227,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
   int rounds;
   int i,j, r, t, rconpointer = 0;
   int KC;
-#if defined(USE_AESNI) || defined(USE_PADLOCK)
+#if defined(USE_AESNI) || defined(USE_PADLOCK) || defined(USE_SSSE3)
   unsigned int hwfeatures;
 #endif
 
@@ -486,78 +248,84 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
   if (selftest_failed)
     return GPG_ERR_SELFTEST_FAILED;
 
-#if defined(USE_AESNI) || defined(USE_PADLOCK)
-  hwfeatures = _gcry_get_hw_features ();
-#endif
-
-  ctx->decryption_prepared = 0;
-#ifdef USE_PADLOCK
-  ctx->use_padlock = 0;
-#endif
-#ifdef USE_AESNI
-  ctx->use_aesni = 0;
-#endif
-
   if( keylen == 128/8 )
     {
       rounds = 10;
       KC = 4;
-
-      if (0)
-        {
-          ;
-        }
-#ifdef USE_PADLOCK
-      else if (hwfeatures & HWF_PADLOCK_AES)
-        {
-          ctx->use_padlock = 1;
-          memcpy (ctx->padlockkey, key, keylen);
-        }
-#endif
-#ifdef USE_AESNI
-      else if (hwfeatures & HWF_INTEL_AESNI)
-        {
-          ctx->use_aesni = 1;
-        }
-#endif
     }
   else if ( keylen == 192/8 )
     {
       rounds = 12;
       KC = 6;
-
-      if (0)
-        {
-          ;
-        }
-#ifdef USE_AESNI
-      else if (hwfeatures & HWF_INTEL_AESNI)
-        {
-          ctx->use_aesni = 1;
-        }
-#endif
     }
   else if ( keylen == 256/8 )
     {
       rounds = 14;
       KC = 8;
-
-      if (0)
-        {
-          ;
-        }
-#ifdef USE_AESNI
-      else if (hwfeatures & HWF_INTEL_AESNI)
-        {
-          ctx->use_aesni = 1;
-        }
-#endif
     }
   else
     return GPG_ERR_INV_KEYLEN;
 
   ctx->rounds = rounds;
 
+#if defined(USE_AESNI) || defined(USE_PADLOCK) || defined(USE_SSSE3)
+  hwfeatures = _gcry_get_hw_features ();
+#endif
+
+  ctx->decryption_prepared = 0;
+#ifdef USE_PADLOCK
+  ctx->use_padlock = 0;
+#endif
+#ifdef USE_AESNI
+  ctx->use_aesni = 0;
+#endif
+#ifdef USE_SSSE3
+  ctx->use_ssse3 = 0;
+#endif
+
+  if (0)
+    {
+      ;
+    }
+#ifdef USE_AESNI
+  else if (hwfeatures & HWF_INTEL_AESNI)
+    {
+      ctx->encrypt_fn = _gcry_aes_aesni_encrypt;
+      ctx->decrypt_fn = _gcry_aes_aesni_decrypt;
+      ctx->prefetch_enc_fn = NULL;
+      ctx->prefetch_dec_fn = NULL;
+      ctx->use_aesni = 1;
+    }
+#endif
+#ifdef USE_PADLOCK
+  else if (hwfeatures & HWF_PADLOCK_AES && keylen == 128/8)
+    {
+      ctx->encrypt_fn = _gcry_aes_padlock_encrypt;
+      ctx->decrypt_fn = _gcry_aes_padlock_decrypt;
+      ctx->prefetch_enc_fn = NULL;
+      ctx->prefetch_dec_fn = NULL;
+      ctx->use_padlock = 1;
+      memcpy (ctx->padlockkey, key, keylen);
+    }
+#endif
+#ifdef USE_SSSE3
+  else if (hwfeatures & HWF_INTEL_SSSE3)
+    {
+      ctx->encrypt_fn = _gcry_aes_ssse3_encrypt;
+      ctx->decrypt_fn = _gcry_aes_ssse3_decrypt;
+      ctx->prefetch_enc_fn = NULL;
+      ctx->prefetch_dec_fn = NULL;
+      ctx->use_ssse3 = 1;
+    }
+#endif
+  else
+    {
+      ctx->encrypt_fn = do_encrypt;
+      ctx->decrypt_fn = do_decrypt;
+      ctx->prefetch_enc_fn = prefetch_enc;
+      ctx->prefetch_dec_fn = prefetch_dec;
+    }
+
   /* NB: We don't yet support Padlock hardware key generation.  */
 
   if (0)
@@ -566,18 +334,30 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
     }
 #ifdef USE_AESNI
   else if (ctx->use_aesni)
-    aesni_do_setkey(ctx, key);
+    _gcry_aes_aesni_do_setkey (ctx, key);
+#endif
+#ifdef USE_SSSE3
+  else if (ctx->use_ssse3)
+    _gcry_aes_ssse3_do_setkey (ctx, key);
 #endif
   else
     {
+      const byte *sbox = ((const byte *)encT) + 1;
       union
         {
           PROPERLY_ALIGNED_TYPE dummy;
           byte data[MAXKC][4];
-        } k, tk;
-#define k k.data
-#define tk tk.data
-#define W (ctx->keyschenc)
+          u32 data32[MAXKC];
+        } tkk[2];
+#define k      tkk[0].data
+#define k_u32  tkk[0].data32
+#define tk     tkk[1].data
+#define tk_u32 tkk[1].data32
+#define W      (ctx->keyschenc)
+#define W_u32  (ctx->keyschenc32)
+
+      prefetch_enc();
+
       for (i = 0; i < keylen; i++)
         {
           k[i >> 2][i & 3] = key[i];
@@ -585,7 +365,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
 
       for (j = KC-1; j >= 0; j--)
         {
-          *((u32_a_t*)tk[j]) = *((u32_a_t*)k[j]);
+          tk_u32[j] = k_u32[j];
         }
       r = 0;
       t = 0;
@@ -594,7 +374,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
         {
           for (; (j < KC) && (t < 4); j++, t++)
             {
-              *((u32_a_t*)W[r][t]) = *((u32_a_t*)tk[j]);
+              W_u32[r][t] = le_bswap32(tk_u32[j]);
             }
           if (t == 4)
             {
@@ -607,32 +387,32 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
         {
           /* While not enough round key material calculated calculate
              new values.  */
-          tk[0][0] ^= S[tk[KC-1][1]];
-          tk[0][1] ^= S[tk[KC-1][2]];
-          tk[0][2] ^= S[tk[KC-1][3]];
-          tk[0][3] ^= S[tk[KC-1][0]];
+          tk[0][0] ^= sbox[tk[KC-1][1] * 4];
+          tk[0][1] ^= sbox[tk[KC-1][2] * 4];
+          tk[0][2] ^= sbox[tk[KC-1][3] * 4];
+          tk[0][3] ^= sbox[tk[KC-1][0] * 4];
           tk[0][0] ^= rcon[rconpointer++];
 
           if (KC != 8)
             {
               for (j = 1; j < KC; j++)
                 {
-                  *((u32_a_t*)tk[j]) ^= *((u32_a_t*)tk[j-1]);
+                  tk_u32[j] ^= tk_u32[j-1];
                 }
             }
           else
             {
               for (j = 1; j < KC/2; j++)
                 {
-                  *((u32_a_t*)tk[j]) ^= *((u32_a_t*)tk[j-1]);
+                  tk_u32[j] ^= tk_u32[j-1];
                 }
-              tk[KC/2][0] ^= S[tk[KC/2 - 1][0]];
-              tk[KC/2][1] ^= S[tk[KC/2 - 1][1]];
-              tk[KC/2][2] ^= S[tk[KC/2 - 1][2]];
-              tk[KC/2][3] ^= S[tk[KC/2 - 1][3]];
+              tk[KC/2][0] ^= sbox[tk[KC/2 - 1][0] * 4];
+              tk[KC/2][1] ^= sbox[tk[KC/2 - 1][1] * 4];
+              tk[KC/2][2] ^= sbox[tk[KC/2 - 1][2] * 4];
+              tk[KC/2][3] ^= sbox[tk[KC/2 - 1][3] * 4];
               for (j = KC/2 + 1; j < KC; j++)
                 {
-                  *((u32_a_t*)tk[j]) ^= *((u32_a_t*)tk[j-1]);
+                  tk_u32[j] ^= tk_u32[j-1];
                 }
             }
 
@@ -641,7 +421,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
             {
               for (; (j < KC) && (t < 4); j++, t++)
                 {
-                  *((u32_a_t*)W[r][t]) = *((u32_a_t*)tk[j]);
+                  W_u32[r][t] = le_bswap32(tk_u32[j]);
                 }
               if (t == 4)
                 {
@@ -653,8 +433,10 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
 #undef W
 #undef tk
 #undef k
-      wipememory(&tk, sizeof(tk));
-      wipememory(&t, sizeof(t));
+#undef W_u32
+#undef tk_u32
+#undef k_u32
+      wipememory(&tkk, sizeof(tkk));
     }
 
   return 0;
@@ -675,997 +457,257 @@ prepare_decryption( RIJNDAEL_context *ctx )
 {
   int r;
 
+  if (0)
+    ;
 #ifdef USE_AESNI
-  if (ctx->use_aesni)
+  else if (ctx->use_aesni)
     {
-      /* The AES-NI decrypt instructions use the Equivalent Inverse
-         Cipher, thus we can't use the the standard decrypt key
-         preparation.  */
-        u128_t *ekey = (u128_t *)ctx->keyschenc;
-        u128_t *dkey = (u128_t *)ctx->keyschdec;
-        int rr;
-
-       aesni_prepare();
-
-#define DO_AESNI_AESIMC() \
-       asm volatile ("movdqa %[ekey], %%xmm1\n\t" \
-                      /*"aesimc %%xmm1, %%xmm1\n\t"*/ \
-                      ".byte 0x66, 0x0f, 0x38, 0xdb, 0xc9\n\t" \
-                      "movdqa %%xmm1, %[dkey]" \
-                      : [dkey] "=m" (dkey[r]) \
-                      : [ekey] "m" (ekey[rr]) \
-                      : "memory")
-
-        dkey[0] = ekey[ctx->rounds];
-        r=1;
-       rr=ctx->rounds-1;
-       DO_AESNI_AESIMC(); r++; rr--; /* round 1 */
-       DO_AESNI_AESIMC(); r++; rr--; /* round 2 */
-       DO_AESNI_AESIMC(); r++; rr--; /* round 3 */
-       DO_AESNI_AESIMC(); r++; rr--; /* round 4 */
-       DO_AESNI_AESIMC(); r++; rr--; /* round 5 */
-       DO_AESNI_AESIMC(); r++; rr--; /* round 6 */
-       DO_AESNI_AESIMC(); r++; rr--; /* round 7 */
-       DO_AESNI_AESIMC(); r++; rr--; /* round 8 */
-       DO_AESNI_AESIMC(); r++; rr--; /* round 9 */
-       if (ctx->rounds > 10)
-         {
-           DO_AESNI_AESIMC(); r++; rr--; /* round 10 */
-           DO_AESNI_AESIMC(); r++; rr--; /* round 11 */
-           if (ctx->rounds > 12)
-             {
-               DO_AESNI_AESIMC(); r++; rr--; /* round 12 */
-               DO_AESNI_AESIMC(); r++; rr--; /* round 13 */
-             }
-         }
-
-        dkey[r] = ekey[0];
-
-#undef DO_AESNI_AESIMC
-
-       aesni_cleanup();
+      _gcry_aes_aesni_prepare_decryption (ctx);
     }
-  else
 #endif /*USE_AESNI*/
+#ifdef USE_SSSE3
+  else if (ctx->use_ssse3)
     {
-      union
-      {
-        PROPERLY_ALIGNED_TYPE dummy;
-        byte *w;
-      } w;
-#define w w.w
-
-      for (r=0; r < MAXROUNDS+1; r++ )
-        {
-          *((u32_a_t*)ctx->keyschdec[r][0]) = *((u32_a_t*)ctx->keyschenc[r][0]);
-          *((u32_a_t*)ctx->keyschdec[r][1]) = *((u32_a_t*)ctx->keyschenc[r][1]);
-          *((u32_a_t*)ctx->keyschdec[r][2]) = *((u32_a_t*)ctx->keyschenc[r][2]);
-          *((u32_a_t*)ctx->keyschdec[r][3]) = *((u32_a_t*)ctx->keyschenc[r][3]);
-        }
-#define W (ctx->keyschdec)
-      for (r = 1; r < ctx->rounds; r++)
-        {
-          w = W[r][0];
-          *((u32_a_t*)w) = *((u32_a_t*)U1[w[0]]) ^ *((u32_a_t*)U2[w[1]])
-            ^ *((u32_a_t*)U3[w[2]]) ^ *((u32_a_t*)U4[w[3]]);
+      _gcry_aes_ssse3_prepare_decryption (ctx);
+    }
+#endif /*USE_SSSE3*/
+#ifdef USE_PADLOCK
+  else if (ctx->use_padlock)
+    {
+      /* Padlock does not need decryption subkeys. */
+    }
+#endif /*USE_PADLOCK*/
+  else
+    {
+      const byte *sbox = ((const byte *)encT) + 1;
 
-          w = W[r][1];
-          *((u32_a_t*)w) = *((u32_a_t*)U1[w[0]]) ^ *((u32_a_t*)U2[w[1]])
-            ^ *((u32_a_t*)U3[w[2]]) ^ *((u32_a_t*)U4[w[3]]);
+      prefetch_enc();
+      prefetch_dec();
 
-          w = W[r][2];
-          *((u32_a_t*)w) = *((u32_a_t*)U1[w[0]]) ^ *((u32_a_t*)U2[w[1]])
-        ^ *((u32_a_t*)U3[w[2]]) ^ *((u32_a_t*)U4[w[3]]);
+      ctx->keyschdec32[0][0] = ctx->keyschenc32[0][0];
+      ctx->keyschdec32[0][1] = ctx->keyschenc32[0][1];
+      ctx->keyschdec32[0][2] = ctx->keyschenc32[0][2];
+      ctx->keyschdec32[0][3] = ctx->keyschenc32[0][3];
 
-          w = W[r][3];
-          *((u32_a_t*)w) = *((u32_a_t*)U1[w[0]]) ^ *((u32_a_t*)U2[w[1]])
-            ^ *((u32_a_t*)U3[w[2]]) ^ *((u32_a_t*)U4[w[3]]);
+      for (r = 1; r < ctx->rounds; r++)
+        {
+          u32 *wi = ctx->keyschenc32[r];
+          u32 *wo = ctx->keyschdec32[r];
+          u32 wt;
+
+          wt = wi[0];
+          wo[0] = rol(decT[sbox[(byte)(wt >> 0) * 4]], 8 * 0)
+                 ^ rol(decT[sbox[(byte)(wt >> 8) * 4]], 8 * 1)
+                 ^ rol(decT[sbox[(byte)(wt >> 16) * 4]], 8 * 2)
+                 ^ rol(decT[sbox[(byte)(wt >> 24) * 4]], 8 * 3);
+
+          wt = wi[1];
+          wo[1] = rol(decT[sbox[(byte)(wt >> 0) * 4]], 8 * 0)
+                 ^ rol(decT[sbox[(byte)(wt >> 8) * 4]], 8 * 1)
+                 ^ rol(decT[sbox[(byte)(wt >> 16) * 4]], 8 * 2)
+                 ^ rol(decT[sbox[(byte)(wt >> 24) * 4]], 8 * 3);
+
+          wt = wi[2];
+          wo[2] = rol(decT[sbox[(byte)(wt >> 0) * 4]], 8 * 0)
+                 ^ rol(decT[sbox[(byte)(wt >> 8) * 4]], 8 * 1)
+                 ^ rol(decT[sbox[(byte)(wt >> 16) * 4]], 8 * 2)
+                 ^ rol(decT[sbox[(byte)(wt >> 24) * 4]], 8 * 3);
+
+          wt = wi[3];
+          wo[3] = rol(decT[sbox[(byte)(wt >> 0) * 4]], 8 * 0)
+                 ^ rol(decT[sbox[(byte)(wt >> 8) * 4]], 8 * 1)
+                 ^ rol(decT[sbox[(byte)(wt >> 16) * 4]], 8 * 2)
+                 ^ rol(decT[sbox[(byte)(wt >> 24) * 4]], 8 * 3);
         }
-#undef W
-#undef w
-      wipememory(&w, sizeof(w));
+
+      ctx->keyschdec32[r][0] = ctx->keyschenc32[r][0];
+      ctx->keyschdec32[r][1] = ctx->keyschenc32[r][1];
+      ctx->keyschdec32[r][2] = ctx->keyschenc32[r][2];
+      ctx->keyschdec32[r][3] = ctx->keyschenc32[r][3];
     }
 }
 
 \f
-/* Encrypt one block.  A and B need to be aligned on a 4 byte
-   boundary.  A and B may be the same. */
-static void
-do_encrypt_aligned (const RIJNDAEL_context *ctx,
-                    unsigned char *b, const unsigned char *a)
+#if !defined(USE_ARM_ASM) && !defined(USE_AMD64_ASM)
+/* Encrypt one block. A and B may be the same. */
+static unsigned int
+do_encrypt_fn (const RIJNDAEL_context *ctx, unsigned char *b,
+               const unsigned char *a)
 {
-#ifdef USE_AMD64_ASM
-  _gcry_aes_amd64_encrypt_block(ctx->keyschenc, b, a, ctx->rounds);
-#elif defined(USE_ARM_ASM)
-  _gcry_aes_arm_encrypt_block(ctx->keyschenc, b, a, ctx->rounds);
-#else
-#define rk (ctx->keyschenc)
+#define rk (ctx->keyschenc32)
+  const byte *sbox = ((const byte *)encT) + 1;
   int rounds = ctx->rounds;
   int r;
-  union
-  {
-    u32  tempu32[4];  /* Force correct alignment. */
-    byte temp[4][4];
-  } u;
-
-  *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(a   )) ^ *((u32_a_t*)rk[0][0]);
-  *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(a+ 4)) ^ *((u32_a_t*)rk[0][1]);
-  *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(a+ 8)) ^ *((u32_a_t*)rk[0][2]);
-  *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(a+12)) ^ *((u32_a_t*)rk[0][3]);
-  *((u32_a_t*)(b    ))   = (*((u32_a_t*)T1[u.temp[0][0]])
-                        ^ *((u32_a_t*)T2[u.temp[1][1]])
-                        ^ *((u32_a_t*)T3[u.temp[2][2]])
-                        ^ *((u32_a_t*)T4[u.temp[3][3]]));
-  *((u32_a_t*)(b + 4))   = (*((u32_a_t*)T1[u.temp[1][0]])
-                        ^ *((u32_a_t*)T2[u.temp[2][1]])
-                        ^ *((u32_a_t*)T3[u.temp[3][2]])
-                        ^ *((u32_a_t*)T4[u.temp[0][3]]));
-  *((u32_a_t*)(b + 8))   = (*((u32_a_t*)T1[u.temp[2][0]])
-                        ^ *((u32_a_t*)T2[u.temp[3][1]])
-                        ^ *((u32_a_t*)T3[u.temp[0][2]])
-                        ^ *((u32_a_t*)T4[u.temp[1][3]]));
-  *((u32_a_t*)(b +12))   = (*((u32_a_t*)T1[u.temp[3][0]])
-                        ^ *((u32_a_t*)T2[u.temp[0][1]])
-                        ^ *((u32_a_t*)T3[u.temp[1][2]])
-                        ^ *((u32_a_t*)T4[u.temp[2][3]]));
-
-  for (r = 1; r < rounds-1; r++)
+  u32 sa[4];
+  u32 sb[4];
+
+  sb[0] = buf_get_le32(a + 0);
+  sb[1] = buf_get_le32(a + 4);
+  sb[2] = buf_get_le32(a + 8);
+  sb[3] = buf_get_le32(a + 12);
+
+  sa[0] = sb[0] ^ rk[0][0];
+  sa[1] = sb[1] ^ rk[0][1];
+  sa[2] = sb[2] ^ rk[0][2];
+  sa[3] = sb[3] ^ rk[0][3];
+
+  sb[0] = rol(encT[(byte)(sa[0] >> (0 * 8))], (0 * 8));
+  sb[3] = rol(encT[(byte)(sa[0] >> (1 * 8))], (1 * 8));
+  sb[2] = rol(encT[(byte)(sa[0] >> (2 * 8))], (2 * 8));
+  sb[1] = rol(encT[(byte)(sa[0] >> (3 * 8))], (3 * 8));
+  sa[0] = rk[1][0] ^ sb[0];
+
+  sb[1] ^= rol(encT[(byte)(sa[1] >> (0 * 8))], (0 * 8));
+  sa[0] ^= rol(encT[(byte)(sa[1] >> (1 * 8))], (1 * 8));
+  sb[3] ^= rol(encT[(byte)(sa[1] >> (2 * 8))], (2 * 8));
+  sb[2] ^= rol(encT[(byte)(sa[1] >> (3 * 8))], (3 * 8));
+  sa[1] = rk[1][1] ^ sb[1];
+
+  sb[2] ^= rol(encT[(byte)(sa[2] >> (0 * 8))], (0 * 8));
+  sa[1] ^= rol(encT[(byte)(sa[2] >> (1 * 8))], (1 * 8));
+  sa[0] ^= rol(encT[(byte)(sa[2] >> (2 * 8))], (2 * 8));
+  sb[3] ^= rol(encT[(byte)(sa[2] >> (3 * 8))], (3 * 8));
+  sa[2] = rk[1][2] ^ sb[2];
+
+  sb[3] ^= rol(encT[(byte)(sa[3] >> (0 * 8))], (0 * 8));
+  sa[2] ^= rol(encT[(byte)(sa[3] >> (1 * 8))], (1 * 8));
+  sa[1] ^= rol(encT[(byte)(sa[3] >> (2 * 8))], (2 * 8));
+  sa[0] ^= rol(encT[(byte)(sa[3] >> (3 * 8))], (3 * 8));
+  sa[3] = rk[1][3] ^ sb[3];
+
+  for (r = 2; r < rounds; r++)
     {
-      *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(b   )) ^ *((u32_a_t*)rk[r][0]);
-      *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[r][1]);
-      *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[r][2]);
-      *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)rk[r][3]);
-
-      *((u32_a_t*)(b    ))   = (*((u32_a_t*)T1[u.temp[0][0]])
-                            ^ *((u32_a_t*)T2[u.temp[1][1]])
-                            ^ *((u32_a_t*)T3[u.temp[2][2]])
-                            ^ *((u32_a_t*)T4[u.temp[3][3]]));
-      *((u32_a_t*)(b + 4))   = (*((u32_a_t*)T1[u.temp[1][0]])
-                            ^ *((u32_a_t*)T2[u.temp[2][1]])
-                            ^ *((u32_a_t*)T3[u.temp[3][2]])
-                            ^ *((u32_a_t*)T4[u.temp[0][3]]));
-      *((u32_a_t*)(b + 8))   = (*((u32_a_t*)T1[u.temp[2][0]])
-                            ^ *((u32_a_t*)T2[u.temp[3][1]])
-                            ^ *((u32_a_t*)T3[u.temp[0][2]])
-                            ^ *((u32_a_t*)T4[u.temp[1][3]]));
-      *((u32_a_t*)(b +12))   = (*((u32_a_t*)T1[u.temp[3][0]])
-                            ^ *((u32_a_t*)T2[u.temp[0][1]])
-                            ^ *((u32_a_t*)T3[u.temp[1][2]])
-                            ^ *((u32_a_t*)T4[u.temp[2][3]]));
+      sb[0] = rol(encT[(byte)(sa[0] >> (0 * 8))], (0 * 8));
+      sb[3] = rol(encT[(byte)(sa[0] >> (1 * 8))], (1 * 8));
+      sb[2] = rol(encT[(byte)(sa[0] >> (2 * 8))], (2 * 8));
+      sb[1] = rol(encT[(byte)(sa[0] >> (3 * 8))], (3 * 8));
+      sa[0] = rk[r][0] ^ sb[0];
+
+      sb[1] ^= rol(encT[(byte)(sa[1] >> (0 * 8))], (0 * 8));
+      sa[0] ^= rol(encT[(byte)(sa[1] >> (1 * 8))], (1 * 8));
+      sb[3] ^= rol(encT[(byte)(sa[1] >> (2 * 8))], (2 * 8));
+      sb[2] ^= rol(encT[(byte)(sa[1] >> (3 * 8))], (3 * 8));
+      sa[1] = rk[r][1] ^ sb[1];
+
+      sb[2] ^= rol(encT[(byte)(sa[2] >> (0 * 8))], (0 * 8));
+      sa[1] ^= rol(encT[(byte)(sa[2] >> (1 * 8))], (1 * 8));
+      sa[0] ^= rol(encT[(byte)(sa[2] >> (2 * 8))], (2 * 8));
+      sb[3] ^= rol(encT[(byte)(sa[2] >> (3 * 8))], (3 * 8));
+      sa[2] = rk[r][2] ^ sb[2];
+
+      sb[3] ^= rol(encT[(byte)(sa[3] >> (0 * 8))], (0 * 8));
+      sa[2] ^= rol(encT[(byte)(sa[3] >> (1 * 8))], (1 * 8));
+      sa[1] ^= rol(encT[(byte)(sa[3] >> (2 * 8))], (2 * 8));
+      sa[0] ^= rol(encT[(byte)(sa[3] >> (3 * 8))], (3 * 8));
+      sa[3] = rk[r][3] ^ sb[3];
+
+      r++;
+
+      sb[0] = rol(encT[(byte)(sa[0] >> (0 * 8))], (0 * 8));
+      sb[3] = rol(encT[(byte)(sa[0] >> (1 * 8))], (1 * 8));
+      sb[2] = rol(encT[(byte)(sa[0] >> (2 * 8))], (2 * 8));
+      sb[1] = rol(encT[(byte)(sa[0] >> (3 * 8))], (3 * 8));
+      sa[0] = rk[r][0] ^ sb[0];
+
+      sb[1] ^= rol(encT[(byte)(sa[1] >> (0 * 8))], (0 * 8));
+      sa[0] ^= rol(encT[(byte)(sa[1] >> (1 * 8))], (1 * 8));
+      sb[3] ^= rol(encT[(byte)(sa[1] >> (2 * 8))], (2 * 8));
+      sb[2] ^= rol(encT[(byte)(sa[1] >> (3 * 8))], (3 * 8));
+      sa[1] = rk[r][1] ^ sb[1];
+
+      sb[2] ^= rol(encT[(byte)(sa[2] >> (0 * 8))], (0 * 8));
+      sa[1] ^= rol(encT[(byte)(sa[2] >> (1 * 8))], (1 * 8));
+      sa[0] ^= rol(encT[(byte)(sa[2] >> (2 * 8))], (2 * 8));
+      sb[3] ^= rol(encT[(byte)(sa[2] >> (3 * 8))], (3 * 8));
+      sa[2] = rk[r][2] ^ sb[2];
+
+      sb[3] ^= rol(encT[(byte)(sa[3] >> (0 * 8))], (0 * 8));
+      sa[2] ^= rol(encT[(byte)(sa[3] >> (1 * 8))], (1 * 8));
+      sa[1] ^= rol(encT[(byte)(sa[3] >> (2 * 8))], (2 * 8));
+      sa[0] ^= rol(encT[(byte)(sa[3] >> (3 * 8))], (3 * 8));
+      sa[3] = rk[r][3] ^ sb[3];
     }
 
   /* Last round is special. */
-  *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(b   )) ^ *((u32_a_t*)rk[rounds-1][0]);
-  *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[rounds-1][1]);
-  *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[rounds-1][2]);
-  *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)rk[rounds-1][3]);
-  b[ 0] = T1[u.temp[0][0]][1];
-  b[ 1] = T1[u.temp[1][1]][1];
-  b[ 2] = T1[u.temp[2][2]][1];
-  b[ 3] = T1[u.temp[3][3]][1];
-  b[ 4] = T1[u.temp[1][0]][1];
-  b[ 5] = T1[u.temp[2][1]][1];
-  b[ 6] = T1[u.temp[3][2]][1];
-  b[ 7] = T1[u.temp[0][3]][1];
-  b[ 8] = T1[u.temp[2][0]][1];
-  b[ 9] = T1[u.temp[3][1]][1];
-  b[10] = T1[u.temp[0][2]][1];
-  b[11] = T1[u.temp[1][3]][1];
-  b[12] = T1[u.temp[3][0]][1];
-  b[13] = T1[u.temp[0][1]][1];
-  b[14] = T1[u.temp[1][2]][1];
-  b[15] = T1[u.temp[2][3]][1];
-  *((u32_a_t*)(b   )) ^= *((u32_a_t*)rk[rounds][0]);
-  *((u32_a_t*)(b+ 4)) ^= *((u32_a_t*)rk[rounds][1]);
-  *((u32_a_t*)(b+ 8)) ^= *((u32_a_t*)rk[rounds][2]);
-  *((u32_a_t*)(b+12)) ^= *((u32_a_t*)rk[rounds][3]);
-#undef rk
-#endif /*!USE_AMD64_ASM && !USE_ARM_ASM*/
-}
 
+  sb[0] = (sbox[(byte)(sa[0] >> (0 * 8)) * 4]) << (0 * 8);
+  sb[3] = (sbox[(byte)(sa[0] >> (1 * 8)) * 4]) << (1 * 8);
+  sb[2] = (sbox[(byte)(sa[0] >> (2 * 8)) * 4]) << (2 * 8);
+  sb[1] = (sbox[(byte)(sa[0] >> (3 * 8)) * 4]) << (3 * 8);
+  sa[0] = rk[r][0] ^ sb[0];
+
+  sb[1] ^= (sbox[(byte)(sa[1] >> (0 * 8)) * 4]) << (0 * 8);
+  sa[0] ^= (sbox[(byte)(sa[1] >> (1 * 8)) * 4]) << (1 * 8);
+  sb[3] ^= (sbox[(byte)(sa[1] >> (2 * 8)) * 4]) << (2 * 8);
+  sb[2] ^= (sbox[(byte)(sa[1] >> (3 * 8)) * 4]) << (3 * 8);
+  sa[1] = rk[r][1] ^ sb[1];
+
+  sb[2] ^= (sbox[(byte)(sa[2] >> (0 * 8)) * 4]) << (0 * 8);
+  sa[1] ^= (sbox[(byte)(sa[2] >> (1 * 8)) * 4]) << (1 * 8);
+  sa[0] ^= (sbox[(byte)(sa[2] >> (2 * 8)) * 4]) << (2 * 8);
+  sb[3] ^= (sbox[(byte)(sa[2] >> (3 * 8)) * 4]) << (3 * 8);
+  sa[2] = rk[r][2] ^ sb[2];
+
+  sb[3] ^= (sbox[(byte)(sa[3] >> (0 * 8)) * 4]) << (0 * 8);
+  sa[2] ^= (sbox[(byte)(sa[3] >> (1 * 8)) * 4]) << (1 * 8);
+  sa[1] ^= (sbox[(byte)(sa[3] >> (2 * 8)) * 4]) << (2 * 8);
+  sa[0] ^= (sbox[(byte)(sa[3] >> (3 * 8)) * 4]) << (3 * 8);
+  sa[3] = rk[r][3] ^ sb[3];
+
+  buf_put_le32(b + 0, sa[0]);
+  buf_put_le32(b + 4, sa[1]);
+  buf_put_le32(b + 8, sa[2]);
+  buf_put_le32(b + 12, sa[3]);
+#undef rk
 
-static void
-do_encrypt (const RIJNDAEL_context *ctx,
-            unsigned char *bx, const unsigned char *ax)
-{
-#if !defined(USE_AMD64_ASM) && !defined(USE_ARM_ASM)
-  /* BX and AX are not necessary correctly aligned.  Thus we might
-     need to copy them here.  We try to align to a 16 bytes.  */
-  if (((size_t)ax & 0x0f) || ((size_t)bx & 0x0f))
-    {
-      union
-      {
-        u32  dummy[4];
-        byte a[16] ATTR_ALIGNED_16;
-      } a;
-      union
-      {
-        u32  dummy[4];
-        byte b[16] ATTR_ALIGNED_16;
-      } b;
-
-      buf_cpy (a.a, ax, 16);
-      do_encrypt_aligned (ctx, b.b, a.a);
-      buf_cpy (bx, b.b, 16);
-    }
-  else
-#endif /*!USE_AMD64_ASM && !USE_ARM_ASM*/
-    {
-      do_encrypt_aligned (ctx, bx, ax);
-    }
+  return (56 + 2*sizeof(int));
 }
+#endif /*!USE_ARM_ASM && !USE_AMD64_ASM*/
 
 
-/* Encrypt or decrypt one block using the padlock engine.  A and B may
-   be the same. */
-#ifdef USE_PADLOCK
-static void
-do_padlock (const RIJNDAEL_context *ctx, int decrypt_flag,
+static unsigned int
+do_encrypt (const RIJNDAEL_context *ctx,
             unsigned char *bx, const unsigned char *ax)
 {
-  /* BX and AX are not necessary correctly aligned.  Thus we need to
-     copy them here. */
-  unsigned char a[16] __attribute__ ((aligned (16)));
-  unsigned char b[16] __attribute__ ((aligned (16)));
-  unsigned int cword[4] __attribute__ ((aligned (16)));
-  int blocks;
-
-  /* The control word fields are:
-      127:12   11:10 9     8     7     6     5     4     3:0
-      RESERVED KSIZE CRYPT INTER KEYGN CIPHR ALIGN DGEST ROUND  */
-  cword[0] = (ctx->rounds & 15);  /* (The mask is just a safeguard.)  */
-  cword[1] = 0;
-  cword[2] = 0;
-  cword[3] = 0;
-  if (decrypt_flag)
-    cword[0] |= 0x00000200;
-
-  memcpy (a, ax, 16);
-
-  blocks = 1; /* Init counter for just one block.  */
-#ifdef __x86_64__
-  asm volatile
-    ("pushfq\n\t"          /* Force key reload.  */
-     "popfq\n\t"
-     ".byte 0xf3, 0x0f, 0xa7, 0xc8\n\t" /* REP XCRYPT ECB. */
-     : /* No output */
-     : "S" (a), "D" (b), "d" (cword), "b" (ctx->padlockkey), "c" (blocks)
-     : "cc", "memory"
-     );
+#ifdef USE_AMD64_ASM
+# ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+  return _gcry_aes_amd64_encrypt_block(ctx->keyschenc, bx, ax, ctx->rounds,
+                                      encT);
+# else
+  /* Call SystemV ABI function without storing non-volatile XMM registers,
+   * as target function does not use vector instruction sets. */
+  const void *key = ctx->keyschenc;
+  uintptr_t rounds = ctx->rounds;
+  uintptr_t ret;
+  asm volatile ("movq %[encT], %%r8\n\t"
+                "callq *%[ret]\n\t"
+                : [ret] "=a" (ret),
+                  "+D" (key),
+                  "+S" (bx),
+                  "+d" (ax),
+                  "+c" (rounds)
+                : "0" (_gcry_aes_amd64_encrypt_block),
+                  [encT] "g" (encT)
+                : "cc", "memory", "r8", "r9", "r10", "r11");
+  return ret;
+# endif /* HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS */
+#elif defined(USE_ARM_ASM)
+  return _gcry_aes_arm_encrypt_block(ctx->keyschenc, bx, ax, ctx->rounds, encT);
 #else
-  asm volatile
-    ("pushfl\n\t"          /* Force key reload.  */
-     "popfl\n\t"
-     "xchg %3, %%ebx\n\t"  /* Load key.  */
-     ".byte 0xf3, 0x0f, 0xa7, 0xc8\n\t" /* REP XCRYPT ECB. */
-     "xchg %3, %%ebx\n"    /* Restore GOT register.  */
-     : /* No output */
-     : "S" (a), "D" (b), "d" (cword), "r" (ctx->padlockkey), "c" (blocks)
-     : "cc", "memory"
-     );
-#endif
-
-  memcpy (bx, b, 16);
-
-}
-#endif /*USE_PADLOCK*/
-
-
-#ifdef USE_AESNI
-/* Encrypt one block using the Intel AES-NI instructions.  A and B may
-   be the same.
-
-   Our problem here is that gcc does not allow the "x" constraint for
-   SSE registers in asm unless you compile with -msse.  The common
-   wisdom is to use a separate file for SSE instructions and build it
-   separately.  This would require a lot of extra build system stuff,
-   similar to what we do in mpi/ for the asm stuff.  What we do
-   instead is to use standard registers and a bit more of plain asm
-   which copies the data and key stuff to the SSE registers and later
-   back.  If we decide to implement some block modes with parallelized
-   AES instructions, it might indeed be better to use plain asm ala
-   mpi/.  */
-static inline void
-do_aesni_enc (const RIJNDAEL_context *ctx, unsigned char *b,
-              const unsigned char *a)
-{
-#define aesenc_xmm1_xmm0      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t"
-#define aesenclast_xmm1_xmm0  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t"
-  /* Note: For now we relax the alignment requirement for A and B: It
-     does not make much difference because in many case we would need
-     to memcpy them to an extra buffer; using the movdqu is much faster
-     that memcpy and movdqa.  For CFB we know that the IV is properly
-     aligned but that is a special case.  We should better implement
-     CFB direct in asm.  */
-  asm volatile ("movdqu %[src], %%xmm0\n\t"     /* xmm0 := *a     */
-                "movdqa (%[key]), %%xmm1\n\t"    /* xmm1 := key[0] */
-                "pxor   %%xmm1, %%xmm0\n\t"     /* xmm0 ^= key[0] */
-                "movdqa 0x10(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0x20(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0x30(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0x40(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0x50(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0x60(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0x70(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0x80(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0x90(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0xa0(%[key]), %%xmm1\n\t"
-                "cmpl $10, %[rounds]\n\t"
-                "jz .Lenclast%=\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0xb0(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0xc0(%[key]), %%xmm1\n\t"
-                "cmpl $12, %[rounds]\n\t"
-                "jz .Lenclast%=\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0xd0(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0xe0(%[key]), %%xmm1\n"
-
-                ".Lenclast%=:\n\t"
-                aesenclast_xmm1_xmm0
-                "movdqu %%xmm0, %[dst]\n"
-                : [dst] "=m" (*b)
-                : [src] "m" (*a),
-                  [key] "r" (ctx->keyschenc),
-                  [rounds] "r" (ctx->rounds)
-                : "cc", "memory");
-#undef aesenc_xmm1_xmm0
-#undef aesenclast_xmm1_xmm0
-}
-
-
-static inline void
-do_aesni_dec (const RIJNDAEL_context *ctx, unsigned char *b,
-              const unsigned char *a)
-{
-#define aesdec_xmm1_xmm0      ".byte 0x66, 0x0f, 0x38, 0xde, 0xc1\n\t"
-#define aesdeclast_xmm1_xmm0  ".byte 0x66, 0x0f, 0x38, 0xdf, 0xc1\n\t"
-  asm volatile ("movdqu %[src], %%xmm0\n\t"     /* xmm0 := *a     */
-                "movdqa (%[key]), %%xmm1\n\t"
-                "pxor   %%xmm1, %%xmm0\n\t"     /* xmm0 ^= key[0] */
-                "movdqa 0x10(%[key]), %%xmm1\n\t"
-                aesdec_xmm1_xmm0
-                "movdqa 0x20(%[key]), %%xmm1\n\t"
-                aesdec_xmm1_xmm0
-                "movdqa 0x30(%[key]), %%xmm1\n\t"
-                aesdec_xmm1_xmm0
-                "movdqa 0x40(%[key]), %%xmm1\n\t"
-                aesdec_xmm1_xmm0
-                "movdqa 0x50(%[key]), %%xmm1\n\t"
-                aesdec_xmm1_xmm0
-                "movdqa 0x60(%[key]), %%xmm1\n\t"
-                aesdec_xmm1_xmm0
-                "movdqa 0x70(%[key]), %%xmm1\n\t"
-                aesdec_xmm1_xmm0
-                "movdqa 0x80(%[key]), %%xmm1\n\t"
-                aesdec_xmm1_xmm0
-                "movdqa 0x90(%[key]), %%xmm1\n\t"
-                aesdec_xmm1_xmm0
-                "movdqa 0xa0(%[key]), %%xmm1\n\t"
-                "cmpl $10, %[rounds]\n\t"
-                "jz .Ldeclast%=\n\t"
-                aesdec_xmm1_xmm0
-                "movdqa 0xb0(%[key]), %%xmm1\n\t"
-                aesdec_xmm1_xmm0
-                "movdqa 0xc0(%[key]), %%xmm1\n\t"
-                "cmpl $12, %[rounds]\n\t"
-                "jz .Ldeclast%=\n\t"
-                aesdec_xmm1_xmm0
-                "movdqa 0xd0(%[key]), %%xmm1\n\t"
-                aesdec_xmm1_xmm0
-                "movdqa 0xe0(%[key]), %%xmm1\n"
-
-                ".Ldeclast%=:\n\t"
-                aesdeclast_xmm1_xmm0
-                "movdqu %%xmm0, %[dst]\n"
-                : [dst] "=m" (*b)
-                : [src] "m" (*a),
-                  [key] "r" (ctx->keyschdec),
-                  [rounds] "r" (ctx->rounds)
-                : "cc", "memory");
-#undef aesdec_xmm1_xmm0
-#undef aesdeclast_xmm1_xmm0
+  return do_encrypt_fn (ctx, bx, ax);
+#endif /* !USE_ARM_ASM && !USE_AMD64_ASM*/
 }
 
 
-/* Encrypt four blocks using the Intel AES-NI instructions.  Blocks are input
- * and output through SSE registers xmm1 to xmm4.  */
-static void
-do_aesni_enc_vec4 (const RIJNDAEL_context *ctx)
-{
-#define aesenc_xmm0_xmm1      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc8\n\t"
-#define aesenc_xmm0_xmm2      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd0\n\t"
-#define aesenc_xmm0_xmm3      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd8\n\t"
-#define aesenc_xmm0_xmm4      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xe0\n\t"
-#define aesenclast_xmm0_xmm1  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc8\n\t"
-#define aesenclast_xmm0_xmm2  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd0\n\t"
-#define aesenclast_xmm0_xmm3  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd8\n\t"
-#define aesenclast_xmm0_xmm4  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xe0\n\t"
-  asm volatile ("movdqa (%[key]), %%xmm0\n\t"
-                "pxor   %%xmm0, %%xmm1\n\t"     /* xmm1 ^= key[0] */
-                "pxor   %%xmm0, %%xmm2\n\t"     /* xmm2 ^= key[0] */
-                "pxor   %%xmm0, %%xmm3\n\t"     /* xmm3 ^= key[0] */
-                "pxor   %%xmm0, %%xmm4\n\t"     /* xmm4 ^= key[0] */
-                "movdqa 0x10(%[key]), %%xmm0\n\t"
-                aesenc_xmm0_xmm1
-                aesenc_xmm0_xmm2
-                aesenc_xmm0_xmm3
-                aesenc_xmm0_xmm4
-                "movdqa 0x20(%[key]), %%xmm0\n\t"
-                aesenc_xmm0_xmm1
-                aesenc_xmm0_xmm2
-                aesenc_xmm0_xmm3
-                aesenc_xmm0_xmm4
-                "movdqa 0x30(%[key]), %%xmm0\n\t"
-                aesenc_xmm0_xmm1
-                aesenc_xmm0_xmm2
-                aesenc_xmm0_xmm3
-                aesenc_xmm0_xmm4
-                "movdqa 0x40(%[key]), %%xmm0\n\t"
-                aesenc_xmm0_xmm1
-                aesenc_xmm0_xmm2
-                aesenc_xmm0_xmm3
-                aesenc_xmm0_xmm4
-                "movdqa 0x50(%[key]), %%xmm0\n\t"
-                aesenc_xmm0_xmm1
-                aesenc_xmm0_xmm2
-                aesenc_xmm0_xmm3
-                aesenc_xmm0_xmm4
-                "movdqa 0x60(%[key]), %%xmm0\n\t"
-                aesenc_xmm0_xmm1
-                aesenc_xmm0_xmm2
-                aesenc_xmm0_xmm3
-                aesenc_xmm0_xmm4
-                "movdqa 0x70(%[key]), %%xmm0\n\t"
-                aesenc_xmm0_xmm1
-                aesenc_xmm0_xmm2
-                aesenc_xmm0_xmm3
-                aesenc_xmm0_xmm4
-                "movdqa 0x80(%[key]), %%xmm0\n\t"
-                aesenc_xmm0_xmm1
-                aesenc_xmm0_xmm2
-                aesenc_xmm0_xmm3
-                aesenc_xmm0_xmm4
-                "movdqa 0x90(%[key]), %%xmm0\n\t"
-                aesenc_xmm0_xmm1
-                aesenc_xmm0_xmm2
-                aesenc_xmm0_xmm3
-                aesenc_xmm0_xmm4
-                "movdqa 0xa0(%[key]), %%xmm0\n\t"
-                "cmpl $10, %[rounds]\n\t"
-                "jz .Ldeclast%=\n\t"
-                aesenc_xmm0_xmm1
-                aesenc_xmm0_xmm2
-                aesenc_xmm0_xmm3
-                aesenc_xmm0_xmm4
-                "movdqa 0xb0(%[key]), %%xmm0\n\t"
-                aesenc_xmm0_xmm1
-                aesenc_xmm0_xmm2
-                aesenc_xmm0_xmm3
-                aesenc_xmm0_xmm4
-                "movdqa 0xc0(%[key]), %%xmm0\n\t"
-                "cmpl $12, %[rounds]\n\t"
-                "jz .Ldeclast%=\n\t"
-                aesenc_xmm0_xmm1
-                aesenc_xmm0_xmm2
-                aesenc_xmm0_xmm3
-                aesenc_xmm0_xmm4
-                "movdqa 0xd0(%[key]), %%xmm0\n\t"
-                aesenc_xmm0_xmm1
-                aesenc_xmm0_xmm2
-                aesenc_xmm0_xmm3
-                aesenc_xmm0_xmm4
-                "movdqa 0xe0(%[key]), %%xmm0\n"
-
-                ".Ldeclast%=:\n\t"
-                aesenclast_xmm0_xmm1
-                aesenclast_xmm0_xmm2
-                aesenclast_xmm0_xmm3
-                aesenclast_xmm0_xmm4
-                : /* no output */
-                : [key] "r" (ctx->keyschenc),
-                  [rounds] "r" (ctx->rounds)
-                : "cc", "memory");
-#undef aesenc_xmm0_xmm1
-#undef aesenc_xmm0_xmm2
-#undef aesenc_xmm0_xmm3
-#undef aesenc_xmm0_xmm4
-#undef aesenclast_xmm0_xmm1
-#undef aesenclast_xmm0_xmm2
-#undef aesenclast_xmm0_xmm3
-#undef aesenclast_xmm0_xmm4
-}
-
-
-/* Decrypt four blocks using the Intel AES-NI instructions.  Blocks are input
- * and output through SSE registers xmm1 to xmm4.  */
-static void
-do_aesni_dec_vec4 (const RIJNDAEL_context *ctx)
-{
-#define aesdec_xmm0_xmm1 ".byte 0x66, 0x0f, 0x38, 0xde, 0xc8\n\t"
-#define aesdec_xmm0_xmm2 ".byte 0x66, 0x0f, 0x38, 0xde, 0xd0\n\t"
-#define aesdec_xmm0_xmm3 ".byte 0x66, 0x0f, 0x38, 0xde, 0xd8\n\t"
-#define aesdec_xmm0_xmm4 ".byte 0x66, 0x0f, 0x38, 0xde, 0xe0\n\t"
-#define aesdeclast_xmm0_xmm1 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xc8\n\t"
-#define aesdeclast_xmm0_xmm2 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xd0\n\t"
-#define aesdeclast_xmm0_xmm3 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xd8\n\t"
-#define aesdeclast_xmm0_xmm4 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xe0\n\t"
-  asm volatile ("movdqa (%[key]), %%xmm0\n\t"
-                "pxor   %%xmm0, %%xmm1\n\t"     /* xmm1 ^= key[0] */
-                "pxor   %%xmm0, %%xmm2\n\t"     /* xmm2 ^= key[0] */
-                "pxor   %%xmm0, %%xmm3\n\t"     /* xmm3 ^= key[0] */
-                "pxor   %%xmm0, %%xmm4\n\t"     /* xmm4 ^= key[0] */
-                "movdqa 0x10(%[key]), %%xmm0\n\t"
-                aesdec_xmm0_xmm1
-                aesdec_xmm0_xmm2
-                aesdec_xmm0_xmm3
-                aesdec_xmm0_xmm4
-                "movdqa 0x20(%[key]), %%xmm0\n\t"
-                aesdec_xmm0_xmm1
-                aesdec_xmm0_xmm2
-                aesdec_xmm0_xmm3
-                aesdec_xmm0_xmm4
-                "movdqa 0x30(%[key]), %%xmm0\n\t"
-                aesdec_xmm0_xmm1
-                aesdec_xmm0_xmm2
-                aesdec_xmm0_xmm3
-                aesdec_xmm0_xmm4
-                "movdqa 0x40(%[key]), %%xmm0\n\t"
-                aesdec_xmm0_xmm1
-                aesdec_xmm0_xmm2
-                aesdec_xmm0_xmm3
-                aesdec_xmm0_xmm4
-                "movdqa 0x50(%[key]), %%xmm0\n\t"
-                aesdec_xmm0_xmm1
-                aesdec_xmm0_xmm2
-                aesdec_xmm0_xmm3
-                aesdec_xmm0_xmm4
-                "movdqa 0x60(%[key]), %%xmm0\n\t"
-                aesdec_xmm0_xmm1
-                aesdec_xmm0_xmm2
-                aesdec_xmm0_xmm3
-                aesdec_xmm0_xmm4
-                "movdqa 0x70(%[key]), %%xmm0\n\t"
-                aesdec_xmm0_xmm1
-                aesdec_xmm0_xmm2
-                aesdec_xmm0_xmm3
-                aesdec_xmm0_xmm4
-                "movdqa 0x80(%[key]), %%xmm0\n\t"
-                aesdec_xmm0_xmm1
-                aesdec_xmm0_xmm2
-                aesdec_xmm0_xmm3
-                aesdec_xmm0_xmm4
-                "movdqa 0x90(%[key]), %%xmm0\n\t"
-                aesdec_xmm0_xmm1
-                aesdec_xmm0_xmm2
-                aesdec_xmm0_xmm3
-                aesdec_xmm0_xmm4
-                "movdqa 0xa0(%[key]), %%xmm0\n\t"
-                "cmpl $10, %[rounds]\n\t"
-                "jz .Ldeclast%=\n\t"
-                aesdec_xmm0_xmm1
-                aesdec_xmm0_xmm2
-                aesdec_xmm0_xmm3
-                aesdec_xmm0_xmm4
-                "movdqa 0xb0(%[key]), %%xmm0\n\t"
-                aesdec_xmm0_xmm1
-                aesdec_xmm0_xmm2
-                aesdec_xmm0_xmm3
-                aesdec_xmm0_xmm4
-                "movdqa 0xc0(%[key]), %%xmm0\n\t"
-                "cmpl $12, %[rounds]\n\t"
-                "jz .Ldeclast%=\n\t"
-                aesdec_xmm0_xmm1
-                aesdec_xmm0_xmm2
-                aesdec_xmm0_xmm3
-                aesdec_xmm0_xmm4
-                "movdqa 0xd0(%[key]), %%xmm0\n\t"
-                aesdec_xmm0_xmm1
-                aesdec_xmm0_xmm2
-                aesdec_xmm0_xmm3
-                aesdec_xmm0_xmm4
-                "movdqa 0xe0(%[key]), %%xmm0\n"
-
-                ".Ldeclast%=:\n\t"
-                aesdeclast_xmm0_xmm1
-                aesdeclast_xmm0_xmm2
-                aesdeclast_xmm0_xmm3
-                aesdeclast_xmm0_xmm4
-                : /* no output */
-                : [key] "r" (ctx->keyschdec),
-                  [rounds] "r" (ctx->rounds)
-                : "cc", "memory");
-#undef aesdec_xmm0_xmm1
-#undef aesdec_xmm0_xmm2
-#undef aesdec_xmm0_xmm3
-#undef aesdec_xmm0_xmm4
-#undef aesdeclast_xmm0_xmm1
-#undef aesdeclast_xmm0_xmm2
-#undef aesdeclast_xmm0_xmm3
-#undef aesdeclast_xmm0_xmm4
-}
-
-
-/* Perform a CFB encryption or decryption round using the
-   initialization vector IV and the input block A.  Write the result
-   to the output block B and update IV.  IV needs to be 16 byte
-   aligned.  */
-static void
-do_aesni_cfb (const RIJNDAEL_context *ctx, int decrypt_flag,
-              unsigned char *iv, unsigned char *b, const unsigned char *a)
-{
-#define aesenc_xmm1_xmm0      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t"
-#define aesenclast_xmm1_xmm0  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t"
-  asm volatile ("movdqa %[iv], %%xmm0\n\t"      /* xmm0 := IV     */
-                "movdqa (%[key]), %%xmm1\n\t"    /* xmm1 := key[0] */
-                "pxor   %%xmm1, %%xmm0\n\t"     /* xmm0 ^= key[0] */
-                "movdqa 0x10(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0x20(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0x30(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0x40(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0x50(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0x60(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0x70(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0x80(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0x90(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0xa0(%[key]), %%xmm1\n\t"
-                "cmpl $10, %[rounds]\n\t"
-                "jz .Lenclast%=\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0xb0(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0xc0(%[key]), %%xmm1\n\t"
-                "cmpl $12, %[rounds]\n\t"
-                "jz .Lenclast%=\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0xd0(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0xe0(%[key]), %%xmm1\n"
-
-                ".Lenclast%=:\n\t"
-                aesenclast_xmm1_xmm0
-                "movdqu %[src], %%xmm1\n\t"      /* Save input.  */
-                "pxor %%xmm1, %%xmm0\n\t"        /* xmm0 = input ^ IV  */
-
-                "cmpl $1, %[decrypt]\n\t"
-                "jz .Ldecrypt_%=\n\t"
-                "movdqa %%xmm0, %[iv]\n\t"       /* [encrypt] Store IV.  */
-                "jmp .Lleave_%=\n"
-                ".Ldecrypt_%=:\n\t"
-                "movdqa %%xmm1, %[iv]\n"         /* [decrypt] Store IV.  */
-                ".Lleave_%=:\n\t"
-                "movdqu %%xmm0, %[dst]\n"        /* Store output.   */
-                : [iv] "+m" (*iv), [dst] "=m" (*b)
-                : [src] "m" (*a),
-                  [key] "r" (ctx->keyschenc),
-                  [rounds] "g" (ctx->rounds),
-                  [decrypt] "m" (decrypt_flag)
-                : "cc", "memory");
-#undef aesenc_xmm1_xmm0
-#undef aesenclast_xmm1_xmm0
-}
-
-/* Perform a CTR encryption round using the counter CTR and the input
-   block A.  Write the result to the output block B and update CTR.
-   CTR needs to be a 16 byte aligned little-endian value.  */
-static void
-do_aesni_ctr (const RIJNDAEL_context *ctx,
-              unsigned char *ctr, unsigned char *b, const unsigned char *a)
-{
-#define aesenc_xmm1_xmm0      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t"
-#define aesenclast_xmm1_xmm0  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t"
-
-  asm volatile ("movdqa %%xmm5, %%xmm0\n\t"     /* xmm0 := CTR (xmm5)  */
-                "pcmpeqd %%xmm1, %%xmm1\n\t"
-                "psrldq $8, %%xmm1\n\t"         /* xmm1 = -1 */
-
-                "pshufb %%xmm6, %%xmm5\n\t"
-                "psubq  %%xmm1, %%xmm5\n\t"     /* xmm5++ (big endian) */
-
-                /* detect if 64-bit carry handling is needed */
-                "cmpl   $0xffffffff, 8(%[ctr])\n\t"
-                "jne    .Lno_carry%=\n\t"
-                "cmpl   $0xffffffff, 12(%[ctr])\n\t"
-                "jne    .Lno_carry%=\n\t"
-
-                "pslldq $8, %%xmm1\n\t"         /* move lower 64-bit to high */
-                "psubq   %%xmm1, %%xmm5\n\t"    /* add carry to upper 64bits */
-
-                ".Lno_carry%=:\n\t"
-
-                "pshufb %%xmm6, %%xmm5\n\t"
-                "movdqa %%xmm5, (%[ctr])\n\t"   /* Update CTR (mem).       */
-
-                "pxor (%[key]), %%xmm0\n\t"     /* xmm1 ^= key[0]    */
-                "movdqa 0x10(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0x20(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0x30(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0x40(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0x50(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0x60(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0x70(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0x80(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0x90(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0xa0(%[key]), %%xmm1\n\t"
-                "cmpl $10, %[rounds]\n\t"
-                "jz .Lenclast%=\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0xb0(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0xc0(%[key]), %%xmm1\n\t"
-                "cmpl $12, %[rounds]\n\t"
-                "jz .Lenclast%=\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0xd0(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                "movdqa 0xe0(%[key]), %%xmm1\n"
-
-                ".Lenclast%=:\n\t"
-                aesenclast_xmm1_xmm0
-                "movdqu %[src], %%xmm1\n\t"      /* xmm1 := input   */
-                "pxor %%xmm1, %%xmm0\n\t"        /* EncCTR ^= input  */
-                "movdqu %%xmm0, %[dst]"          /* Store EncCTR.    */
-
-                : [dst] "=m" (*b)
-                : [src] "m" (*a),
-                  [ctr] "r" (ctr),
-                  [key] "r" (ctx->keyschenc),
-                  [rounds] "g" (ctx->rounds)
-                : "cc", "memory");
-#undef aesenc_xmm1_xmm0
-#undef aesenclast_xmm1_xmm0
-}
-
-
-/* Four blocks at a time variant of do_aesni_ctr.  */
-static void
-do_aesni_ctr_4 (const RIJNDAEL_context *ctx,
-                unsigned char *ctr, unsigned char *b, const unsigned char *a)
-{
-#define aesenc_xmm1_xmm0      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t"
-#define aesenc_xmm1_xmm2      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd1\n\t"
-#define aesenc_xmm1_xmm3      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd9\n\t"
-#define aesenc_xmm1_xmm4      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xe1\n\t"
-#define aesenclast_xmm1_xmm0  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t"
-#define aesenclast_xmm1_xmm2  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd1\n\t"
-#define aesenclast_xmm1_xmm3  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd9\n\t"
-#define aesenclast_xmm1_xmm4  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xe1\n\t"
-
-  /* Register usage:
-      esi   keyschedule
-      xmm0  CTR-0
-      xmm1  temp / round key
-      xmm2  CTR-1
-      xmm3  CTR-2
-      xmm4  CTR-3
-      xmm5  copy of *ctr
-      xmm6  endian swapping mask
-   */
-
-  asm volatile ("movdqa %%xmm5, %%xmm0\n\t"   /* xmm0, xmm2 := CTR (xmm5) */
-                "movdqa %%xmm0, %%xmm2\n\t"
-                "pcmpeqd %%xmm1, %%xmm1\n\t"
-                "psrldq $8, %%xmm1\n\t"         /* xmm1 = -1 */
-
-                "pshufb %%xmm6, %%xmm2\n\t"     /* xmm2 := le(xmm2) */
-                "psubq  %%xmm1, %%xmm2\n\t"     /* xmm2++           */
-                "movdqa %%xmm2, %%xmm3\n\t"     /* xmm3 := xmm2     */
-                "psubq  %%xmm1, %%xmm3\n\t"     /* xmm3++           */
-                "movdqa %%xmm3, %%xmm4\n\t"     /* xmm4 := xmm3     */
-                "psubq  %%xmm1, %%xmm4\n\t"     /* xmm4++           */
-                "movdqa %%xmm4, %%xmm5\n\t"     /* xmm5 := xmm4     */
-                "psubq  %%xmm1, %%xmm5\n\t"     /* xmm5++           */
-
-                /* detect if 64-bit carry handling is needed */
-                "cmpl   $0xffffffff, 8(%[ctr])\n\t"
-                "jne    .Lno_carry%=\n\t"
-                "movl   12(%[ctr]), %%esi\n\t"
-                "bswapl %%esi\n\t"
-                "cmpl   $0xfffffffc, %%esi\n\t"
-                "jb     .Lno_carry%=\n\t"       /* no carry */
-
-                "pslldq $8, %%xmm1\n\t"         /* move lower 64-bit to high */
-                "je     .Lcarry_xmm5%=\n\t"     /* esi == 0xfffffffc */
-                "cmpl   $0xfffffffe, %%esi\n\t"
-                "jb     .Lcarry_xmm4%=\n\t"     /* esi == 0xfffffffd */
-                "je     .Lcarry_xmm3%=\n\t"     /* esi == 0xfffffffe */
-                /* esi == 0xffffffff */
-
-                "psubq   %%xmm1, %%xmm2\n\t"
-                ".Lcarry_xmm3%=:\n\t"
-                "psubq   %%xmm1, %%xmm3\n\t"
-                ".Lcarry_xmm4%=:\n\t"
-                "psubq   %%xmm1, %%xmm4\n\t"
-                ".Lcarry_xmm5%=:\n\t"
-                "psubq   %%xmm1, %%xmm5\n\t"
-
-                ".Lno_carry%=:\n\t"
-                "movdqa (%[key]), %%xmm1\n\t"   /* xmm1 := key[0]    */
-                "movl %[rounds], %%esi\n\t"
-
-                "pshufb %%xmm6, %%xmm2\n\t"     /* xmm2 := be(xmm2) */
-                "pshufb %%xmm6, %%xmm3\n\t"     /* xmm3 := be(xmm3) */
-                "pshufb %%xmm6, %%xmm4\n\t"     /* xmm4 := be(xmm4) */
-                "pshufb %%xmm6, %%xmm5\n\t"     /* xmm5 := be(xmm5) */
-                "movdqa %%xmm5, (%[ctr])\n\t"   /* Update CTR (mem).  */
-
-                "pxor   %%xmm1, %%xmm0\n\t"     /* xmm0 ^= key[0]    */
-                "pxor   %%xmm1, %%xmm2\n\t"     /* xmm2 ^= key[0]    */
-                "pxor   %%xmm1, %%xmm3\n\t"     /* xmm3 ^= key[0]    */
-                "pxor   %%xmm1, %%xmm4\n\t"     /* xmm4 ^= key[0]    */
-                "movdqa 0x10(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                aesenc_xmm1_xmm2
-                aesenc_xmm1_xmm3
-                aesenc_xmm1_xmm4
-                "movdqa 0x20(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                aesenc_xmm1_xmm2
-                aesenc_xmm1_xmm3
-                aesenc_xmm1_xmm4
-                "movdqa 0x30(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                aesenc_xmm1_xmm2
-                aesenc_xmm1_xmm3
-                aesenc_xmm1_xmm4
-                "movdqa 0x40(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                aesenc_xmm1_xmm2
-                aesenc_xmm1_xmm3
-                aesenc_xmm1_xmm4
-                "movdqa 0x50(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                aesenc_xmm1_xmm2
-                aesenc_xmm1_xmm3
-                aesenc_xmm1_xmm4
-                "movdqa 0x60(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                aesenc_xmm1_xmm2
-                aesenc_xmm1_xmm3
-                aesenc_xmm1_xmm4
-                "movdqa 0x70(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                aesenc_xmm1_xmm2
-                aesenc_xmm1_xmm3
-                aesenc_xmm1_xmm4
-                "movdqa 0x80(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                aesenc_xmm1_xmm2
-                aesenc_xmm1_xmm3
-                aesenc_xmm1_xmm4
-                "movdqa 0x90(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                aesenc_xmm1_xmm2
-                aesenc_xmm1_xmm3
-                aesenc_xmm1_xmm4
-                "movdqa 0xa0(%[key]), %%xmm1\n\t"
-                "cmpl $10, %%esi\n\t"
-                "jz .Lenclast%=\n\t"
-                aesenc_xmm1_xmm0
-                aesenc_xmm1_xmm2
-                aesenc_xmm1_xmm3
-                aesenc_xmm1_xmm4
-                "movdqa 0xb0(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                aesenc_xmm1_xmm2
-                aesenc_xmm1_xmm3
-                aesenc_xmm1_xmm4
-                "movdqa 0xc0(%[key]), %%xmm1\n\t"
-                "cmpl $12, %%esi\n\t"
-                "jz .Lenclast%=\n\t"
-                aesenc_xmm1_xmm0
-                aesenc_xmm1_xmm2
-                aesenc_xmm1_xmm3
-                aesenc_xmm1_xmm4
-                "movdqa 0xd0(%[key]), %%xmm1\n\t"
-                aesenc_xmm1_xmm0
-                aesenc_xmm1_xmm2
-                aesenc_xmm1_xmm3
-                aesenc_xmm1_xmm4
-                "movdqa 0xe0(%[key]), %%xmm1\n"
-
-                ".Lenclast%=:\n\t"
-                aesenclast_xmm1_xmm0
-                aesenclast_xmm1_xmm2
-                aesenclast_xmm1_xmm3
-                aesenclast_xmm1_xmm4
-
-                "movdqu (%[src]), %%xmm1\n\t"    /* Get block 1.      */
-                "pxor %%xmm1, %%xmm0\n\t"        /* EncCTR-1 ^= input */
-                "movdqu %%xmm0, (%[dst])\n\t"    /* Store block 1     */
-
-                "movdqu 16(%[src]), %%xmm1\n\t"  /* Get block 2.      */
-                "pxor %%xmm1, %%xmm2\n\t"        /* EncCTR-2 ^= input */
-                "movdqu %%xmm2, 16(%[dst])\n\t"  /* Store block 2.    */
-
-                "movdqu 32(%[src]), %%xmm1\n\t"  /* Get block 3.      */
-                "pxor %%xmm1, %%xmm3\n\t"        /* EncCTR-3 ^= input */
-                "movdqu %%xmm3, 32(%[dst])\n\t"  /* Store block 3.    */
-
-                "movdqu 48(%[src]), %%xmm1\n\t"  /* Get block 4.      */
-                "pxor %%xmm1, %%xmm4\n\t"        /* EncCTR-4 ^= input */
-                "movdqu %%xmm4, 48(%[dst])"      /* Store block 4.   */
-
-                :
-                : [ctr] "r" (ctr),
-                  [src] "r" (a),
-                  [dst] "r" (b),
-                  [key] "r" (ctx->keyschenc),
-                  [rounds] "g" (ctx->rounds)
-                : "%esi", "cc", "memory");
-#undef aesenc_xmm1_xmm0
-#undef aesenc_xmm1_xmm2
-#undef aesenc_xmm1_xmm3
-#undef aesenc_xmm1_xmm4
-#undef aesenclast_xmm1_xmm0
-#undef aesenclast_xmm1_xmm2
-#undef aesenclast_xmm1_xmm3
-#undef aesenclast_xmm1_xmm4
-}
-
-#endif /*USE_AESNI*/
-
-
 static unsigned int
 rijndael_encrypt (void *context, byte *b, const byte *a)
 {
   RIJNDAEL_context *ctx = context;
-  unsigned int burn_stack;
 
-  if (0)
-    ;
-#ifdef USE_PADLOCK
-  else if (ctx->use_padlock)
-    {
-      do_padlock (ctx, 0, b, a);
-      burn_stack = (48 + 15 /* possible padding for alignment */);
-    }
-#endif /*USE_PADLOCK*/
-#ifdef USE_AESNI
-  else if (ctx->use_aesni)
-    {
-      aesni_prepare ();
-      do_aesni_enc (ctx, b, a);
-      aesni_cleanup ();
-      burn_stack = 0;
-    }
-#endif /*USE_AESNI*/
-  else
-    {
-      do_encrypt (ctx, b, a);
-      burn_stack = (56 + 2*sizeof(int));
-    }
+  if (ctx->prefetch_enc_fn)
+    ctx->prefetch_enc_fn();
 
-  return burn_stack;
+  return ctx->encrypt_fn (ctx, b, a);
 }
 
 
@@ -1681,46 +723,35 @@ _gcry_aes_cfb_enc (void *context, unsigned char *iv,
   RIJNDAEL_context *ctx = context;
   unsigned char *outbuf = outbuf_arg;
   const unsigned char *inbuf = inbuf_arg;
-  unsigned int burn_depth = 48 + 2*sizeof(int);
+  unsigned int burn_depth = 0;
+
+  if (ctx->prefetch_enc_fn)
+    ctx->prefetch_enc_fn();
 
   if (0)
     ;
-#ifdef USE_PADLOCK
-  else if (ctx->use_padlock)
-    {
-      /* Fixme: Let Padlock do the CFBing.  */
-      for ( ;nblocks; nblocks-- )
-        {
-          /* Encrypt the IV. */
-          do_padlock (ctx, 0, iv, iv);
-          /* XOR the input with the IV and store input into IV.  */
-          buf_xor_2dst(outbuf, iv, inbuf, BLOCKSIZE);
-          outbuf += BLOCKSIZE;
-          inbuf  += BLOCKSIZE;
-        }
-    }
-#endif /*USE_PADLOCK*/
 #ifdef USE_AESNI
   else if (ctx->use_aesni)
     {
-      aesni_prepare ();
-      for ( ;nblocks; nblocks-- )
-        {
-          do_aesni_cfb (ctx, 0, iv, outbuf, inbuf);
-          outbuf += BLOCKSIZE;
-          inbuf  += BLOCKSIZE;
-        }
-      aesni_cleanup ();
-
-      burn_depth = 0; /* No stack usage. */
+      _gcry_aes_aesni_cfb_enc (ctx, outbuf, inbuf, iv, nblocks);
+      burn_depth = 0;
     }
 #endif /*USE_AESNI*/
+#ifdef USE_SSSE3
+  else if (ctx->use_ssse3)
+    {
+      _gcry_aes_ssse3_cfb_enc (ctx, outbuf, inbuf, iv, nblocks);
+      burn_depth = 0;
+    }
+#endif /*USE_SSSE3*/
   else
     {
+      rijndael_cryptfn_t encrypt_fn = ctx->encrypt_fn;
+
       for ( ;nblocks; nblocks-- )
         {
           /* Encrypt the IV. */
-          do_encrypt_aligned (ctx, iv, iv);
+          burn_depth = encrypt_fn (ctx, iv, iv);
           /* XOR the input with the IV and store input into IV.  */
           buf_xor_2dst(outbuf, iv, inbuf, BLOCKSIZE);
           outbuf += BLOCKSIZE;
@@ -1729,7 +760,7 @@ _gcry_aes_cfb_enc (void *context, unsigned char *iv,
     }
 
   if (burn_depth)
-    _gcry_burn_stack (burn_depth);
+    _gcry_burn_stack (burn_depth + 4 * sizeof(void *));
 }
 
 
@@ -1746,87 +777,51 @@ _gcry_aes_cbc_enc (void *context, unsigned char *iv,
   unsigned char *outbuf = outbuf_arg;
   const unsigned char *inbuf = inbuf_arg;
   unsigned char *last_iv;
-  unsigned int burn_depth = 48 + 2*sizeof(int);
-#ifdef USE_AESNI
-  int use_aesni = ctx->use_aesni;
-#endif
+  unsigned int burn_depth = 0;
 
+  if (ctx->prefetch_enc_fn)
+    ctx->prefetch_enc_fn();
+
+  if (0)
+    ;
 #ifdef USE_AESNI
-  if (use_aesni)
-    aesni_prepare ();
+  else if (ctx->use_aesni)
+    {
+      _gcry_aes_aesni_cbc_enc (ctx, outbuf, inbuf, iv, nblocks, cbc_mac);
+      burn_depth = 0;
+    }
 #endif /*USE_AESNI*/
+#ifdef USE_SSSE3
+  else if (ctx->use_ssse3)
+    {
+      _gcry_aes_ssse3_cbc_enc (ctx, outbuf, inbuf, iv, nblocks, cbc_mac);
+      burn_depth = 0;
+    }
+#endif /*USE_SSSE3*/
+  else
+    {
+      rijndael_cryptfn_t encrypt_fn = ctx->encrypt_fn;
 
-  last_iv = iv;
+      last_iv = iv;
 
-  for ( ;nblocks; nblocks-- )
-    {
-      if (0)
-        ;
-#ifdef USE_AESNI
-      else if (use_aesni)
-        {
-          /* ~35% speed up on Sandy-Bridge when doing xoring and copying with
-             SSE registers.  */
-          asm volatile ("movdqu %[iv], %%xmm0\n\t"
-                        "movdqu %[inbuf], %%xmm1\n\t"
-                        "pxor %%xmm0, %%xmm1\n\t"
-                        "movdqu %%xmm1, %[outbuf]\n\t"
-                        : /* No output */
-                        : [iv] "m" (*last_iv),
-                          [inbuf] "m" (*inbuf),
-                          [outbuf] "m" (*outbuf)
-                        : "memory" );
-
-          do_aesni_enc (ctx, outbuf, outbuf);
-        }
-#endif /*USE_AESNI*/
-      else
+      for ( ;nblocks; nblocks-- )
         {
           buf_xor(outbuf, inbuf, last_iv, BLOCKSIZE);
 
-          if (0)
-            ;
-#ifdef USE_PADLOCK
-          else if (ctx->use_padlock)
-            do_padlock (ctx, 0, outbuf, outbuf);
-#endif /*USE_PADLOCK*/
-          else
-            do_encrypt (ctx, outbuf, outbuf );
-        }
+          burn_depth = encrypt_fn (ctx, outbuf, outbuf);
 
-      last_iv = outbuf;
-      inbuf += BLOCKSIZE;
-      if (!cbc_mac)
-        outbuf += BLOCKSIZE;
-    }
+          last_iv = outbuf;
+          inbuf += BLOCKSIZE;
+          if (!cbc_mac)
+            outbuf += BLOCKSIZE;
+        }
 
-  if (last_iv != iv)
-    {
-      if (0)
-        ;
-#ifdef USE_AESNI
-      else if (use_aesni)
-        asm volatile ("movdqu %[last], %%xmm0\n\t"
-                      "movdqu %%xmm0, %[iv]\n\t"
-                      : /* No output */
-                      : [last] "m" (*last_iv),
-                        [iv] "m" (*iv)
-                      : "memory" );
-#endif /*USE_AESNI*/
-      else
+      if (last_iv != iv)
         buf_cpy (iv, last_iv, BLOCKSIZE);
     }
 
-#ifdef USE_AESNI
-   if (use_aesni)
-     {
-       aesni_cleanup ();
-       burn_depth = 0; /* No stack usage. */
-     }
-#endif /*USE_AESNI*/
-
   if (burn_depth)
-    _gcry_burn_stack (burn_depth);
+    _gcry_burn_stack (burn_depth + 4 * sizeof(void *));
 }
 
 
@@ -1843,52 +838,37 @@ _gcry_aes_ctr_enc (void *context, unsigned char *ctr,
   RIJNDAEL_context *ctx = context;
   unsigned char *outbuf = outbuf_arg;
   const unsigned char *inbuf = inbuf_arg;
-  unsigned int burn_depth = 48 + 2*sizeof(int);
+  unsigned int burn_depth = 0;
   int i;
 
+  if (ctx->prefetch_enc_fn)
+    ctx->prefetch_enc_fn();
+
   if (0)
     ;
 #ifdef USE_AESNI
   else if (ctx->use_aesni)
     {
-      static const unsigned char be_mask[16] __attribute__ ((aligned (16))) =
-        { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
-
-      aesni_prepare ();
-
-      asm volatile ("movdqa %[mask], %%xmm6\n\t" /* Preload mask */
-                    "movdqa %[ctr], %%xmm5\n\t"  /* Preload CTR */
-                    : /* No output */
-                    : [mask] "m" (*be_mask),
-                      [ctr] "m" (*ctr)
-                    : "memory");
-
-      for ( ;nblocks > 3 ; nblocks -= 4 )
-        {
-          do_aesni_ctr_4 (ctx, ctr, outbuf, inbuf);
-          outbuf += 4*BLOCKSIZE;
-          inbuf  += 4*BLOCKSIZE;
-        }
-      for ( ;nblocks; nblocks-- )
-        {
-          do_aesni_ctr (ctx, ctr, outbuf, inbuf);
-          outbuf += BLOCKSIZE;
-          inbuf  += BLOCKSIZE;
-        }
-      aesni_cleanup ();
-      aesni_cleanup_2_6 ();
-
-      burn_depth = 0; /* No stack usage. */
+      _gcry_aes_aesni_ctr_enc (ctx, outbuf, inbuf, ctr, nblocks);
+      burn_depth = 0;
     }
 #endif /*USE_AESNI*/
+#ifdef USE_SSSE3
+  else if (ctx->use_ssse3)
+    {
+      _gcry_aes_ssse3_ctr_enc (ctx, outbuf, inbuf, ctr, nblocks);
+      burn_depth = 0;
+    }
+#endif /*USE_SSSE3*/
   else
     {
-      union { unsigned char x1[16]; u32 x32[4]; } tmp;
+      union { unsigned char x1[16] ATTR_ALIGNED_16; u32 x32[4]; } tmp;
+      rijndael_cryptfn_t encrypt_fn = ctx->encrypt_fn;
 
       for ( ;nblocks; nblocks-- )
         {
           /* Encrypt the counter. */
-          do_encrypt_aligned (ctx, tmp.x1, ctr);
+          burn_depth = encrypt_fn (ctx, tmp.x1, ctr);
           /* XOR the input with the encrypted counter and store in output.  */
           buf_xor(outbuf, tmp.x1, inbuf, BLOCKSIZE);
           outbuf += BLOCKSIZE;
@@ -1901,154 +881,191 @@ _gcry_aes_ctr_enc (void *context, unsigned char *ctr,
                 break;
             }
         }
+
+      wipememory(&tmp, sizeof(tmp));
     }
 
   if (burn_depth)
-    _gcry_burn_stack (burn_depth);
+    _gcry_burn_stack (burn_depth + 4 * sizeof(void *));
 }
 
 
 \f
-/* Decrypt one block.  A and B need to be aligned on a 4 byte boundary
-   and the decryption must have been prepared.  A and B may be the
-   same. */
-static void
-do_decrypt_aligned (RIJNDAEL_context *ctx,
-                    unsigned char *b, const unsigned char *a)
+#if !defined(USE_ARM_ASM) && !defined(USE_AMD64_ASM)
+/* Decrypt one block.  A and B may be the same. */
+static unsigned int
+do_decrypt_fn (const RIJNDAEL_context *ctx, unsigned char *b,
+               const unsigned char *a)
 {
-#ifdef USE_AMD64_ASM
-  _gcry_aes_amd64_decrypt_block(ctx->keyschdec, b, a, ctx->rounds);
-#elif defined(USE_ARM_ASM)
-  _gcry_aes_arm_decrypt_block(ctx->keyschdec, b, a, ctx->rounds);
-#else
-#define rk  (ctx->keyschdec)
+#define rk (ctx->keyschdec32)
   int rounds = ctx->rounds;
   int r;
-  union
-  {
-    u32  tempu32[4];  /* Force correct alignment. */
-    byte temp[4][4];
-  } u;
-
-
-  *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(a   )) ^ *((u32_a_t*)rk[rounds][0]);
-  *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(a+ 4)) ^ *((u32_a_t*)rk[rounds][1]);
-  *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(a+ 8)) ^ *((u32_a_t*)rk[rounds][2]);
-  *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(a+12)) ^ *((u32_a_t*)rk[rounds][3]);
-
-  *((u32_a_t*)(b   ))    = (*((u32_a_t*)T5[u.temp[0][0]])
-                        ^ *((u32_a_t*)T6[u.temp[3][1]])
-                        ^ *((u32_a_t*)T7[u.temp[2][2]])
-                        ^ *((u32_a_t*)T8[u.temp[1][3]]));
-  *((u32_a_t*)(b+ 4))    = (*((u32_a_t*)T5[u.temp[1][0]])
-                        ^ *((u32_a_t*)T6[u.temp[0][1]])
-                        ^ *((u32_a_t*)T7[u.temp[3][2]])
-                        ^ *((u32_a_t*)T8[u.temp[2][3]]));
-  *((u32_a_t*)(b+ 8))    = (*((u32_a_t*)T5[u.temp[2][0]])
-                        ^ *((u32_a_t*)T6[u.temp[1][1]])
-                        ^ *((u32_a_t*)T7[u.temp[0][2]])
-                        ^ *((u32_a_t*)T8[u.temp[3][3]]));
-  *((u32_a_t*)(b+12))    = (*((u32_a_t*)T5[u.temp[3][0]])
-                        ^ *((u32_a_t*)T6[u.temp[2][1]])
-                        ^ *((u32_a_t*)T7[u.temp[1][2]])
-                        ^ *((u32_a_t*)T8[u.temp[0][3]]));
-
-  for (r = rounds-1; r > 1; r--)
+  u32 sa[4];
+  u32 sb[4];
+
+  sb[0] = buf_get_le32(a + 0);
+  sb[1] = buf_get_le32(a + 4);
+  sb[2] = buf_get_le32(a + 8);
+  sb[3] = buf_get_le32(a + 12);
+
+  sa[0] = sb[0] ^ rk[rounds][0];
+  sa[1] = sb[1] ^ rk[rounds][1];
+  sa[2] = sb[2] ^ rk[rounds][2];
+  sa[3] = sb[3] ^ rk[rounds][3];
+
+  for (r = rounds - 1; r > 1; r--)
     {
-      *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(b   )) ^ *((u32_a_t*)rk[r][0]);
-      *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[r][1]);
-      *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[r][2]);
-      *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)rk[r][3]);
-      *((u32_a_t*)(b   ))    = (*((u32_a_t*)T5[u.temp[0][0]])
-                            ^ *((u32_a_t*)T6[u.temp[3][1]])
-                            ^ *((u32_a_t*)T7[u.temp[2][2]])
-                            ^ *((u32_a_t*)T8[u.temp[1][3]]));
-      *((u32_a_t*)(b+ 4))    = (*((u32_a_t*)T5[u.temp[1][0]])
-                            ^ *((u32_a_t*)T6[u.temp[0][1]])
-                            ^ *((u32_a_t*)T7[u.temp[3][2]])
-                            ^ *((u32_a_t*)T8[u.temp[2][3]]));
-      *((u32_a_t*)(b+ 8))    = (*((u32_a_t*)T5[u.temp[2][0]])
-                            ^ *((u32_a_t*)T6[u.temp[1][1]])
-                            ^ *((u32_a_t*)T7[u.temp[0][2]])
-                            ^ *((u32_a_t*)T8[u.temp[3][3]]));
-      *((u32_a_t*)(b+12))    = (*((u32_a_t*)T5[u.temp[3][0]])
-                            ^ *((u32_a_t*)T6[u.temp[2][1]])
-                            ^ *((u32_a_t*)T7[u.temp[1][2]])
-                            ^ *((u32_a_t*)T8[u.temp[0][3]]));
+      sb[0] = rol(decT[(byte)(sa[0] >> (0 * 8))], (0 * 8));
+      sb[1] = rol(decT[(byte)(sa[0] >> (1 * 8))], (1 * 8));
+      sb[2] = rol(decT[(byte)(sa[0] >> (2 * 8))], (2 * 8));
+      sb[3] = rol(decT[(byte)(sa[0] >> (3 * 8))], (3 * 8));
+      sa[0] = rk[r][0] ^ sb[0];
+
+      sb[1] ^= rol(decT[(byte)(sa[1] >> (0 * 8))], (0 * 8));
+      sb[2] ^= rol(decT[(byte)(sa[1] >> (1 * 8))], (1 * 8));
+      sb[3] ^= rol(decT[(byte)(sa[1] >> (2 * 8))], (2 * 8));
+      sa[0] ^= rol(decT[(byte)(sa[1] >> (3 * 8))], (3 * 8));
+      sa[1] = rk[r][1] ^ sb[1];
+
+      sb[2] ^= rol(decT[(byte)(sa[2] >> (0 * 8))], (0 * 8));
+      sb[3] ^= rol(decT[(byte)(sa[2] >> (1 * 8))], (1 * 8));
+      sa[0] ^= rol(decT[(byte)(sa[2] >> (2 * 8))], (2 * 8));
+      sa[1] ^= rol(decT[(byte)(sa[2] >> (3 * 8))], (3 * 8));
+      sa[2] = rk[r][2] ^ sb[2];
+
+      sb[3] ^= rol(decT[(byte)(sa[3] >> (0 * 8))], (0 * 8));
+      sa[0] ^= rol(decT[(byte)(sa[3] >> (1 * 8))], (1 * 8));
+      sa[1] ^= rol(decT[(byte)(sa[3] >> (2 * 8))], (2 * 8));
+      sa[2] ^= rol(decT[(byte)(sa[3] >> (3 * 8))], (3 * 8));
+      sa[3] = rk[r][3] ^ sb[3];
+
+      r--;
+
+      sb[0] = rol(decT[(byte)(sa[0] >> (0 * 8))], (0 * 8));
+      sb[1] = rol(decT[(byte)(sa[0] >> (1 * 8))], (1 * 8));
+      sb[2] = rol(decT[(byte)(sa[0] >> (2 * 8))], (2 * 8));
+      sb[3] = rol(decT[(byte)(sa[0] >> (3 * 8))], (3 * 8));
+      sa[0] = rk[r][0] ^ sb[0];
+
+      sb[1] ^= rol(decT[(byte)(sa[1] >> (0 * 8))], (0 * 8));
+      sb[2] ^= rol(decT[(byte)(sa[1] >> (1 * 8))], (1 * 8));
+      sb[3] ^= rol(decT[(byte)(sa[1] >> (2 * 8))], (2 * 8));
+      sa[0] ^= rol(decT[(byte)(sa[1] >> (3 * 8))], (3 * 8));
+      sa[1] = rk[r][1] ^ sb[1];
+
+      sb[2] ^= rol(decT[(byte)(sa[2] >> (0 * 8))], (0 * 8));
+      sb[3] ^= rol(decT[(byte)(sa[2] >> (1 * 8))], (1 * 8));
+      sa[0] ^= rol(decT[(byte)(sa[2] >> (2 * 8))], (2 * 8));
+      sa[1] ^= rol(decT[(byte)(sa[2] >> (3 * 8))], (3 * 8));
+      sa[2] = rk[r][2] ^ sb[2];
+
+      sb[3] ^= rol(decT[(byte)(sa[3] >> (0 * 8))], (0 * 8));
+      sa[0] ^= rol(decT[(byte)(sa[3] >> (1 * 8))], (1 * 8));
+      sa[1] ^= rol(decT[(byte)(sa[3] >> (2 * 8))], (2 * 8));
+      sa[2] ^= rol(decT[(byte)(sa[3] >> (3 * 8))], (3 * 8));
+      sa[3] = rk[r][3] ^ sb[3];
     }
 
+  sb[0] = rol(decT[(byte)(sa[0] >> (0 * 8))], (0 * 8));
+  sb[1] = rol(decT[(byte)(sa[0] >> (1 * 8))], (1 * 8));
+  sb[2] = rol(decT[(byte)(sa[0] >> (2 * 8))], (2 * 8));
+  sb[3] = rol(decT[(byte)(sa[0] >> (3 * 8))], (3 * 8));
+  sa[0] = rk[1][0] ^ sb[0];
+
+  sb[1] ^= rol(decT[(byte)(sa[1] >> (0 * 8))], (0 * 8));
+  sb[2] ^= rol(decT[(byte)(sa[1] >> (1 * 8))], (1 * 8));
+  sb[3] ^= rol(decT[(byte)(sa[1] >> (2 * 8))], (2 * 8));
+  sa[0] ^= rol(decT[(byte)(sa[1] >> (3 * 8))], (3 * 8));
+  sa[1] = rk[1][1] ^ sb[1];
+
+  sb[2] ^= rol(decT[(byte)(sa[2] >> (0 * 8))], (0 * 8));
+  sb[3] ^= rol(decT[(byte)(sa[2] >> (1 * 8))], (1 * 8));
+  sa[0] ^= rol(decT[(byte)(sa[2] >> (2 * 8))], (2 * 8));
+  sa[1] ^= rol(decT[(byte)(sa[2] >> (3 * 8))], (3 * 8));
+  sa[2] = rk[1][2] ^ sb[2];
+
+  sb[3] ^= rol(decT[(byte)(sa[3] >> (0 * 8))], (0 * 8));
+  sa[0] ^= rol(decT[(byte)(sa[3] >> (1 * 8))], (1 * 8));
+  sa[1] ^= rol(decT[(byte)(sa[3] >> (2 * 8))], (2 * 8));
+  sa[2] ^= rol(decT[(byte)(sa[3] >> (3 * 8))], (3 * 8));
+  sa[3] = rk[1][3] ^ sb[3];
+
   /* Last round is special. */
-  *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(b   )) ^ *((u32_a_t*)rk[1][0]);
-  *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[1][1]);
-  *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[1][2]);
-  *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)rk[1][3]);
-  b[ 0] = S5[u.temp[0][0]];
-  b[ 1] = S5[u.temp[3][1]];
-  b[ 2] = S5[u.temp[2][2]];
-  b[ 3] = S5[u.temp[1][3]];
-  b[ 4] = S5[u.temp[1][0]];
-  b[ 5] = S5[u.temp[0][1]];
-  b[ 6] = S5[u.temp[3][2]];
-  b[ 7] = S5[u.temp[2][3]];
-  b[ 8] = S5[u.temp[2][0]];
-  b[ 9] = S5[u.temp[1][1]];
-  b[10] = S5[u.temp[0][2]];
-  b[11] = S5[u.temp[3][3]];
-  b[12] = S5[u.temp[3][0]];
-  b[13] = S5[u.temp[2][1]];
-  b[14] = S5[u.temp[1][2]];
-  b[15] = S5[u.temp[0][3]];
-  *((u32_a_t*)(b   )) ^= *((u32_a_t*)rk[0][0]);
-  *((u32_a_t*)(b+ 4)) ^= *((u32_a_t*)rk[0][1]);
-  *((u32_a_t*)(b+ 8)) ^= *((u32_a_t*)rk[0][2]);
-  *((u32_a_t*)(b+12)) ^= *((u32_a_t*)rk[0][3]);
+  sb[0] = inv_sbox[(byte)(sa[0] >> (0 * 8))] << (0 * 8);
+  sb[1] = inv_sbox[(byte)(sa[0] >> (1 * 8))] << (1 * 8);
+  sb[2] = inv_sbox[(byte)(sa[0] >> (2 * 8))] << (2 * 8);
+  sb[3] = inv_sbox[(byte)(sa[0] >> (3 * 8))] << (3 * 8);
+  sa[0] = sb[0] ^ rk[0][0];
+
+  sb[1] ^= inv_sbox[(byte)(sa[1] >> (0 * 8))] << (0 * 8);
+  sb[2] ^= inv_sbox[(byte)(sa[1] >> (1 * 8))] << (1 * 8);
+  sb[3] ^= inv_sbox[(byte)(sa[1] >> (2 * 8))] << (2 * 8);
+  sa[0] ^= inv_sbox[(byte)(sa[1] >> (3 * 8))] << (3 * 8);
+  sa[1] = sb[1] ^ rk[0][1];
+
+  sb[2] ^= inv_sbox[(byte)(sa[2] >> (0 * 8))] << (0 * 8);
+  sb[3] ^= inv_sbox[(byte)(sa[2] >> (1 * 8))] << (1 * 8);
+  sa[0] ^= inv_sbox[(byte)(sa[2] >> (2 * 8))] << (2 * 8);
+  sa[1] ^= inv_sbox[(byte)(sa[2] >> (3 * 8))] << (3 * 8);
+  sa[2] = sb[2] ^ rk[0][2];
+
+  sb[3] ^= inv_sbox[(byte)(sa[3] >> (0 * 8))] << (0 * 8);
+  sa[0] ^= inv_sbox[(byte)(sa[3] >> (1 * 8))] << (1 * 8);
+  sa[1] ^= inv_sbox[(byte)(sa[3] >> (2 * 8))] << (2 * 8);
+  sa[2] ^= inv_sbox[(byte)(sa[3] >> (3 * 8))] << (3 * 8);
+  sa[3] = sb[3] ^ rk[0][3];
+
+  buf_put_le32(b + 0, sa[0]);
+  buf_put_le32(b + 4, sa[1]);
+  buf_put_le32(b + 8, sa[2]);
+  buf_put_le32(b + 12, sa[3]);
 #undef rk
-#endif /*!USE_AMD64_ASM && !USE_ARM_ASM*/
+
+  return (56+2*sizeof(int));
 }
+#endif /*!USE_ARM_ASM && !USE_AMD64_ASM*/
 
 
 /* Decrypt one block.  AX and BX may be the same. */
-static void
-do_decrypt (RIJNDAEL_context *ctx, byte *bx, const byte *ax)
+static unsigned int
+do_decrypt (const RIJNDAEL_context *ctx, unsigned char *bx,
+            const unsigned char *ax)
 {
-#if !defined(USE_AMD64_ASM) && !defined(USE_ARM_ASM)
-  /* BX and AX are not necessary correctly aligned.  Thus we might
-     need to copy them here.  We try to align to a 16 bytes. */
-  if (((size_t)ax & 0x0f) || ((size_t)bx & 0x0f))
-    {
-      union
-      {
-        u32  dummy[4];
-        byte a[16] ATTR_ALIGNED_16;
-      } a;
-      union
-      {
-        u32  dummy[4];
-        byte b[16] ATTR_ALIGNED_16;
-      } b;
-
-      buf_cpy (a.a, ax, 16);
-      do_decrypt_aligned (ctx, b.b, a.a);
-      buf_cpy (bx, b.b, 16);
-    }
-  else
-#endif /*!USE_AMD64_ASM && !USE_ARM_ASM*/
-    {
-      do_decrypt_aligned (ctx, bx, ax);
-    }
+#ifdef USE_AMD64_ASM
+# ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+  return _gcry_aes_amd64_decrypt_block(ctx->keyschdec, bx, ax, ctx->rounds,
+                                      &dec_tables);
+# else
+  /* Call SystemV ABI function without storing non-volatile XMM registers,
+   * as target function does not use vector instruction sets. */
+  const void *key = ctx->keyschdec;
+  uintptr_t rounds = ctx->rounds;
+  uintptr_t ret;
+  asm volatile ("movq %[dectabs], %%r8\n\t"
+                "callq *%[ret]\n\t"
+                : [ret] "=a" (ret),
+                  "+D" (key),
+                  "+S" (bx),
+                  "+d" (ax),
+                  "+c" (rounds)
+                : "0" (_gcry_aes_amd64_decrypt_block),
+                  [dectabs] "g" (&dec_tables)
+                : "cc", "memory", "r8", "r9", "r10", "r11");
+  return ret;
+# endif /* HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS */
+#elif defined(USE_ARM_ASM)
+  return _gcry_aes_arm_decrypt_block(ctx->keyschdec, bx, ax, ctx->rounds,
+                                    &dec_tables);
+#else
+  return do_decrypt_fn (ctx, bx, ax);
+#endif /*!USE_ARM_ASM && !USE_AMD64_ASM*/
 }
 
 
 static inline void
 check_decryption_preparation (RIJNDAEL_context *ctx)
 {
-  if (0)
-    ;
-#ifdef USE_PADLOCK
-  else if (ctx->use_padlock)
-    { /* Padlock does not need decryption subkeys. */ }
-#endif /*USE_PADLOCK*/
-  else if ( !ctx->decryption_prepared )
+  if ( !ctx->decryption_prepared )
     {
       prepare_decryption ( ctx );
       ctx->decryption_prepared = 1;
@@ -2060,35 +1077,13 @@ static unsigned int
 rijndael_decrypt (void *context, byte *b, const byte *a)
 {
   RIJNDAEL_context *ctx = context;
-  unsigned int burn_stack;
 
   check_decryption_preparation (ctx);
 
-  if (0)
-    ;
-#ifdef USE_PADLOCK
-  else if (ctx->use_padlock)
-    {
-      do_padlock (ctx, 1, b, a);
-      burn_stack = (48 + 2*sizeof(int) /* FIXME */);
-    }
-#endif /*USE_PADLOCK*/
-#ifdef USE_AESNI
-  else if (ctx->use_aesni)
-    {
-      aesni_prepare ();
-      do_aesni_dec (ctx, b, a);
-      aesni_cleanup ();
-      burn_stack = 0;
-    }
-#endif /*USE_AESNI*/
-  else
-    {
-      do_decrypt (ctx, b, a);
-      burn_stack = (56+2*sizeof(int));
-    }
+  if (ctx->prefetch_dec_fn)
+    ctx->prefetch_dec_fn();
 
-  return burn_stack;
+  return ctx->decrypt_fn (ctx, b, a);
 }
 
 
@@ -2104,88 +1099,34 @@ _gcry_aes_cfb_dec (void *context, unsigned char *iv,
   RIJNDAEL_context *ctx = context;
   unsigned char *outbuf = outbuf_arg;
   const unsigned char *inbuf = inbuf_arg;
-  unsigned int burn_depth = 48 + 2*sizeof(int);
+  unsigned int burn_depth = 0;
+
+  if (ctx->prefetch_enc_fn)
+    ctx->prefetch_enc_fn();
 
   if (0)
     ;
-#ifdef USE_PADLOCK
-  else if (ctx->use_padlock)
-    {
-      /* Fixme:  Let Padlock do the CFBing.  */
-      for ( ;nblocks; nblocks-- )
-        {
-          do_padlock (ctx, 0, iv, iv);
-          buf_xor_n_copy(outbuf, iv, inbuf, BLOCKSIZE);
-          outbuf += BLOCKSIZE;
-          inbuf  += BLOCKSIZE;
-        }
-    }
-#endif /*USE_PADLOCK*/
 #ifdef USE_AESNI
   else if (ctx->use_aesni)
     {
-      aesni_prepare ();
-
-      /* CFB decryption can be parallelized */
-      for ( ;nblocks >= 4; nblocks -= 4)
-        {
-          asm volatile
-            ("movdqu (%[iv]),        %%xmm1\n\t" /* load input blocks */
-             "movdqu 0*16(%[inbuf]), %%xmm2\n\t"
-             "movdqu 1*16(%[inbuf]), %%xmm3\n\t"
-             "movdqu 2*16(%[inbuf]), %%xmm4\n\t"
-
-             "movdqu 3*16(%[inbuf]), %%xmm0\n\t" /* update IV */
-             "movdqu %%xmm0,         (%[iv])\n\t"
-             : /* No output */
-             : [inbuf] "r" (inbuf), [iv] "r" (iv)
-             : "memory");
-
-          do_aesni_enc_vec4 (ctx);
-
-          asm volatile
-            ("movdqu 0*16(%[inbuf]), %%xmm5\n\t"
-             "pxor %%xmm5, %%xmm1\n\t"
-             "movdqu %%xmm1, 0*16(%[outbuf])\n\t"
-
-             "movdqu 1*16(%[inbuf]), %%xmm5\n\t"
-             "pxor %%xmm5, %%xmm2\n\t"
-             "movdqu %%xmm2, 1*16(%[outbuf])\n\t"
-
-             "movdqu 2*16(%[inbuf]), %%xmm5\n\t"
-             "pxor %%xmm5, %%xmm3\n\t"
-             "movdqu %%xmm3, 2*16(%[outbuf])\n\t"
-
-             "movdqu 3*16(%[inbuf]), %%xmm5\n\t"
-             "pxor %%xmm5, %%xmm4\n\t"
-             "movdqu %%xmm4, 3*16(%[outbuf])\n\t"
-
-             : /* No output */
-             : [inbuf] "r" (inbuf),
-               [outbuf] "r" (outbuf)
-             : "memory");
-
-          outbuf += 4*BLOCKSIZE;
-          inbuf  += 4*BLOCKSIZE;
-        }
-
-      for ( ;nblocks; nblocks-- )
-        {
-          do_aesni_cfb (ctx, 1, iv, outbuf, inbuf);
-          outbuf += BLOCKSIZE;
-          inbuf  += BLOCKSIZE;
-        }
-      aesni_cleanup ();
-      aesni_cleanup_2_6 ();
-
-      burn_depth = 0; /* No stack usage. */
+      _gcry_aes_aesni_cfb_dec (ctx, outbuf, inbuf, iv, nblocks);
+      burn_depth = 0;
     }
 #endif /*USE_AESNI*/
+#ifdef USE_SSSE3
+  else if (ctx->use_ssse3)
+    {
+      _gcry_aes_ssse3_cfb_dec (ctx, outbuf, inbuf, iv, nblocks);
+      burn_depth = 0;
+    }
+#endif /*USE_SSSE3*/
   else
     {
+      rijndael_cryptfn_t encrypt_fn = ctx->encrypt_fn;
+
       for ( ;nblocks; nblocks-- )
         {
-          do_encrypt_aligned (ctx, iv, iv);
+          burn_depth = encrypt_fn (ctx, iv, iv);
           buf_xor_n_copy(outbuf, iv, inbuf, BLOCKSIZE);
           outbuf += BLOCKSIZE;
           inbuf  += BLOCKSIZE;
@@ -2193,7 +1134,7 @@ _gcry_aes_cfb_dec (void *context, unsigned char *iv,
     }
 
   if (burn_depth)
-    _gcry_burn_stack (burn_depth);
+    _gcry_burn_stack (burn_depth + 4 * sizeof(void *));
 }
 
 
@@ -2209,128 +1150,207 @@ _gcry_aes_cbc_dec (void *context, unsigned char *iv,
   RIJNDAEL_context *ctx = context;
   unsigned char *outbuf = outbuf_arg;
   const unsigned char *inbuf = inbuf_arg;
-  unsigned int burn_depth = 48 + 2*sizeof(int) + 4*sizeof (char*);
+  unsigned int burn_depth = 0;
 
   check_decryption_preparation (ctx);
 
+  if (ctx->prefetch_dec_fn)
+    ctx->prefetch_dec_fn();
+
   if (0)
     ;
 #ifdef USE_AESNI
   else if (ctx->use_aesni)
     {
-      aesni_prepare ();
+      _gcry_aes_aesni_cbc_dec (ctx, outbuf, inbuf, iv, nblocks);
+      burn_depth = 0;
+    }
+#endif /*USE_AESNI*/
+#ifdef USE_SSSE3
+  else if (ctx->use_ssse3)
+    {
+      _gcry_aes_ssse3_cbc_dec (ctx, outbuf, inbuf, iv, nblocks);
+      burn_depth = 0;
+    }
+#endif /*USE_SSSE3*/
+  else
+    {
+      unsigned char savebuf[BLOCKSIZE] ATTR_ALIGNED_16;
+      rijndael_cryptfn_t decrypt_fn = ctx->decrypt_fn;
+
+      for ( ;nblocks; nblocks-- )
+        {
+          /* INBUF is needed later and it may be identical to OUTBUF, so store
+             the intermediate result to SAVEBUF.  */
+
+          burn_depth = decrypt_fn (ctx, savebuf, inbuf);
+
+          buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, BLOCKSIZE);
+          inbuf += BLOCKSIZE;
+          outbuf += BLOCKSIZE;
+        }
+
+      wipememory(savebuf, sizeof(savebuf));
+    }
+
+  if (burn_depth)
+    _gcry_burn_stack (burn_depth + 4 * sizeof(void *));
+}
+
+
+\f
+/* Bulk encryption/decryption of complete blocks in OCB mode. */
+size_t
+_gcry_aes_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
+                     const void *inbuf_arg, size_t nblocks, int encrypt)
+{
+  RIJNDAEL_context *ctx = (void *)&c->context.c;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  unsigned int burn_depth = 0;
+
+  if (encrypt)
+    {
+      if (ctx->prefetch_enc_fn)
+        ctx->prefetch_enc_fn();
+    }
+  else
+    {
+      check_decryption_preparation (ctx);
 
-      asm volatile
-        ("movdqu %[iv], %%xmm5\n\t"    /* use xmm5 as fast IV storage */
-         : /* No output */
-         : [iv] "m" (*iv)
-         : "memory");
+      if (ctx->prefetch_dec_fn)
+        ctx->prefetch_dec_fn();
+    }
 
-      for ( ;nblocks > 3 ; nblocks -= 4 )
+  if (0)
+    ;
+#ifdef USE_AESNI
+  else if (ctx->use_aesni)
+    {
+      _gcry_aes_aesni_ocb_crypt (c, outbuf, inbuf, nblocks, encrypt);
+      burn_depth = 0;
+    }
+#endif /*USE_AESNI*/
+#ifdef USE_SSSE3
+  else if (ctx->use_ssse3)
+    {
+      _gcry_aes_ssse3_ocb_crypt (c, outbuf, inbuf, nblocks, encrypt);
+      burn_depth = 0;
+    }
+#endif /*USE_SSSE3*/
+  else if (encrypt)
+    {
+      union { unsigned char x1[16] ATTR_ALIGNED_16; u32 x32[4]; } l_tmp;
+      rijndael_cryptfn_t encrypt_fn = ctx->encrypt_fn;
+
+      for ( ;nblocks; nblocks-- )
         {
-          asm volatile
-            ("movdqu 0*16(%[inbuf]), %%xmm1\n\t"       /* load input blocks */
-             "movdqu 1*16(%[inbuf]), %%xmm2\n\t"
-             "movdqu 2*16(%[inbuf]), %%xmm3\n\t"
-             "movdqu 3*16(%[inbuf]), %%xmm4\n\t"
-             : /* No output */
-             : [inbuf] "r" (inbuf)
-             : "memory");
-
-          do_aesni_dec_vec4 (ctx);
-
-          asm volatile
-            ("pxor %%xmm5, %%xmm1\n\t"                 /* xor IV with output */
-             "movdqu 0*16(%[inbuf]), %%xmm5\n\t"       /* load new IV */
-             "movdqu %%xmm1, 0*16(%[outbuf])\n\t"
-
-             "pxor %%xmm5, %%xmm2\n\t"                 /* xor IV with output */
-             "movdqu 1*16(%[inbuf]), %%xmm5\n\t"       /* load new IV */
-             "movdqu %%xmm2, 1*16(%[outbuf])\n\t"
-
-             "pxor %%xmm5, %%xmm3\n\t"                 /* xor IV with output */
-             "movdqu 2*16(%[inbuf]), %%xmm5\n\t"       /* load new IV */
-             "movdqu %%xmm3, 2*16(%[outbuf])\n\t"
-
-             "pxor %%xmm5, %%xmm4\n\t"                 /* xor IV with output */
-             "movdqu 3*16(%[inbuf]), %%xmm5\n\t"       /* load new IV */
-             "movdqu %%xmm4, 3*16(%[outbuf])\n\t"
-
-             : /* No output */
-             : [inbuf] "r" (inbuf),
-               [outbuf] "r" (outbuf)
-             : "memory");
-
-          outbuf += 4*BLOCKSIZE;
-          inbuf  += 4*BLOCKSIZE;
+          u64 i = ++c->u_mode.ocb.data_nblocks;
+          const unsigned char *l = ocb_get_l(c, l_tmp.x1, i);
+
+          /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+          buf_xor_1 (c->u_iv.iv, l, BLOCKSIZE);
+          buf_cpy (l_tmp.x1, inbuf, BLOCKSIZE);
+          /* Checksum_i = Checksum_{i-1} xor P_i  */
+          buf_xor_1 (c->u_ctr.ctr, l_tmp.x1, BLOCKSIZE);
+          /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)  */
+          buf_xor_1 (l_tmp.x1, c->u_iv.iv, BLOCKSIZE);
+          burn_depth = encrypt_fn (ctx, l_tmp.x1, l_tmp.x1);
+          buf_xor_1 (l_tmp.x1, c->u_iv.iv, BLOCKSIZE);
+          buf_cpy (outbuf, l_tmp.x1, BLOCKSIZE);
+
+          inbuf += BLOCKSIZE;
+          outbuf += BLOCKSIZE;
         }
+    }
+  else
+    {
+      union { unsigned char x1[16] ATTR_ALIGNED_16; u32 x32[4]; } l_tmp;
+      rijndael_cryptfn_t decrypt_fn = ctx->decrypt_fn;
 
       for ( ;nblocks; nblocks-- )
         {
-          asm volatile
-            ("movdqu %[inbuf], %%xmm2\n\t"     /* use xmm2 as savebuf */
-             : /* No output */
-             : [inbuf] "m" (*inbuf)
-             : "memory");
-
-          /* uses only xmm0 and xmm1 */
-          do_aesni_dec (ctx, outbuf, inbuf);
-
-          asm volatile
-            ("movdqu %[outbuf], %%xmm0\n\t"
-             "pxor %%xmm5, %%xmm0\n\t"         /* xor IV with output */
-             "movdqu %%xmm0, %[outbuf]\n\t"
-             "movdqu %%xmm2, %%xmm5\n\t"       /* store savebuf as new IV */
-             : /* No output */
-             : [outbuf] "m" (*outbuf)
-             : "memory");
+          u64 i = ++c->u_mode.ocb.data_nblocks;
+          const unsigned char *l = ocb_get_l(c, l_tmp.x1, i);
+
+          /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+          buf_xor_1 (c->u_iv.iv, l, BLOCKSIZE);
+          buf_cpy (l_tmp.x1, inbuf, BLOCKSIZE);
+          /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)  */
+          buf_xor_1 (l_tmp.x1, c->u_iv.iv, BLOCKSIZE);
+          burn_depth = decrypt_fn (ctx, l_tmp.x1, l_tmp.x1);
+          buf_xor_1 (l_tmp.x1, c->u_iv.iv, BLOCKSIZE);
+          /* Checksum_i = Checksum_{i-1} xor P_i  */
+          buf_xor_1 (c->u_ctr.ctr, l_tmp.x1, BLOCKSIZE);
+          buf_cpy (outbuf, l_tmp.x1, BLOCKSIZE);
 
+          inbuf += BLOCKSIZE;
           outbuf += BLOCKSIZE;
-          inbuf  += BLOCKSIZE;
         }
+    }
 
-      asm volatile
-        ("movdqu %%xmm5, %[iv]\n\t"    /* store IV */
-         : /* No output */
-         : [iv] "m" (*iv)
-         : "memory");
+  if (burn_depth)
+    _gcry_burn_stack (burn_depth + 4 * sizeof(void *));
+
+  return 0;
+}
 
-      aesni_cleanup ();
-      aesni_cleanup_2_6 ();
 
-      burn_depth = 0; /* No stack usage. */
+/* Bulk authentication of complete blocks in OCB mode. */
+size_t
+_gcry_aes_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks)
+{
+  RIJNDAEL_context *ctx = (void *)&c->context.c;
+  const unsigned char *abuf = abuf_arg;
+  unsigned int burn_depth = 0;
+
+  if (ctx->prefetch_enc_fn)
+    ctx->prefetch_enc_fn();
+
+  if (0)
+    ;
+#ifdef USE_AESNI
+  else if (ctx->use_aesni)
+    {
+      _gcry_aes_aesni_ocb_auth (c, abuf, nblocks);
+      burn_depth = 0;
     }
 #endif /*USE_AESNI*/
+#ifdef USE_SSSE3
+  else if (ctx->use_ssse3)
+    {
+      _gcry_aes_ssse3_ocb_auth (c, abuf, nblocks);
+      burn_depth = 0;
+    }
+#endif /*USE_SSSE3*/
   else
     {
-      unsigned char savebuf[BLOCKSIZE];
+      union { unsigned char x1[16] ATTR_ALIGNED_16; u32 x32[4]; } l_tmp;
+      rijndael_cryptfn_t encrypt_fn = ctx->encrypt_fn;
 
       for ( ;nblocks; nblocks-- )
         {
-          /* INBUF is needed later and it may be identical to OUTBUF, so store
-             the intermediate result to SAVEBUF.  */
+          u64 i = ++c->u_mode.ocb.aad_nblocks;
+          const unsigned char *l = ocb_get_l(c, l_tmp.x1, i);
 
-          if (0)
-            ;
-#ifdef USE_PADLOCK
-          else if (ctx->use_padlock)
-            do_padlock (ctx, 1, savebuf, inbuf);
-#endif /*USE_PADLOCK*/
-          else
-            do_decrypt (ctx, savebuf, inbuf);
+          /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+          buf_xor_1 (c->u_mode.ocb.aad_offset, l, BLOCKSIZE);
+          /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i)  */
+          buf_xor (l_tmp.x1, c->u_mode.ocb.aad_offset, abuf, BLOCKSIZE);
+          burn_depth = encrypt_fn (ctx, l_tmp.x1, l_tmp.x1);
+          buf_xor_1 (c->u_mode.ocb.aad_sum, l_tmp.x1, BLOCKSIZE);
 
-          buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, BLOCKSIZE);
-          inbuf += BLOCKSIZE;
-          outbuf += BLOCKSIZE;
+          abuf += BLOCKSIZE;
         }
 
-      wipememory(savebuf, sizeof(savebuf));
+      wipememory(&l_tmp, sizeof(l_tmp));
     }
 
   if (burn_depth)
-    _gcry_burn_stack (burn_depth);
-}
+    _gcry_burn_stack (burn_depth + 4 * sizeof(void *));
 
+  return 0;
+}
 
 
 \f
@@ -2338,7 +1358,8 @@ _gcry_aes_cbc_dec (void *context, unsigned char *iv,
 static const char*
 selftest_basic_128 (void)
 {
-  RIJNDAEL_context ctx;
+  RIJNDAEL_context *ctx;
+  unsigned char *ctxmem;
   unsigned char scratch[16];
 
   /* The test vectors are from the AES supplied ones; more or less
@@ -2381,11 +1402,21 @@ selftest_basic_128 (void)
     };
 #endif
 
-  rijndael_setkey (&ctx, key_128, sizeof (key_128));
-  rijndael_encrypt (&ctx, scratch, plaintext_128);
+  /* Because gcc/ld can only align the CTX struct on 8 bytes on the
+     stack, we need to allocate that context on the heap.  */
+  ctx = _gcry_cipher_selftest_alloc_ctx (sizeof *ctx, &ctxmem);
+  if (!ctx)
+    return "failed to allocate memory";
+
+  rijndael_setkey (ctx, key_128, sizeof (key_128));
+  rijndael_encrypt (ctx, scratch, plaintext_128);
   if (memcmp (scratch, ciphertext_128, sizeof (ciphertext_128)))
-     return "AES-128 test encryption failed.";
-  rijndael_decrypt (&ctx, scratch, scratch);
+    {
+      xfree (ctxmem);
+      return "AES-128 test encryption failed.";
+    }
+  rijndael_decrypt (ctx, scratch, scratch);
+  xfree (ctxmem);
   if (memcmp (scratch, plaintext_128, sizeof (plaintext_128)))
     return "AES-128 test decryption failed.";
 
@@ -2396,7 +1427,8 @@ selftest_basic_128 (void)
 static const char*
 selftest_basic_192 (void)
 {
-  RIJNDAEL_context ctx;
+  RIJNDAEL_context *ctx;
+  unsigned char *ctxmem;
   unsigned char scratch[16];
 
   static unsigned char plaintext_192[16] =
@@ -2416,11 +1448,18 @@ selftest_basic_192 (void)
       0x12,0x13,0x1A,0xC7,0xC5,0x47,0x88,0xAA
     };
 
-  rijndael_setkey (&ctx, key_192, sizeof(key_192));
-  rijndael_encrypt (&ctx, scratch, plaintext_192);
+  ctx = _gcry_cipher_selftest_alloc_ctx (sizeof *ctx, &ctxmem);
+  if (!ctx)
+    return "failed to allocate memory";
+  rijndael_setkey (ctx, key_192, sizeof(key_192));
+  rijndael_encrypt (ctx, scratch, plaintext_192);
   if (memcmp (scratch, ciphertext_192, sizeof (ciphertext_192)))
-    return "AES-192 test encryption failed.";
-  rijndael_decrypt (&ctx, scratch, scratch);
+    {
+      xfree (ctxmem);
+      return "AES-192 test encryption failed.";
+    }
+  rijndael_decrypt (ctx, scratch, scratch);
+  xfree (ctxmem);
   if (memcmp (scratch, plaintext_192, sizeof (plaintext_192)))
     return "AES-192 test decryption failed.";
 
@@ -2432,7 +1471,8 @@ selftest_basic_192 (void)
 static const char*
 selftest_basic_256 (void)
 {
-  RIJNDAEL_context ctx;
+  RIJNDAEL_context *ctx;
+  unsigned char *ctxmem;
   unsigned char scratch[16];
 
   static unsigned char plaintext_256[16] =
@@ -2453,11 +1493,18 @@ selftest_basic_256 (void)
       0x9A,0xCF,0x72,0x80,0x86,0x04,0x0A,0xE3
     };
 
-  rijndael_setkey (&ctx, key_256, sizeof(key_256));
-  rijndael_encrypt (&ctx, scratch, plaintext_256);
+  ctx = _gcry_cipher_selftest_alloc_ctx (sizeof *ctx, &ctxmem);
+  if (!ctx)
+    return "failed to allocate memory";
+  rijndael_setkey (ctx, key_256, sizeof(key_256));
+  rijndael_encrypt (ctx, scratch, plaintext_256);
   if (memcmp (scratch, ciphertext_256, sizeof (ciphertext_256)))
-    return "AES-256 test encryption failed.";
-  rijndael_decrypt (&ctx, scratch, scratch);
+    {
+      xfree (ctxmem);
+      return "AES-256 test encryption failed.";
+    }
+  rijndael_decrypt (ctx, scratch, scratch);
+  xfree (ctxmem);
   if (memcmp (scratch, plaintext_256, sizeof (plaintext_256)))
     return "AES-256 test decryption failed.";
 
index 08e8cb0..0a019b9 100644 (file)
@@ -24,7 +24,7 @@
 #include <string.h>
 
 #include "g10lib.h"
-#include "rmd.h"
+#include "hash-common.h"
 #include "cipher.h" /* Only used for the rmd160_hash_buffer() prototype. */
 
 #include "bithelp.h"
  * 1 million times "a"   52783243c1697bdbe16d37f97f68f08325dc1528
  */
 
+typedef struct
+{
+  gcry_md_block_ctx_t bctx;
+  u32  h0,h1,h2,h3,h4;
+} RMD160_CONTEXT;
+
+
 static unsigned int
-transform ( void *ctx, const unsigned char *data );
+transform ( void *ctx, const unsigned char *data, size_t nblks );
 
 static void
 rmd160_init (void *context, unsigned int flags)
@@ -164,22 +171,14 @@ rmd160_init (void *context, unsigned int flags)
 }
 
 
-void
-_gcry_rmd160_init (void *context)
-{
-  rmd160_init (context, 0);
-}
-
-
 /****************
  * Transform the message X which consists of 16 32-bit-words
  */
 static unsigned int
-transform ( void *ctx, const unsigned char *data )
+transform_blk ( 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,224 +200,208 @@ transform ( void *ctx, const unsigned char *data )
 #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;
-
-  return /*burn_stack*/ 108+5*sizeof(void*);
+  /* 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*/ 104+5*sizeof(void*);
 }
 
 
-/****************
- * Apply the rmd160 transform function on the buffer which must have
- * a length 64 bytes. Do not use this function together with the
- * other functions, use rmd160_init to initialize internal variables.
- * Returns: 16 bytes in buffer with the mixed contentes of buffer.
- */
-void
-_gcry_rmd160_mixblock ( RMD160_CONTEXT *hd, void *blockof64byte )
+static unsigned int
+transform ( void *c, const unsigned char *data, size_t nblks )
 {
-  char *p = blockof64byte;
+  unsigned int burn;
 
-  transform ( hd, blockof64byte );
-#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
-  X(0);
-  X(1);
-  X(2);
-  X(3);
-  X(4);
-#undef X
+  do
+    {
+      burn = transform_blk (c, data);
+      data += 64;
+    }
+  while (--nblks);
+
+  return burn;
 }
 
 
-/* The routine terminates the computation
+/*
+ * The routine terminates the computation
  */
-
 static void
 rmd160_final( void *context )
 {
@@ -465,11 +448,11 @@ rmd160_final( void *context )
   /* append the 64 bit count */
   buf_put_le32(hd->bctx.buf + 56, lsb);
   buf_put_le32(hd->bctx.buf + 60, msb);
-  burn = transform( hd, hd->bctx.buf );
+  burn = transform ( hd, hd->bctx.buf, 1 );
   _gcry_burn_stack (burn);
 
   p = hd->bctx.buf;
-#define X(a) do { *(u32*)p = le_bswap32(hd->h##a) ; p += 4; } while(0)
+#define X(a) do { buf_put_le32(p, hd->h##a); p += 4; } while(0)
   X(0);
   X(1);
   X(2);
@@ -497,7 +480,7 @@ _gcry_rmd160_hash_buffer (void *outbuf, const void *buffer, size_t length )
 {
   RMD160_CONTEXT hd;
 
-  _gcry_rmd160_init ( &hd );
+  rmd160_init (&hd, 0);
   _gcry_md_block_write ( &hd, buffer, length );
   rmd160_final ( &hd );
   memcpy ( outbuf, hd.bctx.buf, 20 );
@@ -520,6 +503,6 @@ gcry_md_spec_t _gcry_digest_spec_rmd160 =
   {
     GCRY_MD_RMD160, {0, 0},
     "RIPEMD160", asn, DIM (asn), oid_spec_rmd160, 20,
-    rmd160_init, _gcry_md_block_write, rmd160_final, rmd160_read,
+    rmd160_init, _gcry_md_block_write, rmd160_final, rmd160_read, NULL,
     sizeof (RMD160_CONTEXT)
   };
index 4f5a659..7b56237 100644 (file)
@@ -46,7 +46,7 @@ octet_string_from_mpi (unsigned char **r_frame, void *space,
 
 
 /* Encode {VALUE,VALUELEN} for an NBITS keys using the pkcs#1 block
-   type 2 padding.  On sucess the result is stored as a new MPI at
+   type 2 padding.  On success the result is stored as a new MPI at
    R_RESULT.  On error the value at R_RESULT is undefined.
 
    If {RANDOM_OVERRIDE, RANDOM_OVERRIDE_LEN} is given it is used as
@@ -319,6 +319,71 @@ _gcry_rsa_pkcs1_encode_for_sig (gcry_mpi_t *r_result, unsigned int nbits,
   return rc;
 }
 
+/* Encode {VALUE,VALUELEN} for an NBITS keys using the pkcs#1 block
+   type 1 padding.  On success the result is stored as a new MPI at
+   R_RESULT.  On error the value at R_RESULT is undefined.
+
+   We encode the value in this way:
+
+     0  1  PAD(n bytes)  0  VALUE(valuelen bytes)
+
+   0   is a marker we unfortunately can't encode because we return an
+       MPI which strips all leading zeroes.
+   1   is the block type.
+   PAD consists of 0xff bytes.
+   0   marks the end of the padding.
+
+   (Note that PGP prior to version 2.3 encoded the message digest as:
+      0   1   MD(16 bytes)   0   PAD(n bytes)   1
+    The MD is always 16 bytes here because it's always MD5.  GnuPG
+    does not not support pre-v2.3 signatures, but I'm including this
+    comment so the information is easily found if needed.)
+*/
+gpg_err_code_t
+_gcry_rsa_pkcs1_encode_raw_for_sig (gcry_mpi_t *r_result, unsigned int nbits,
+                                const unsigned char *value, size_t valuelen)
+{
+  gcry_err_code_t rc = 0;
+  gcry_error_t err;
+  byte *frame = NULL;
+  size_t nframe = (nbits+7) / 8;
+  int i;
+  size_t n;
+
+  if ( !valuelen || valuelen + 4 > nframe)
+    {
+      /* Can't encode an DLEN byte digest MD into an NFRAME byte
+         frame.  */
+      return GPG_ERR_TOO_SHORT;
+    }
+
+  if ( !(frame = xtrymalloc (nframe)) )
+    return gpg_err_code_from_syserror ();
+
+  /* Assemble the pkcs#1 block type 1. */
+  n = 0;
+  frame[n++] = 0;
+  frame[n++] = 1; /* block type */
+  i = nframe - valuelen - 3 ;
+  gcry_assert (i > 1);
+  memset (frame+n, 0xff, i );
+  n += i;
+  frame[n++] = 0;
+  memcpy (frame+n, value, valuelen );
+  n += valuelen;
+  gcry_assert (n == nframe);
+
+  /* Convert it into an MPI. */
+  err = _gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe);
+  if (err)
+    rc = gcry_err_code (err);
+  else if (DBG_CIPHER)
+    log_mpidump ("PKCS#1 block type 1 encoded data", *r_result);
+  xfree (frame);
+
+  return rc;
+}
+
 
 /* Mask generation function for OAEP.  See RFC-3447 B.2.1.  */
 static gcry_err_code_t
@@ -328,7 +393,7 @@ mgf1 (unsigned char *output, size_t outlen, unsigned char *seed, size_t seedlen,
   size_t dlen, nbytes, n;
   int idx;
   gcry_md_hd_t hd;
-  gcry_error_t err;
+  gcry_err_code_t err;
 
   err = _gcry_md_open (&hd, algo, 0);
   if (err)
@@ -610,7 +675,7 @@ _gcry_rsa_oaep_decode (unsigned char **r_result, size_t *r_resultlen,
     }
   db = seed + hlen;
 
-  /* To avoid choosen ciphertext attacks from now on we make sure to
+  /* To avoid chosen ciphertext attacks from now on we make sure to
      run all code even in the error case; this avoids possible timing
      attacks as described by Manger.  */
 
index 9a8d235..ce8e215 100644 (file)
@@ -62,36 +62,53 @@ static const char *rsa_names[] =
   };
 
 
-/* A sample 1024 bit RSA key used for the selftests.  */
+/* A sample 2048 bit RSA key used for the selftests.  */
 static const char sample_secret_key[] =
-"(private-key"
-" (rsa"
-"  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
-"      2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
-"      ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
-"      891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)"
-"  (e #010001#)"
-"  (d #046129f2489d71579be0a75fe029bd6cdb574ebf57ea8a5b0fda942cab943b11"
-"      7d7bb95e5d28875e0f9fc5fcc06a72f6d502464dabded78ef6b716177b83d5bd"
-"      c543dc5d3fed932e59f5897e92e6f58a0f33424106a3b6fa2cbf877510e4ac21"
-"      c3ee47851e97d12996222ac3566d4ccb0b83d164074abf7de655fc2446da1781#)"
-"  (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
-"      fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)"
-"  (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9"
-"      35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#)"
-"  (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
-"      ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)))";
-/* A sample 1024 bit RSA key used for the selftests (public only).  */
+" (private-key"
+"  (rsa"
+"  (n #009F56231A3D82E3E7D613D59D53E9AB921BEF9F08A782AED0B6E46ADBC853EC"
+"      7C71C422435A3CD8FA0DB9EFD55CD3295BADC4E8E2E2B94E15AE82866AB8ADE8"
+"      7E469FAE76DC3577DE87F1F419C4EB41123DFAF8D16922D5EDBAD6E9076D5A1C"
+"      958106F0AE5E2E9193C6B49124C64C2A241C4075D4AF16299EB87A6585BAE917"
+"      DEF27FCDD165764D069BC18D16527B29DAAB549F7BBED4A7C6A842D203ED6613"
+"      6E2411744E432CD26D940132F25874483DCAEECDFD95744819CBCF1EA810681C"
+"      42907EBCB1C7EAFBE75C87EC32C5413EA10476545D3FC7B2ADB1B66B7F200918"
+"      664B0E5261C2895AA28B0DE321E921B3F877172CCCAB81F43EF98002916156F6CB#)"
+"   (e #010001#)"
+"   (d #07EF82500C403899934FE993AC5A36F14FF2DF38CF1EF315F205EE4C83EDAA19"
+"       8890FC23DE9AA933CAFB37B6A8A8DBA675411958337287310D3FF2F1DDC0CB93"
+"       7E70F57F75F833C021852B631D2B9A520E4431A03C5C3FCB5742DCD841D9FB12"
+"       771AA1620DCEC3F1583426066ED9DC3F7028C5B59202C88FDF20396E2FA0EC4F"
+"       5A22D9008F3043673931BC14A5046D6327398327900867E39CC61B2D1AFE2F48"
+"       EC8E1E3861C68D257D7425F4E6F99ABD77D61F10CA100EFC14389071831B33DD"
+"       69CC8EABEF860D1DC2AAA84ABEAE5DFC91BC124DAF0F4C8EF5BBEA436751DE84"
+"       3A8063E827A024466F44C28614F93B0732A100D4A0D86D532FE1E22C7725E401#)"
+"   (p #00C29D438F115825779631CD665A5739367F3E128ADC29766483A46CA80897E0"
+"       79B32881860B8F9A6A04C2614A904F6F2578DAE13EA67CD60AE3D0AA00A1FF9B"
+"       441485E44B2DC3D0B60260FBFE073B5AC72FAF67964DE15C8212C389D20DB9CF"
+"       54AF6AEF5C4196EAA56495DD30CF709F499D5AB30CA35E086C2A1589D6283F1783#)"
+"   (q #00D1984135231CB243FE959C0CBEF551EDD986AD7BEDF71EDF447BE3DA27AF46"
+"       79C974A6FA69E4D52FE796650623DE70622862713932AA2FD9F2EC856EAEAA77"
+"       88B4EA6084DC81C902F014829B18EA8B2666EC41586818E0589E18876065F97E"
+"       8D22CE2DA53A05951EC132DCEF41E70A9C35F4ACC268FFAC2ADF54FA1DA110B919#)"
+"   (u #67CF0FD7635205DD80FA814EE9E9C267C17376BF3209FB5D1BC42890D2822A04"
+"       479DAF4D5B6ED69D0F8D1AF94164D07F8CD52ECEFE880641FA0F41DDAB1785E4"
+"       A37A32F997A516480B4CD4F6482B9466A1765093ED95023CA32D5EDC1E34CEE9"
+"       AF595BC51FE43C4BF810FA225AF697FB473B83815966188A4312C048B885E3F7#)))";
+
+/* A sample 2048 bit RSA key used for the selftests (public only).  */
 static const char sample_public_key[] =
-"(public-key"
-" (rsa"
-"  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
-"      2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
-"      ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
-"      891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)"
-"  (e #010001#)))";
-
-
+" (public-key"
+"  (rsa"
+"   (n #009F56231A3D82E3E7D613D59D53E9AB921BEF9F08A782AED0B6E46ADBC853EC"
+"       7C71C422435A3CD8FA0DB9EFD55CD3295BADC4E8E2E2B94E15AE82866AB8ADE8"
+"       7E469FAE76DC3577DE87F1F419C4EB41123DFAF8D16922D5EDBAD6E9076D5A1C"
+"       958106F0AE5E2E9193C6B49124C64C2A241C4075D4AF16299EB87A6585BAE917"
+"       DEF27FCDD165764D069BC18D16527B29DAAB549F7BBED4A7C6A842D203ED6613"
+"       6E2411744E432CD26D940132F25874483DCAEECDFD95744819CBCF1EA810681C"
+"       42907EBCB1C7EAFBE75C87EC32C5413EA10476545D3FC7B2ADB1B66B7F200918"
+"       664B0E5261C2895AA28B0DE321E921B3F877172CCCAB81F43EF98002916156F6CB#)"
+"   (e #010001#)))";
 
 \f
 static int test_keys (RSA_secret_key *sk, unsigned nbits);
@@ -339,6 +356,286 @@ generate_std (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e,
 }
 
 
+/****************
+ * Generate a key pair with a key of size NBITS.
+ * USE_E = 0 let Libcgrypt decide what exponent to use.
+ *       = 1 request the use of a "secure" exponent; this is required by some
+ *           specification to be 65537.
+ *       > 2 Use this public exponent.  If the given exponent
+ *           is not odd one is internally added to it.
+ * TESTPARMS: If set, do not generate but test whether the p,q is probably prime
+ *            Returns key with zeroes to not break code calling this function.
+ * TRANSIENT_KEY:  If true, generate the primes using the standard RNG.
+ * Returns: 2 structures filled with all needed values
+ */
+static gpg_err_code_t
+generate_fips (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e,
+               gcry_sexp_t testparms, int transient_key)
+{
+  gcry_mpi_t p, q; /* the two primes */
+  gcry_mpi_t d;    /* the private key */
+  gcry_mpi_t u;
+  gcry_mpi_t p1, q1;
+  gcry_mpi_t n;    /* the public key */
+  gcry_mpi_t e;    /* the exponent */
+  gcry_mpi_t g;
+  gcry_mpi_t minp;
+  gcry_mpi_t diff, mindiff;
+  gcry_random_level_t random_level;
+  unsigned int pbits = nbits/2;
+  unsigned int i;
+  int pqswitch;
+  gpg_err_code_t ec = GPG_ERR_NO_PRIME;
+
+  if (nbits < 1024 || (nbits & 0x1FF))
+    return GPG_ERR_INV_VALUE;
+  if (_gcry_enforced_fips_mode() && nbits != 2048 && nbits != 3072)
+      return GPG_ERR_INV_VALUE;
+
+  /* The random quality depends on the transient_key flag.  */
+  random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
+
+  if (testparms)
+    {
+      /* Parameters to derive the key are given.  */
+      /* Note that we explicitly need to setup the values of tbl
+         because some compilers (e.g. OpenWatcom, IRIX) don't allow to
+         initialize a structure with automatic variables.  */
+      struct { const char *name; gcry_mpi_t *value; } tbl[] = {
+        { "e" },
+        { "p" },
+        { "q" },
+        { NULL }
+      };
+      int idx;
+      gcry_sexp_t oneparm;
+
+      tbl[0].value = &e;
+      tbl[1].value = &p;
+      tbl[2].value = &q;
+
+      for (idx=0; tbl[idx].name; idx++)
+        {
+          oneparm = sexp_find_token (testparms, tbl[idx].name, 0);
+          if (oneparm)
+            {
+              *tbl[idx].value = sexp_nth_mpi (oneparm, 1, GCRYMPI_FMT_USG);
+              sexp_release (oneparm);
+            }
+        }
+      for (idx=0; tbl[idx].name; idx++)
+        if (!*tbl[idx].value)
+          break;
+      if (tbl[idx].name)
+        {
+          /* At least one parameter is missing.  */
+          for (idx=0; tbl[idx].name; idx++)
+            _gcry_mpi_release (*tbl[idx].value);
+          return GPG_ERR_MISSING_VALUE;
+        }
+    }
+  else
+    {
+      if (use_e < 65537)
+        use_e = 65537;  /* This is the smallest value allowed by FIPS */
+
+      e = mpi_alloc ((32+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB);
+
+      use_e |= 1; /* make sure this is odd */
+      mpi_set_ui (e, use_e);
+
+      p = mpi_snew (pbits);
+      q = mpi_snew (pbits);
+    }
+
+  n = mpi_new (nbits);
+  d = mpi_snew (nbits);
+  u = mpi_snew (nbits);
+
+  /* prepare approximate minimum p and q */
+  minp = mpi_new (pbits);
+  mpi_set_ui (minp, 0xB504F334);
+  mpi_lshift (minp, minp, pbits - 32);
+
+  /* prepare minimum p and q difference */
+  diff = mpi_new (pbits);
+  mindiff = mpi_new (pbits - 99);
+  mpi_set_ui (mindiff, 1);
+  mpi_lshift (mindiff, mindiff, pbits - 100);
+
+  p1 = mpi_snew (pbits);
+  q1 = mpi_snew (pbits);
+  g  = mpi_snew (pbits);
+
+ retry:
+  /* generate p and q */
+  for (i = 0; i < 5 * pbits; i++)
+    {
+    ploop:
+      if (!testparms)
+        {
+          _gcry_mpi_randomize (p, pbits, random_level);
+        }
+      if (mpi_cmp (p, minp) < 0)
+        {
+          if (testparms)
+            goto err;
+          goto ploop;
+        }
+
+      mpi_sub_ui (p1, p, 1);
+      if (mpi_gcd (g, p1, e))
+        {
+          if (_gcry_fips186_4_prime_check (p, pbits) != GPG_ERR_NO_ERROR)
+            {
+              /* not a prime */
+              if (testparms)
+                goto err;
+            }
+          else
+            break;
+        }
+      else if (testparms)
+        goto err;
+    }
+  if (i >= 5 * pbits)
+    goto err;
+
+  for (i = 0; i < 5 * pbits; i++)
+    {
+    qloop:
+      if (!testparms)
+        {
+          _gcry_mpi_randomize (q, pbits, random_level);
+        }
+      if (mpi_cmp (q, minp) < 0)
+        {
+          if (testparms)
+            goto err;
+          goto qloop;
+        }
+      if (mpi_cmp (p, q) > 0)
+        {
+          pqswitch = 1;
+          mpi_sub (diff, p, q);
+        }
+      else
+        {
+          pqswitch = 0;
+          mpi_sub (diff, q, p);
+        }
+      if (mpi_cmp (diff, mindiff) < 0)
+        {
+          if (testparms)
+            goto err;
+          goto qloop;
+        }
+
+      mpi_sub_ui (q1, q, 1);
+      if (mpi_gcd (g, q1, e))
+        {
+          if (_gcry_fips186_4_prime_check (q, pbits) != GPG_ERR_NO_ERROR)
+            {
+              /* not a prime */
+              if (testparms)
+                goto err;
+            }
+          else
+            break;
+        }
+      else if (testparms)
+        goto err;
+    }
+  if (i >= 5 * pbits)
+    goto err;
+
+  if (testparms)
+    {
+      mpi_clear (p);
+      mpi_clear (q);
+    }
+  else
+    {
+      gcry_mpi_t f;
+
+      if (pqswitch)
+        {
+          gcry_mpi_t tmp;
+
+          tmp = p;
+          p = q;
+          q = tmp;
+        }
+
+      f = mpi_snew (nbits);
+
+      /* calculate the modulus */
+      mpi_mul (n, p, q);
+
+      /* calculate the secret key d = e^1 mod phi */
+      mpi_gcd (g, p1, q1);
+      mpi_fdiv_q (f, p1, g);
+      mpi_mul (f, f, q1);
+
+      mpi_invm (d, e, f);
+
+      _gcry_mpi_release (f);
+
+      if (mpi_get_nbits (d) < pbits)
+        goto retry;
+
+      /* calculate the inverse of p and q (used for chinese remainder theorem)*/
+      mpi_invm (u, p, q );
+    }
+
+  ec = 0;
+
+  if (DBG_CIPHER)
+    {
+      log_mpidump("  p= ", p );
+      log_mpidump("  q= ", q );
+      log_mpidump("  n= ", n );
+      log_mpidump("  e= ", e );
+      log_mpidump("  d= ", d );
+      log_mpidump("  u= ", u );
+    }
+
+ err:
+
+  _gcry_mpi_release (p1);
+  _gcry_mpi_release (q1);
+  _gcry_mpi_release (g);
+  _gcry_mpi_release (minp);
+  _gcry_mpi_release (mindiff);
+  _gcry_mpi_release (diff);
+
+  sk->n = n;
+  sk->e = e;
+  sk->p = p;
+  sk->q = q;
+  sk->d = d;
+  sk->u = u;
+
+  /* Now we can test our keys. */
+  if (ec || (!testparms && test_keys (sk, nbits - 64)))
+    {
+      _gcry_mpi_release (sk->n); sk->n = NULL;
+      _gcry_mpi_release (sk->e); sk->e = NULL;
+      _gcry_mpi_release (sk->p); sk->p = NULL;
+      _gcry_mpi_release (sk->q); sk->q = NULL;
+      _gcry_mpi_release (sk->d); sk->d = NULL;
+      _gcry_mpi_release (sk->u); sk->u = NULL;
+      if (!ec)
+        {
+          fips_signal_error ("self-test after key generation failed");
+          return GPG_ERR_SELFTEST_FAILED;
+        }
+    }
+
+  return ec;
+}
+
+
 /* Helper for generate_x931.  */
 static gcry_mpi_t
 gen_x931_parm_xp (unsigned int nbits)
@@ -738,7 +1035,7 @@ secret (gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey )
       if ( mpi_has_sign ( h ) )
         mpi_add ( h, h, skey->q );
       mpi_mulm( h, skey->u, h, skey->q );
-      /* m = m2 + h * p */
+      /* m = m1 + h * p */
       mpi_mul ( h, h, skey->p );
       mpi_add ( output, m1, h );
 
@@ -748,7 +1045,48 @@ secret (gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey )
     }
 }
 
+static void
+secret_blinded (gcry_mpi_t output, gcry_mpi_t input,
+                RSA_secret_key *sk, unsigned int nbits)
+{
+  gcry_mpi_t r;                   /* Random number needed for blinding.  */
+  gcry_mpi_t ri;          /* Modular multiplicative inverse of r.  */
+  gcry_mpi_t bldata;       /* Blinded data to decrypt.  */
+
+  /* First, we need a random number r between 0 and n - 1, which is
+   * relatively prime to n (i.e. it is neither p nor q).  The random
+   * number needs to be only unpredictable, thus we employ the
+   * gcry_create_nonce function by using GCRY_WEAK_RANDOM with
+   * gcry_mpi_randomize.  */
+  r  = mpi_snew (nbits);
+  ri = mpi_snew (nbits);
+  bldata = mpi_snew (nbits);
+
+  do
+    {
+      _gcry_mpi_randomize (r, nbits, GCRY_WEAK_RANDOM);
+      mpi_mod (r, r, sk->n);
+    }
+  while (!mpi_invm (ri, r, sk->n));
 
+  /* Do blinding.  We calculate: y = (x * r^e) mod n, where r is the
+   * random number, e is the public exponent, x is the non-blinded
+   * input data and n is the RSA modulus.  */
+  mpi_powm (bldata, r, sk->e, sk->n);
+  mpi_mulm (bldata, bldata, input, sk->n);
+
+  /* Perform decryption.  */
+  secret (output, bldata, sk);
+  _gcry_mpi_release (bldata);
+
+  /* Undo blinding.  Here we calculate: y = (x * r^-1) mod n, where x
+   * is the blinded decrypted data, ri is the modular multiplicative
+   * inverse of r and n is the RSA modulus.  */
+  mpi_mulm (output, output, ri, sk->n);
+
+  _gcry_mpi_release (r);
+  _gcry_mpi_release (ri);
+}
 
 /*********************************************
  **************  interface  ******************
@@ -799,7 +1137,7 @@ rsa_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
         }
     }
 
-  if (deriveparms || (flags & PUBKEY_FLAG_USE_X931) || fips_mode ())
+  if (deriveparms || (flags & PUBKEY_FLAG_USE_X931))
     {
       int swapped;
       ec = generate_x931 (&sk, nbits, evalue, deriveparms, &swapped);
@@ -819,9 +1157,21 @@ rsa_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
               sexp_release (l1);
             }
         }
+      deriveparms = (genparms? sexp_find_token (genparms, "test-parms", 0)
+                     /**/    : NULL);
+
       /* Generate.  */
-      ec = generate_std (&sk, nbits, evalue,
-                         !!(flags & PUBKEY_FLAG_TRANSIENT_KEY));
+      if (deriveparms || fips_mode())
+        {
+          ec = generate_fips (&sk, nbits, evalue, deriveparms,
+                              !!(flags & PUBKEY_FLAG_TRANSIENT_KEY));
+        }
+      else
+        {
+          ec = generate_std (&sk, nbits, evalue,
+                             !!(flags & PUBKEY_FLAG_TRANSIENT_KEY));
+        }
+      sexp_release (deriveparms);
     }
 
   if (!ec)
@@ -957,9 +1307,6 @@ rsa_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
   gcry_mpi_t data = NULL;
   RSA_secret_key sk = {NULL, NULL, NULL, NULL, NULL, NULL};
   gcry_mpi_t plain = NULL;
-  gcry_mpi_t r = NULL;    /* Random number needed for blinding.  */
-  gcry_mpi_t ri = NULL;           /* Modular multiplicative inverse of r.  */
-  gcry_mpi_t bldata = NULL;/* Blinded data to decrypt.  */
   unsigned char *unpad = NULL;
   size_t unpadlen = 0;
 
@@ -1012,44 +1359,10 @@ rsa_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
   /* We use blinding by default to mitigate timing attacks which can
      be practically mounted over the network as shown by Brumley and
      Boney in 2003.  */
-  if (!(ctx.flags & PUBKEY_FLAG_NO_BLINDING))
-    {
-      /* First, we need a random number r between 0 and n - 1, which
-        is relatively prime to n (i.e. it is neither p nor q).  The
-        random number needs to be only unpredictable, thus we employ
-        the gcry_create_nonce function by using GCRY_WEAK_RANDOM with
-        gcry_mpi_randomize.  */
-      r  = mpi_snew (ctx.nbits);
-      ri = mpi_snew (ctx.nbits);
-      bldata = mpi_snew (ctx.nbits);
-
-      do
-        {
-          _gcry_mpi_randomize (r, ctx.nbits, GCRY_WEAK_RANDOM);
-          mpi_mod (r, r, sk.n);
-        }
-      while (!mpi_invm (ri, r, sk.n));
-
-      /* Do blinding.  We calculate: y = (x * r^e) mod n, where r is
-         the random number, e is the public exponent, x is the
-         non-blinded data and n is the RSA modulus.  */
-      mpi_powm (bldata, r, sk.e, sk.n);
-      mpi_mulm (bldata, bldata, data, sk.n);
-
-      /* Perform decryption.  */
-      secret (plain, bldata, &sk);
-      _gcry_mpi_release (bldata); bldata = NULL;
-
-      /* Undo blinding.  Here we calculate: y = (x * r^-1) mod n,
-         where x is the blinded decrypted data, ri is the modular
-         multiplicative inverse of r and n is the RSA modulus.  */
-      mpi_mulm (plain, plain, ri, sk.n);
-
-      _gcry_mpi_release (r); r = NULL;
-      _gcry_mpi_release (ri); ri = NULL;
-    }
-  else
+  if ((ctx.flags & PUBKEY_FLAG_NO_BLINDING))
     secret (plain, data, &sk);
+  else
+    secret_blinded (plain, data, &sk, ctx.nbits);
 
   if (DBG_CIPHER)
     log_printmpi ("rsa_decrypt  res", plain);
@@ -1094,9 +1407,6 @@ rsa_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
   _gcry_mpi_release (sk.q);
   _gcry_mpi_release (sk.u);
   _gcry_mpi_release (data);
-  _gcry_mpi_release (r);
-  _gcry_mpi_release (ri);
-  _gcry_mpi_release (bldata);
   sexp_release (l1);
   _gcry_pk_util_free_encoding_ctx (&ctx);
   if (DBG_CIPHER)
@@ -1112,7 +1422,9 @@ rsa_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
   struct pk_encoding_ctx ctx;
   gcry_mpi_t data = NULL;
   RSA_secret_key sk = {NULL, NULL, NULL, NULL, NULL, NULL};
+  RSA_public_key pk;
   gcry_mpi_t sig = NULL;
+  gcry_mpi_t result = NULL;
 
   _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_SIGN,
                                    rsa_get_nbits (keyparms));
@@ -1148,11 +1460,28 @@ rsa_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
         }
     }
 
-  /* Do RSA computation and build the result.  */
+  /* Do RSA computation.  */
   sig = mpi_new (0);
-  secret (sig, data, &sk);
+  if ((ctx.flags & PUBKEY_FLAG_NO_BLINDING))
+    secret (sig, data, &sk);
+  else
+    secret_blinded (sig, data, &sk, ctx.nbits);
   if (DBG_CIPHER)
     log_printmpi ("rsa_sign    res", sig);
+
+  /* Check that the created signature is good.  This detects a failure
+     of the CRT algorithm  (Lenstra's attack on RSA's use of the CRT).  */
+  result = mpi_new (0);
+  pk.n = sk.n;
+  pk.e = sk.e;
+  public (result, sig, &pk);
+  if (mpi_cmp (result, data))
+    {
+      rc = GPG_ERR_BAD_SIGNATURE;
+      goto leave;
+    }
+
+  /* Convert the result.  */
   if ((ctx.flags & PUBKEY_FLAG_FIXEDLEN))
     {
       /* We need to make sure to return the correct length to avoid
@@ -1172,6 +1501,7 @@ rsa_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
 
 
  leave:
+  _gcry_mpi_release (result);
   _gcry_mpi_release (sig);
   _gcry_mpi_release (sk.n);
   _gcry_mpi_release (sk.e);
@@ -1332,20 +1662,34 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
  */
 
 static const char *
-selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
+selftest_sign_2048 (gcry_sexp_t pkey, gcry_sexp_t skey)
 {
   static const char sample_data[] =
     "(data (flags pkcs1)"
-    " (hash sha1 #11223344556677889900aabbccddeeff10203040#))";
+    " (hash sha256 #11223344556677889900aabbccddeeff"
+    /**/           "102030405060708090a0b0c0d0f01121#))";
   static const char sample_data_bad[] =
     "(data (flags pkcs1)"
-    " (hash sha1 #11223344556677889900aabbccddeeff80203040#))";
+    " (hash sha256 #11223344556677889900aabbccddeeff"
+    /**/           "802030405060708090a0b0c0d0f01121#))";
 
   const char *errtxt = NULL;
   gcry_error_t err;
   gcry_sexp_t data = NULL;
   gcry_sexp_t data_bad = NULL;
   gcry_sexp_t sig = NULL;
+  /* raw signature data reference */
+  const char ref_data[] =
+    "6252a19a11e1d5155ed9376036277193d644fa239397fff03e9b92d6f86415d6"
+    "d30da9273775f290e580d038295ff8ff89522becccfa6ae870bf76b76df402a8"
+    "54f69347e3db3de8e1e7d4dada281ec556810c7a8ecd0b5f51f9b1c0e7aa7557"
+    "61aa2b8ba5f811304acc6af0eca41fe49baf33bf34eddaf44e21e036ac7f0b68"
+    "03cdef1c60021fb7b5b97ebacdd88ab755ce29af568dbc5728cc6e6eff42618d"
+    "62a0386ca8beed46402bdeeef29b6a3feded906bace411a06a39192bf516ae10"
+    "67e4320fa8ea113968525f4574d022a3ceeaafdc41079efe1f22cc94bf59d8d3"
+    "328085da9674857db56de5978a62394aab48aa3b72e23a1b16260cfd9daafe65";
+  gcry_mpi_t ref_mpi = NULL;
+  gcry_mpi_t sig_mpi = NULL;
 
   err = sexp_sscan (&data, NULL, sample_data, strlen (sample_data));
   if (!err)
@@ -1363,6 +1707,27 @@ selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
       errtxt = "signing failed";
       goto leave;
     }
+
+  err = _gcry_mpi_scan(&ref_mpi, GCRYMPI_FMT_HEX, ref_data, 0, NULL);
+  if (err)
+    {
+      errtxt = "converting ref_data to mpi failed";
+      goto leave;
+    }
+
+  err = _gcry_sexp_extract_param(sig, "sig-val!rsa", "s", &sig_mpi, NULL);
+  if (err)
+    {
+      errtxt = "extracting signature data failed";
+      goto leave;
+    }
+
+  if (mpi_cmp (sig_mpi, ref_mpi))
+    {
+      errtxt = "signature does not match reference data";
+      goto leave;
+    }
+
   err = _gcry_pk_verify (sig, data, pkey);
   if (err)
     {
@@ -1381,6 +1746,8 @@ selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
   sexp_release (sig);
   sexp_release (data_bad);
   sexp_release (data);
+  _gcry_mpi_release (ref_mpi);
+  _gcry_mpi_release (sig_mpi);
   return errtxt;
 }
 
@@ -1419,25 +1786,33 @@ extract_a_from_sexp (gcry_sexp_t encr_data)
 
 
 static const char *
-selftest_encr_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
+selftest_encr_2048 (gcry_sexp_t pkey, gcry_sexp_t skey)
 {
   const char *errtxt = NULL;
   gcry_error_t err;
-  const unsigned int nbits = 1000; /* Encrypt 1000 random bits.  */
-  gcry_mpi_t plaintext = NULL;
+  static const char plaintext[] =
+    "Jim quickly realized that the beautiful gowns are expensive.";
   gcry_sexp_t plain = NULL;
   gcry_sexp_t encr  = NULL;
   gcry_mpi_t  ciphertext = NULL;
   gcry_sexp_t decr  = NULL;
-  gcry_mpi_t  decr_plaintext = NULL;
+  char *decr_plaintext = NULL;
   gcry_sexp_t tmplist = NULL;
-
-  /* Create plaintext.  The plaintext is actually a big integer number.  */
-  plaintext = mpi_new (nbits);
-  _gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM);
+  /* expected result of encrypting the plaintext with sample_secret_key */
+  static const char ref_data[] =
+    "18022e2593a402a737caaa93b4c7e750e20ca265452980e1d6b7710fbd3e"
+    "7dce72be5c2110fb47691cb38f42170ee3b4a37f2498d4a51567d762585e"
+    "4cb81d04fbc7df4144f8e5eac2d4b8688521b64011f11d7ad53f4c874004"
+    "819856f2e2a6f83d1c9c4e73ac26089789c14482b0b8d44139133c88c4a5"
+    "2dba9dd6d6ffc622666b7d129168333d999706af30a2d7d272db7734e5ed"
+    "fb8c64ea3018af3ad20f4a013a5060cb0f5e72753967bebe294280a6ed0d"
+    "dbd3c4f11d0a8696e9d32a0dc03deb0b5e49b2cbd1503392642d4e1211f3"
+    "e8e2ee38abaa3671ccd57fcde8ca76e85fd2cb77c35706a970a213a27352"
+    "cec92a9604d543ddb5fc478ff50e0622";
+  gcry_mpi_t ref_mpi = NULL;
 
   /* Put the plaintext into an S-expression.  */
-  err = sexp_build (&plain, NULL, "(data (flags raw) (value %m))", plaintext);
+  err = sexp_build (&plain, NULL, "(data (flags raw) (value %s))", plaintext);
   if (err)
     {
       errtxt = "converting data failed";
@@ -1452,6 +1827,13 @@ selftest_encr_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
       goto leave;
     }
 
+  err = _gcry_mpi_scan(&ref_mpi, GCRYMPI_FMT_HEX, ref_data, 0, NULL);
+  if (err)
+    {
+      errtxt = "converting encrydata to mpi failed";
+      goto leave;
+    }
+
   /* Extraxt the ciphertext from the returned S-expression.  */
   /*sexp_dump (encr);*/
   ciphertext = extract_a_from_sexp (encr);
@@ -1464,9 +1846,9 @@ selftest_encr_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
   /* Check that the ciphertext does no match the plaintext.  */
   /* _gcry_log_printmpi ("plaintext", plaintext); */
   /* _gcry_log_printmpi ("ciphertxt", ciphertext); */
-  if (!mpi_cmp (plaintext, ciphertext))
+  if (mpi_cmp (ref_mpi, ciphertext))
     {
-      errtxt = "ciphertext matches plaintext";
+      errtxt = "ciphertext doesn't match reference data";
       goto leave;
     }
 
@@ -1486,9 +1868,9 @@ selftest_encr_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
      take care of it anyway.  */
   tmplist = sexp_find_token (decr, "value", 0);
   if (tmplist)
-    decr_plaintext = sexp_nth_mpi (tmplist, 1, GCRYMPI_FMT_USG);
+    decr_plaintext = sexp_nth_string (tmplist, 1);
   else
-    decr_plaintext = sexp_nth_mpi (decr, 0, GCRYMPI_FMT_USG);
+    decr_plaintext = sexp_nth_string (decr, 0);
   if (!decr_plaintext)
     {
       errtxt = "decrypt returned no plaintext";
@@ -1496,7 +1878,7 @@ selftest_encr_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
     }
 
   /* Check that the decrypted plaintext matches the original  plaintext.  */
-  if (mpi_cmp (plaintext, decr_plaintext))
+  if (strcmp (plaintext, decr_plaintext))
     {
       errtxt = "mismatch";
       goto leave;
@@ -1504,12 +1886,12 @@ selftest_encr_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
 
  leave:
   sexp_release (tmplist);
-  _gcry_mpi_release (decr_plaintext);
+  xfree (decr_plaintext);
   sexp_release (decr);
   _gcry_mpi_release (ciphertext);
+  _gcry_mpi_release (ref_mpi);
   sexp_release (encr);
   sexp_release (plain);
-  _gcry_mpi_release (plaintext);
   return errtxt;
 }
 
@@ -1544,12 +1926,12 @@ selftests_rsa (selftest_report_func_t report)
     }
 
   what = "sign";
-  errtxt = selftest_sign_1024 (pkey, skey);
+  errtxt = selftest_sign_2048 (pkey, skey);
   if (errtxt)
     goto failed;
 
   what = "encrypt";
-  errtxt = selftest_encr_1024 (pkey, skey);
+  errtxt = selftest_encr_2048 (pkey, skey);
   if (errtxt)
     goto failed;
 
index e79da4e..470c32a 100644 (file)
@@ -1,6 +1,6 @@
 /* salsa20-amd64.S  -  AMD64 implementation of Salsa20
  *
- * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
 
 #ifdef __x86_64
 #include <config.h>
-#if defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && defined(USE_SALSA20)
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+    defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && defined(USE_SALSA20)
+
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
 
 .text
 
 .align 8
 .globl _gcry_salsa20_amd64_keysetup
-.type  _gcry_salsa20_amd64_keysetup,@function;
+ELF(.type  _gcry_salsa20_amd64_keysetup,@function;)
 _gcry_salsa20_amd64_keysetup:
        movl   0(%rsi),%r8d
        movl   4(%rsi),%r9d
@@ -83,7 +90,7 @@ _gcry_salsa20_amd64_keysetup:
 
 .align 8
 .globl _gcry_salsa20_amd64_ivsetup
-.type  _gcry_salsa20_amd64_ivsetup,@function;
+ELF(.type  _gcry_salsa20_amd64_ivsetup,@function;)
 _gcry_salsa20_amd64_ivsetup:
        movl   0(%rsi),%r8d
        movl   4(%rsi),%esi
@@ -97,7 +104,7 @@ _gcry_salsa20_amd64_ivsetup:
 
 .align 8
 .globl _gcry_salsa20_amd64_encrypt_blocks
-.type  _gcry_salsa20_amd64_encrypt_blocks,@function;
+ELF(.type  _gcry_salsa20_amd64_encrypt_blocks,@function;)
 _gcry_salsa20_amd64_encrypt_blocks:
        /*
         * Modifications to original implementation:
@@ -918,7 +925,7 @@ _gcry_salsa20_amd64_encrypt_blocks:
        add  $64,%rdi
        add  $64,%rsi
        jmp .L_bytes_are_64_128_or_192
-.size _gcry_salsa20_amd64_encrypt_blocks,.-_gcry_salsa20_amd64_encrypt_blocks;
+ELF(.size _gcry_salsa20_amd64_encrypt_blocks,.-_gcry_salsa20_amd64_encrypt_blocks;)
 
 #endif /*defined(USE_SALSA20)*/
 #endif /*__x86_64*/
index 8a9d9c4..3686e3f 100644 (file)
@@ -1,6 +1,6 @@
 /* salsa-armv7-neon.S  -  ARM NEON implementation of Salsa20 cipher
  *
- * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
index d75fe51..9768198 100644 (file)
@@ -43,7 +43,8 @@
 
 /* USE_AMD64 indicates whether to compile with AMD64 code. */
 #undef USE_AMD64
-#if defined(__x86_64__) && defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS)
+#if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+    defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
 # define USE_AMD64 1
 #endif
 
@@ -118,12 +119,25 @@ static const char *selftest (void);
 
 
 #ifdef USE_AMD64
+
+/* Assembly implementations use SystemV ABI, ABI conversion and additional
+ * stack to store XMM6-XMM15 needed on Win64. */
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+# define ASM_FUNC_ABI __attribute__((sysv_abi))
+# define ASM_EXTRA_STACK (10 * 16)
+#else
+# define ASM_FUNC_ABI
+# define ASM_EXTRA_STACK 0
+#endif
+
 /* AMD64 assembly implementations of Salsa20. */
-void _gcry_salsa20_amd64_keysetup(u32 *ctxinput, const void *key, int keybits);
-void _gcry_salsa20_amd64_ivsetup(u32 *ctxinput, const void *iv);
+void _gcry_salsa20_amd64_keysetup(u32 *ctxinput, const void *key, int keybits)
+                                 ASM_FUNC_ABI;
+void _gcry_salsa20_amd64_ivsetup(u32 *ctxinput, const void *iv)
+                                ASM_FUNC_ABI;
 unsigned int
 _gcry_salsa20_amd64_encrypt_blocks(u32 *ctxinput, const void *src, void *dst,
-                                   size_t len, int rounds);
+                                   size_t len, int rounds) ASM_FUNC_ABI;
 
 static void
 salsa20_keysetup(SALSA20_context_t *ctx, const byte *key, int keylen)
@@ -141,7 +155,8 @@ static unsigned int
 salsa20_core (u32 *dst, SALSA20_context_t *ctx, unsigned int rounds)
 {
   memset(dst, 0, SALSA20_BLOCK_SIZE);
-  return _gcry_salsa20_amd64_encrypt_blocks(ctx->input, dst, dst, 1, rounds);
+  return _gcry_salsa20_amd64_encrypt_blocks(ctx->input, dst, dst, 1, rounds)
+         + ASM_EXTRA_STACK;
 }
 
 #else /* USE_AMD64 */
@@ -418,6 +433,7 @@ salsa20_do_encrypt_stream (SALSA20_context_t *ctx,
       size_t nblocks = length / SALSA20_BLOCK_SIZE;
       burn = _gcry_salsa20_amd64_encrypt_blocks(ctx->input, inbuf, outbuf,
                                                 nblocks, rounds);
+      burn += ASM_EXTRA_STACK;
       length -= SALSA20_BLOCK_SIZE * nblocks;
       outbuf += SALSA20_BLOCK_SIZE * nblocks;
       inbuf  += SALSA20_BLOCK_SIZE * nblocks;
@@ -485,7 +501,8 @@ salsa20r12_encrypt_stream (void *context,
 static const char*
 selftest (void)
 {
-  SALSA20_context_t ctx;
+  byte ctxbuf[sizeof(SALSA20_context_t) + 15];
+  SALSA20_context_t *ctx;
   byte scratch[8+1];
   byte buf[256+64+4];
   int i;
@@ -502,32 +519,35 @@ selftest (void)
   static const byte ciphertext_1[] =
     { 0xE3, 0xBE, 0x8F, 0xDD, 0x8B, 0xEC, 0xA2, 0xE3};
 
-  salsa20_setkey (&ctx, key_1, sizeof key_1);
-  salsa20_setiv  (&ctx, nonce_1, sizeof nonce_1);
+  /* 16-byte alignment required for amd64 implementation. */
+  ctx = (SALSA20_context_t *)((uintptr_t)(ctxbuf + 15) & ~(uintptr_t)15);
+
+  salsa20_setkey (ctx, key_1, sizeof key_1);
+  salsa20_setiv  (ctx, nonce_1, sizeof nonce_1);
   scratch[8] = 0;
-  salsa20_encrypt_stream (&ctx, scratch, plaintext_1, sizeof plaintext_1);
+  salsa20_encrypt_stream (ctx, scratch, plaintext_1, sizeof plaintext_1);
   if (memcmp (scratch, ciphertext_1, sizeof ciphertext_1))
     return "Salsa20 encryption test 1 failed.";
   if (scratch[8])
     return "Salsa20 wrote too much.";
-  salsa20_setkey( &ctx, key_1, sizeof(key_1));
-  salsa20_setiv  (&ctx, nonce_1, sizeof nonce_1);
-  salsa20_encrypt_stream (&ctx, scratch, scratch, sizeof plaintext_1);
+  salsa20_setkey( ctx, key_1, sizeof(key_1));
+  salsa20_setiv  (ctx, nonce_1, sizeof nonce_1);
+  salsa20_encrypt_stream (ctx, scratch, scratch, sizeof plaintext_1);
   if (memcmp (scratch, plaintext_1, sizeof plaintext_1))
     return "Salsa20 decryption test 1 failed.";
 
   for (i = 0; i < sizeof buf; i++)
     buf[i] = i;
-  salsa20_setkey (&ctx, key_1, sizeof key_1);
-  salsa20_setiv (&ctx, nonce_1, sizeof nonce_1);
+  salsa20_setkey (ctx, key_1, sizeof key_1);
+  salsa20_setiv (ctx, nonce_1, sizeof nonce_1);
   /*encrypt*/
-  salsa20_encrypt_stream (&ctx, buf, buf, sizeof buf);
+  salsa20_encrypt_stream (ctx, buf, buf, sizeof buf);
   /*decrypt*/
-  salsa20_setkey (&ctx, key_1, sizeof key_1);
-  salsa20_setiv (&ctx, nonce_1, sizeof nonce_1);
-  salsa20_encrypt_stream (&ctx, buf, buf, 1);
-  salsa20_encrypt_stream (&ctx, buf+1, buf+1, (sizeof buf)-1-1);
-  salsa20_encrypt_stream (&ctx, buf+(sizeof buf)-1, buf+(sizeof buf)-1, 1);
+  salsa20_setkey (ctx, key_1, sizeof key_1);
+  salsa20_setiv (ctx, nonce_1, sizeof nonce_1);
+  salsa20_encrypt_stream (ctx, buf, buf, 1);
+  salsa20_encrypt_stream (ctx, buf+1, buf+1, (sizeof buf)-1-1);
+  salsa20_encrypt_stream (ctx, buf+(sizeof buf)-1, buf+(sizeof buf)-1, 1);
   for (i = 0; i < sizeof buf; i++)
     if (buf[i] != (byte)i)
       return "Salsa20 encryption test 2 failed.";
index 404943d..13fd1cf 100644 (file)
@@ -50,8 +50,6 @@
 #include "bufhelp.h"
 
 /* We really need a 64 bit type for this code.  */
-#ifdef HAVE_U64_TYPEDEF
-
 #define SALSA20_INPUT_LENGTH 16
 
 #define ROTL32(n,x) (((x)<<(n)) | ((x)>>(32-(n))))
@@ -76,7 +74,7 @@
 
 
 static void
-_salsa20_core(u32 *dst, const u32 *src, unsigned rounds)
+salsa20_core (u32 *dst, const u32 *src, unsigned int rounds)
 {
   u32 x[SALSA20_INPUT_LENGTH];
   unsigned i;
@@ -108,7 +106,7 @@ _salsa20_core(u32 *dst, const u32 *src, unsigned rounds)
 
 
 static void
-_scryptBlockMix (u32 r, unsigned char *B, unsigned char *tmp2)
+scrypt_block_mix (u32 r, unsigned char *B, unsigned char *tmp2)
 {
   u64 i;
   unsigned char *X = tmp2;
@@ -142,7 +140,7 @@ _scryptBlockMix (u32 r, unsigned char *B, unsigned char *tmp2)
       buf_xor(X, X, &B[i * 64], 64);
 
       /* X = Salsa (T) */
-      _salsa20_core ((u32*)X, (u32*)X, 8);
+      salsa20_core ((u32*)(void*)X, (u32*)(void*)X, 8);
 
       /* Y[i] = X */
       memcpy (&Y[i * 64], X, 64);
@@ -173,8 +171,9 @@ _scryptBlockMix (u32 r, unsigned char *B, unsigned char *tmp2)
 #endif
 }
 
+
 static void
-_scryptROMix (u32 r, unsigned char *B, u64 N,
+scrypt_ro_mix (u32 r, unsigned char *B, u64 N,
              unsigned char *tmp1, unsigned char *tmp2)
 {
   unsigned char *X = B, *T = B;
@@ -201,7 +200,7 @@ _scryptROMix (u32 r, unsigned char *B, u64 N,
       memcpy (&tmp1[i * 128 * r], X, 128 * r);
 
       /* X =  ScryptBlockMix (X) */
-      _scryptBlockMix (r, X, tmp2);
+      scrypt_block_mix (r, X, tmp2);
     }
 
   /* for i = 0 to N - 1 do */
@@ -216,7 +215,7 @@ _scryptROMix (u32 r, unsigned char *B, u64 N,
       buf_xor (T, T, &tmp1[j * 128 * r], 128 * r);
 
       /* X = scryptBlockMix (T) */
-      _scryptBlockMix (r, T, tmp2);
+      scrypt_block_mix (r, T, tmp2);
     }
 
 #if 0
@@ -234,7 +233,9 @@ _scryptROMix (u32 r, unsigned char *B, u64 N,
 #endif
 }
 
-/**
+
+/*
+ *
  */
 gcry_err_code_t
 _gcry_kdf_scrypt (const unsigned char *passwd, size_t passwdlen,
@@ -243,7 +244,7 @@ _gcry_kdf_scrypt (const unsigned char *passwd, size_t passwdlen,
                   unsigned long iterations,
                   size_t dkLen, unsigned char *DK)
 {
-  u64 N = subalgo;    /* CPU/memory cost paramter.  */
+  u64 N = subalgo;    /* CPU/memory cost parameter.  */
   u32 r;              /* Block size.  */
   u32 p = iterations; /* Parallelization parameter.  */
 
@@ -306,7 +307,7 @@ _gcry_kdf_scrypt (const unsigned char *passwd, size_t passwdlen,
                         1 /* iterations */, p * r128, B);
 
   for (i = 0; !ec && i < p; i++)
-    _scryptROMix (r, &B[i * r128], N, tmp1, tmp2);
+    scrypt_ro_mix (r, &B[i * r128], N, tmp1, tmp2);
 
   for (i = 0; !ec && i < p; i++)
     ec = _gcry_kdf_pkdf2 (passwd, passwdlen, GCRY_MD_SHA256, B, p * r128,
@@ -319,6 +320,3 @@ _gcry_kdf_scrypt (const unsigned char *passwd, size_t passwdlen,
 
   return ec;
 }
-
-
-#endif /* HAVE_U64_TYPEDEF */
index 92e95a0..adff639 100644 (file)
@@ -1,6 +1,6 @@
 /* serpent-armv7-neon.S  -  ARM/NEON assembly implementation of Serpent cipher
  *
- * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
@@ -866,4 +866,259 @@ _gcry_serpent_neon_cbc_dec:
        pop {pc};
 .size _gcry_serpent_neon_cbc_dec,.-_gcry_serpent_neon_cbc_dec;
 
+.align 3
+.globl _gcry_serpent_neon_ocb_enc
+.type _gcry_serpent_neon_ocb_enc,%function;
+_gcry_serpent_neon_ocb_enc:
+       /* input:
+        *      r0  : ctx, CTX
+        *      r1  : dst (8 blocks)
+        *      r2  : src (8 blocks)
+        *      r3  : offset
+        *      sp+0: checksum
+        *      sp+4: L pointers (void *L[8])
+        */
+
+       push {r4-r11, ip, lr};
+       add ip, sp, #(10*4);
+
+       vpush {RA4-RB2};
+
+       ldm ip, {r4, lr};
+
+       vld1.8 {RT0}, [r3];
+       vld1.8 {RT1}, [r4];
+
+       /* Load L pointers */
+       ldm lr!, {r5, r6, r7, r8};
+       ldm lr, {r9, r10, r11, ip};
+
+       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+       /* Checksum_i = Checksum_{i-1} xor P_i  */
+       /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)  */
+
+       vld1.8 {RA0, RA1}, [r2]!;
+       vld1.8 {RA2, RA3}, [r2]!;
+       vld1.8 {RB0, RB1}, [r2]!;
+       vld1.8 {RB2, RB3}, [r2];
+
+#define OCB_INPUT(lreg, vreg) \
+         vld1.8 {RT3}, [lreg]; \
+         veor RT0, RT3; \
+         veor RT1, vreg; \
+         veor vreg, RT0; \
+         vst1.8 {RT0}, [r1]!;
+
+       OCB_INPUT(r5, RA0);
+       OCB_INPUT(r6, RA1);
+       OCB_INPUT(r7, RA2);
+       OCB_INPUT(r8, RA3);
+       OCB_INPUT(r9, RB0);
+       OCB_INPUT(r10, RB1);
+       OCB_INPUT(r11, RB2);
+       OCB_INPUT(ip, RB3);
+#undef OCB_INPUT
+
+       sub r1, r1, #(8*16);
+       vst1.8 {RT0}, [r3];
+       vst1.8 {RT1}, [r4];
+       mov r2, r1;
+
+       bl __serpent_enc_blk8;
+
+       vld1.8 {RT0, RT1}, [r1]!;
+       veor RT0, RA4, RT0;
+       veor RT1, RA1, RT1;
+       vld1.8 {RT2, RT3}, [r1]!;
+       vst1.8 {RT0, RT1}, [r2]!;
+       veor RT2, RA2, RT2;
+       veor RT3, RA0, RT3;
+       vld1.8 {RT0, RT1}, [r1]!;
+       vst1.8 {RT2, RT3}, [r2]!;
+       veor RT0, RB4, RT0;
+       veor RT1, RB1, RT1;
+       vld1.8 {RT2, RT3}, [r1]!;
+       vst1.8 {RT0, RT1}, [r2]!;
+       veor RT2, RB2, RT2;
+       veor RT3, RB0, RT3;
+       vst1.8 {RT2, RT3}, [r2]!;
+
+       vpop {RA4-RB2};
+
+       /* clear the used registers */
+       veor RA3, RA3;
+       veor RB3, RB3;
+
+       pop {r4-r11, ip, pc};
+.size _gcry_serpent_neon_ocb_enc,.-_gcry_serpent_neon_ocb_enc;
+
+.align 3
+.globl _gcry_serpent_neon_ocb_dec
+.type _gcry_serpent_neon_ocb_dec,%function;
+_gcry_serpent_neon_ocb_dec:
+       /* input:
+        *      r0  : ctx, CTX
+        *      r1  : dst (8 blocks)
+        *      r2  : src (8 blocks)
+        *      r3  : offset
+        *      sp+0: checksum
+        *      sp+4: L pointers (void *L[8])
+        */
+
+       push {r4-r11, ip, lr};
+       add ip, sp, #(10*4);
+
+       vpush {RA4-RB2};
+
+       ldm ip, {r4, lr};
+
+       vld1.8 {RT0}, [r3];
+
+       /* Load L pointers */
+       ldm lr!, {r5, r6, r7, r8};
+       ldm lr, {r9, r10, r11, ip};
+
+       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+       /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i)  */
+
+       vld1.8 {RA0, RA1}, [r2]!;
+       vld1.8 {RA2, RA3}, [r2]!;
+       vld1.8 {RB0, RB1}, [r2]!;
+       vld1.8 {RB2, RB3}, [r2];
+
+#define OCB_INPUT(lreg, vreg) \
+         vld1.8 {RT3}, [lreg]; \
+         veor RT0, RT3; \
+         veor vreg, RT0; \
+         vst1.8 {RT0}, [r1]!;
+
+       OCB_INPUT(r5, RA0);
+       OCB_INPUT(r6, RA1);
+       OCB_INPUT(r7, RA2);
+       OCB_INPUT(r8, RA3);
+       OCB_INPUT(r9, RB0);
+       OCB_INPUT(r10, RB1);
+       OCB_INPUT(r11, RB2);
+       OCB_INPUT(ip, RB3);
+#undef OCB_INPUT
+
+       sub r1, r1, #(8*16);
+       vst1.8 {RT0}, [r3];
+       mov r2, r1;
+
+       bl __serpent_dec_blk8;
+
+       /* Checksum_i = Checksum_{i-1} xor P_i  */
+       vld1.8 {RA4}, [r4];
+
+       vld1.8 {RT0, RT1}, [r1]!;
+       veor RA0, RA0, RT0;
+       veor RA1, RA1, RT1;
+       vld1.8 {RT2, RT3}, [r1]!;
+       veor RA4, RA4, RA0;
+       vst1.8 {RA0, RA1}, [r2]!;
+       veor RA4, RA4, RA1;
+       veor RA2, RA2, RT2;
+       veor RA3, RA3, RT3;
+       vld1.8 {RT0, RT1}, [r1]!;
+       veor RA4, RA4, RA2;
+       vst1.8 {RA2, RA3}, [r2]!;
+       veor RA4, RA4, RA3;
+       veor RB0, RB0, RT0;
+       veor RB1, RB1, RT1;
+       vld1.8 {RT2, RT3}, [r1]!;
+       veor RA4, RA4, RB0;
+       vst1.8 {RB0, RB1}, [r2]!;
+       veor RA4, RA4, RB1;
+       veor RB2, RB2, RT2;
+       veor RB3, RB3, RT3;
+       veor RA4, RA4, RB2;
+       vst1.8 {RB2, RB3}, [r2]!;
+
+       veor RA4, RA4, RB3;
+       vst1.8 {RA4}, [r4];
+
+       vpop {RA4-RB2};
+
+       /* clear the used registers */
+       veor RB4, RB4;
+
+       pop {r4-r11, ip, pc};
+.size _gcry_serpent_neon_ocb_dec,.-_gcry_serpent_neon_ocb_dec;
+
+.align 3
+.globl _gcry_serpent_neon_ocb_auth
+.type _gcry_serpent_neon_ocb_auth,%function;
+_gcry_serpent_neon_ocb_auth:
+       /* input:
+        *      r0  : ctx, CTX
+        *      r1  : abuf (8 blocks)
+        *      r2  : offset
+        *      r3  : checksum
+        *      sp+0: L pointers (void *L[8])
+        */
+
+       push {r5-r11, ip, lr};
+       ldr lr, [sp, #(9*4)];
+
+       vpush {RA4-RB2};
+
+       vld1.8 {RT0}, [r2];
+
+       /* Load L pointers */
+       ldm lr!, {r5, r6, r7, r8};
+       ldm lr, {r9, r10, r11, ip};
+
+       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+       /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i)  */
+
+       vld1.8 {RA0, RA1}, [r1]!;
+       vld1.8 {RA2, RA3}, [r1]!;
+       vld1.8 {RB0, RB1}, [r1]!;
+       vld1.8 {RB2, RB3}, [r1];
+
+#define OCB_INPUT(lreg, vreg) \
+         vld1.8 {RT3}, [lreg]; \
+         veor RT0, RT3; \
+         veor vreg, RT0;
+
+       OCB_INPUT(r5, RA0);
+       OCB_INPUT(r6, RA1);
+       OCB_INPUT(r7, RA2);
+       OCB_INPUT(r8, RA3);
+       OCB_INPUT(r9, RB0);
+       OCB_INPUT(r10, RB1);
+       OCB_INPUT(r11, RB2);
+       OCB_INPUT(ip, RB3);
+#undef OCB_INPUT
+
+       vst1.8 {RT0}, [r2];
+
+       bl __serpent_enc_blk8;
+
+       /* Checksum_i = Checksum_{i-1} xor P_i  */
+       vld1.8 {RT0}, [r3];
+
+       veor RA4, RB4;
+       veor RA1, RB1;
+       veor RA2, RB2;
+       veor RA0, RB0;
+
+       veor RA2, RT0;
+       veor RA1, RA4;
+       veor RA0, RA2;
+
+       veor RA0, RA1;
+
+       vst1.8 {RA0}, [r3];
+
+       vpop {RA4-RB2};
+
+       /* clear the used registers */
+       veor RA3, RA3;
+       veor RB3, RB3;
+
+       pop {r5-r11, ip, pc};
+.size _gcry_serpent_neon_ocb_auth,.-_gcry_serpent_neon_ocb_auth;
+
 #endif
index 3177574..2902dab 100644 (file)
@@ -1,6 +1,6 @@
 /* serpent-avx2-amd64.S  -  AVX2 implementation of Serpent cipher
  *
- * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013-2015 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
 
 #ifdef __x86_64
 #include <config.h>
-#if defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && defined(USE_SERPENT) && \
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+    defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && defined(USE_SERPENT) && \
     defined(ENABLE_AVX2_SUPPORT)
 
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
+
 #ifdef __PIC__
 #  define RIP (%rip)
 #else
 .text
 
 .align 8
-.type   __serpent_enc_blk16,@function;
+ELF(.type   __serpent_enc_blk16,@function;)
 __serpent_enc_blk16:
        /* input:
         *      %rdi: ctx, CTX
@@ -489,10 +496,10 @@ __serpent_enc_blk16:
        transpose_4x4(RB4, RB1, RB2, RB0, RB3, RTMP0, RTMP1);
 
        ret;
-.size __serpent_enc_blk16,.-__serpent_enc_blk16;
+ELF(.size __serpent_enc_blk16,.-__serpent_enc_blk16;)
 
 .align 8
-.type   __serpent_dec_blk16,@function;
+ELF(.type   __serpent_dec_blk16,@function;)
 __serpent_dec_blk16:
        /* input:
         *      %rdi: ctx, CTX
@@ -579,7 +586,7 @@ __serpent_dec_blk16:
        transpose_4x4(RB0, RB1, RB2, RB3, RB4, RTMP0, RTMP1);
 
        ret;
-.size __serpent_dec_blk16,.-__serpent_dec_blk16;
+ELF(.size __serpent_dec_blk16,.-__serpent_dec_blk16;)
 
 #define inc_le128(x, minus_one, tmp) \
        vpcmpeqq minus_one, x, tmp; \
@@ -589,7 +596,7 @@ __serpent_dec_blk16:
 
 .align 8
 .globl _gcry_serpent_avx2_ctr_enc
-.type   _gcry_serpent_avx2_ctr_enc,@function;
+ELF(.type   _gcry_serpent_avx2_ctr_enc,@function;)
 _gcry_serpent_avx2_ctr_enc:
        /* input:
         *      %rdi: ctx, CTX
@@ -695,11 +702,11 @@ _gcry_serpent_avx2_ctr_enc:
        vzeroall;
 
        ret
-.size _gcry_serpent_avx2_ctr_enc,.-_gcry_serpent_avx2_ctr_enc;
+ELF(.size _gcry_serpent_avx2_ctr_enc,.-_gcry_serpent_avx2_ctr_enc;)
 
 .align 8
 .globl _gcry_serpent_avx2_cbc_dec
-.type   _gcry_serpent_avx2_cbc_dec,@function;
+ELF(.type   _gcry_serpent_avx2_cbc_dec,@function;)
 _gcry_serpent_avx2_cbc_dec:
        /* input:
         *      %rdi: ctx, CTX
@@ -746,11 +753,11 @@ _gcry_serpent_avx2_cbc_dec:
        vzeroall;
 
        ret
-.size _gcry_serpent_avx2_cbc_dec,.-_gcry_serpent_avx2_cbc_dec;
+ELF(.size _gcry_serpent_avx2_cbc_dec,.-_gcry_serpent_avx2_cbc_dec;)
 
 .align 8
 .globl _gcry_serpent_avx2_cfb_dec
-.type   _gcry_serpent_avx2_cfb_dec,@function;
+ELF(.type   _gcry_serpent_avx2_cfb_dec,@function;)
 _gcry_serpent_avx2_cfb_dec:
        /* input:
         *      %rdi: ctx, CTX
@@ -799,7 +806,312 @@ _gcry_serpent_avx2_cfb_dec:
        vzeroall;
 
        ret
-.size _gcry_serpent_avx2_cfb_dec,.-_gcry_serpent_avx2_cfb_dec;
+ELF(.size _gcry_serpent_avx2_cfb_dec,.-_gcry_serpent_avx2_cfb_dec;)
+
+.align 8
+.globl _gcry_serpent_avx2_ocb_enc
+ELF(.type _gcry_serpent_avx2_ocb_enc,@function;)
+
+_gcry_serpent_avx2_ocb_enc:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (16 blocks)
+        *      %rdx: src (16 blocks)
+        *      %rcx: offset
+        *      %r8 : checksum
+        *      %r9 : L pointers (void *L[16])
+        */
+
+       vzeroupper;
+
+       subq $(4 * 8), %rsp;
+
+       movq %r10, (0 * 8)(%rsp);
+       movq %r11, (1 * 8)(%rsp);
+       movq %r12, (2 * 8)(%rsp);
+       movq %r13, (3 * 8)(%rsp);
+
+       vmovdqu (%rcx), RTMP0x;
+       vmovdqu (%r8), RTMP1x;
+
+       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+       /* Checksum_i = Checksum_{i-1} xor P_i  */
+       /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)  */
+
+#define OCB_INPUT(n, l0reg, l1reg, yreg) \
+         vmovdqu (n * 32)(%rdx), yreg; \
+         vpxor (l0reg), RTMP0x, RNOTx; \
+         vpxor (l1reg), RNOTx, RTMP0x; \
+         vinserti128 $1, RTMP0x, RNOT, RNOT; \
+         vpxor yreg, RTMP1, RTMP1; \
+         vpxor yreg, RNOT, yreg; \
+         vmovdqu RNOT, (n * 32)(%rsi);
+
+       movq (0 * 8)(%r9), %r10;
+       movq (1 * 8)(%r9), %r11;
+       movq (2 * 8)(%r9), %r12;
+       movq (3 * 8)(%r9), %r13;
+       OCB_INPUT(0, %r10, %r11, RA0);
+       OCB_INPUT(1, %r12, %r13, RA1);
+       movq (4 * 8)(%r9), %r10;
+       movq (5 * 8)(%r9), %r11;
+       movq (6 * 8)(%r9), %r12;
+       movq (7 * 8)(%r9), %r13;
+       OCB_INPUT(2, %r10, %r11, RA2);
+       OCB_INPUT(3, %r12, %r13, RA3);
+       movq (8 * 8)(%r9), %r10;
+       movq (9 * 8)(%r9), %r11;
+       movq (10 * 8)(%r9), %r12;
+       movq (11 * 8)(%r9), %r13;
+       OCB_INPUT(4, %r10, %r11, RB0);
+       OCB_INPUT(5, %r12, %r13, RB1);
+       movq (12 * 8)(%r9), %r10;
+       movq (13 * 8)(%r9), %r11;
+       movq (14 * 8)(%r9), %r12;
+       movq (15 * 8)(%r9), %r13;
+       OCB_INPUT(6, %r10, %r11, RB2);
+       OCB_INPUT(7, %r12, %r13, RB3);
+#undef OCB_INPUT
+
+       vextracti128 $1, RTMP1, RNOTx;
+       vmovdqu RTMP0x, (%rcx);
+       vpxor RNOTx, RTMP1x, RTMP1x;
+       vmovdqu RTMP1x, (%r8);
+
+       movq (0 * 8)(%rsp), %r10;
+       movq (1 * 8)(%rsp), %r11;
+       movq (2 * 8)(%rsp), %r12;
+       movq (3 * 8)(%rsp), %r13;
+
+       call __serpent_enc_blk16;
+
+       addq $(4 * 8), %rsp;
+
+       vpxor (0 * 32)(%rsi), RA4, RA4;
+       vpxor (1 * 32)(%rsi), RA1, RA1;
+       vpxor (2 * 32)(%rsi), RA2, RA2;
+       vpxor (3 * 32)(%rsi), RA0, RA0;
+       vpxor (4 * 32)(%rsi), RB4, RB4;
+       vpxor (5 * 32)(%rsi), RB1, RB1;
+       vpxor (6 * 32)(%rsi), RB2, RB2;
+       vpxor (7 * 32)(%rsi), RB0, RB0;
+
+       vmovdqu RA4, (0 * 32)(%rsi);
+       vmovdqu RA1, (1 * 32)(%rsi);
+       vmovdqu RA2, (2 * 32)(%rsi);
+       vmovdqu RA0, (3 * 32)(%rsi);
+       vmovdqu RB4, (4 * 32)(%rsi);
+       vmovdqu RB1, (5 * 32)(%rsi);
+       vmovdqu RB2, (6 * 32)(%rsi);
+       vmovdqu RB0, (7 * 32)(%rsi);
+
+       vzeroall;
+
+       ret;
+ELF(.size _gcry_serpent_avx2_ocb_enc,.-_gcry_serpent_avx2_ocb_enc;)
+
+.align 8
+.globl _gcry_serpent_avx2_ocb_dec
+ELF(.type _gcry_serpent_avx2_ocb_dec,@function;)
+
+_gcry_serpent_avx2_ocb_dec:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (16 blocks)
+        *      %rdx: src (16 blocks)
+        *      %rcx: offset
+        *      %r8 : checksum
+        *      %r9 : L pointers (void *L[16])
+        */
+
+       vzeroupper;
+
+       subq $(4 * 8), %rsp;
+
+       movq %r10, (0 * 8)(%rsp);
+       movq %r11, (1 * 8)(%rsp);
+       movq %r12, (2 * 8)(%rsp);
+       movq %r13, (3 * 8)(%rsp);
+
+       vmovdqu (%rcx), RTMP0x;
+
+       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+       /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)  */
+
+#define OCB_INPUT(n, l0reg, l1reg, yreg) \
+         vmovdqu (n * 32)(%rdx), yreg; \
+         vpxor (l0reg), RTMP0x, RNOTx; \
+         vpxor (l1reg), RNOTx, RTMP0x; \
+         vinserti128 $1, RTMP0x, RNOT, RNOT; \
+         vpxor yreg, RNOT, yreg; \
+         vmovdqu RNOT, (n * 32)(%rsi);
+
+       movq (0 * 8)(%r9), %r10;
+       movq (1 * 8)(%r9), %r11;
+       movq (2 * 8)(%r9), %r12;
+       movq (3 * 8)(%r9), %r13;
+       OCB_INPUT(0, %r10, %r11, RA0);
+       OCB_INPUT(1, %r12, %r13, RA1);
+       movq (4 * 8)(%r9), %r10;
+       movq (5 * 8)(%r9), %r11;
+       movq (6 * 8)(%r9), %r12;
+       movq (7 * 8)(%r9), %r13;
+       OCB_INPUT(2, %r10, %r11, RA2);
+       OCB_INPUT(3, %r12, %r13, RA3);
+       movq (8 * 8)(%r9), %r10;
+       movq (9 * 8)(%r9), %r11;
+       movq (10 * 8)(%r9), %r12;
+       movq (11 * 8)(%r9), %r13;
+       OCB_INPUT(4, %r10, %r11, RB0);
+       OCB_INPUT(5, %r12, %r13, RB1);
+       movq (12 * 8)(%r9), %r10;
+       movq (13 * 8)(%r9), %r11;
+       movq (14 * 8)(%r9), %r12;
+       movq (15 * 8)(%r9), %r13;
+       OCB_INPUT(6, %r10, %r11, RB2);
+       OCB_INPUT(7, %r12, %r13, RB3);
+#undef OCB_INPUT
+
+       vmovdqu RTMP0x, (%rcx);
+
+       movq (0 * 8)(%rsp), %r10;
+       movq (1 * 8)(%rsp), %r11;
+       movq (2 * 8)(%rsp), %r12;
+       movq (3 * 8)(%rsp), %r13;
+
+       call __serpent_dec_blk16;
+
+       addq $(4 * 8), %rsp;
+
+       vmovdqu (%r8), RTMP1x;
+
+       vpxor (0 * 32)(%rsi), RA0, RA0;
+       vpxor (1 * 32)(%rsi), RA1, RA1;
+       vpxor (2 * 32)(%rsi), RA2, RA2;
+       vpxor (3 * 32)(%rsi), RA3, RA3;
+       vpxor (4 * 32)(%rsi), RB0, RB0;
+       vpxor (5 * 32)(%rsi), RB1, RB1;
+       vpxor (6 * 32)(%rsi), RB2, RB2;
+       vpxor (7 * 32)(%rsi), RB3, RB3;
+
+       /* Checksum_i = Checksum_{i-1} xor P_i  */
+
+       vmovdqu RA0, (0 * 32)(%rsi);
+       vpxor RA0, RTMP1, RTMP1;
+       vmovdqu RA1, (1 * 32)(%rsi);
+       vpxor RA1, RTMP1, RTMP1;
+       vmovdqu RA2, (2 * 32)(%rsi);
+       vpxor RA2, RTMP1, RTMP1;
+       vmovdqu RA3, (3 * 32)(%rsi);
+       vpxor RA3, RTMP1, RTMP1;
+       vmovdqu RB0, (4 * 32)(%rsi);
+       vpxor RB0, RTMP1, RTMP1;
+       vmovdqu RB1, (5 * 32)(%rsi);
+       vpxor RB1, RTMP1, RTMP1;
+       vmovdqu RB2, (6 * 32)(%rsi);
+       vpxor RB2, RTMP1, RTMP1;
+       vmovdqu RB3, (7 * 32)(%rsi);
+       vpxor RB3, RTMP1, RTMP1;
+
+       vextracti128 $1, RTMP1, RNOTx;
+       vpxor RNOTx, RTMP1x, RTMP1x;
+       vmovdqu RTMP1x, (%r8);
+
+       vzeroall;
+
+       ret;
+ELF(.size _gcry_serpent_avx2_ocb_dec,.-_gcry_serpent_avx2_ocb_dec;)
+
+.align 8
+.globl _gcry_serpent_avx2_ocb_auth
+ELF(.type _gcry_serpent_avx2_ocb_auth,@function;)
+
+_gcry_serpent_avx2_ocb_auth:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: abuf (16 blocks)
+        *      %rdx: offset
+        *      %rcx: checksum
+        *      %r8 : L pointers (void *L[16])
+        */
+
+       vzeroupper;
+
+       subq $(4 * 8), %rsp;
+
+       movq %r10, (0 * 8)(%rsp);
+       movq %r11, (1 * 8)(%rsp);
+       movq %r12, (2 * 8)(%rsp);
+       movq %r13, (3 * 8)(%rsp);
+
+       vmovdqu (%rdx), RTMP0x;
+
+       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+       /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i)  */
+
+#define OCB_INPUT(n, l0reg, l1reg, yreg) \
+         vmovdqu (n * 32)(%rsi), yreg; \
+         vpxor (l0reg), RTMP0x, RNOTx; \
+         vpxor (l1reg), RNOTx, RTMP0x; \
+         vinserti128 $1, RTMP0x, RNOT, RNOT; \
+         vpxor yreg, RNOT, yreg;
+
+       movq (0 * 8)(%r8), %r10;
+       movq (1 * 8)(%r8), %r11;
+       movq (2 * 8)(%r8), %r12;
+       movq (3 * 8)(%r8), %r13;
+       OCB_INPUT(0, %r10, %r11, RA0);
+       OCB_INPUT(1, %r12, %r13, RA1);
+       movq (4 * 8)(%r8), %r10;
+       movq (5 * 8)(%r8), %r11;
+       movq (6 * 8)(%r8), %r12;
+       movq (7 * 8)(%r8), %r13;
+       OCB_INPUT(2, %r10, %r11, RA2);
+       OCB_INPUT(3, %r12, %r13, RA3);
+       movq (8 * 8)(%r8), %r10;
+       movq (9 * 8)(%r8), %r11;
+       movq (10 * 8)(%r8), %r12;
+       movq (11 * 8)(%r8), %r13;
+       OCB_INPUT(4, %r10, %r11, RB0);
+       OCB_INPUT(5, %r12, %r13, RB1);
+       movq (12 * 8)(%r8), %r10;
+       movq (13 * 8)(%r8), %r11;
+       movq (14 * 8)(%r8), %r12;
+       movq (15 * 8)(%r8), %r13;
+       OCB_INPUT(6, %r10, %r11, RB2);
+       OCB_INPUT(7, %r12, %r13, RB3);
+#undef OCB_INPUT
+
+       vmovdqu RTMP0x, (%rdx);
+
+       movq (0 * 8)(%rsp), %r10;
+       movq (1 * 8)(%rsp), %r11;
+       movq (2 * 8)(%rsp), %r12;
+       movq (3 * 8)(%rsp), %r13;
+
+       call __serpent_enc_blk16;
+
+       addq $(4 * 8), %rsp;
+
+       vpxor RA4, RB4, RA4;
+       vpxor RA1, RB1, RA1;
+       vpxor RA2, RB2, RA2;
+       vpxor RA0, RB0, RA0;
+
+       vpxor RA4, RA1, RA1;
+       vpxor RA2, RA0, RA0;
+
+       vpxor RA1, RA0, RTMP1;
+
+       vextracti128 $1, RTMP1, RNOTx;
+       vpxor (%rcx), RTMP1x, RTMP1x;
+       vpxor RNOTx, RTMP1x, RTMP1x;
+       vmovdqu RTMP1x, (%rcx);
+
+       vzeroall;
+
+       ret;
+ELF(.size _gcry_serpent_avx2_ocb_auth,.-_gcry_serpent_avx2_ocb_auth;)
 
 .data
 .align 16
index f2be236..b149af2 100644 (file)
@@ -1,6 +1,6 @@
 /* serpent-sse2-amd64.S  -  SSE2 implementation of Serpent cipher
  *
- * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013-2015 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
 
 #ifdef __x86_64
 #include <config.h>
-#if defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && defined(USE_SERPENT)
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+    defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && defined(USE_SERPENT)
+
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
 
 #ifdef __PIC__
 #  define RIP (%rip)
 .text
 
 .align 8
-.type   __serpent_enc_blk8,@function;
+ELF(.type   __serpent_enc_blk8,@function;)
 __serpent_enc_blk8:
        /* input:
         *      %rdi: ctx, CTX
@@ -512,10 +519,10 @@ __serpent_enc_blk8:
        transpose_4x4(RB4, RB1, RB2, RB0, RB3, RTMP0, RTMP1);
 
        ret;
-.size __serpent_enc_blk8,.-__serpent_enc_blk8;
+ELF(.size __serpent_enc_blk8,.-__serpent_enc_blk8;)
 
 .align 8
-.type   __serpent_dec_blk8,@function;
+ELF(.type   __serpent_dec_blk8,@function;)
 __serpent_dec_blk8:
        /* input:
         *      %rdi: ctx, CTX
@@ -602,11 +609,11 @@ __serpent_dec_blk8:
        transpose_4x4(RB0, RB1, RB2, RB3, RB4, RTMP0, RTMP1);
 
        ret;
-.size __serpent_dec_blk8,.-__serpent_dec_blk8;
+ELF(.size __serpent_dec_blk8,.-__serpent_dec_blk8;)
 
 .align 8
 .globl _gcry_serpent_sse2_ctr_enc
-.type   _gcry_serpent_sse2_ctr_enc,@function;
+ELF(.type   _gcry_serpent_sse2_ctr_enc,@function;)
 _gcry_serpent_sse2_ctr_enc:
        /* input:
         *      %rdi: ctx, CTX
@@ -732,11 +739,11 @@ _gcry_serpent_sse2_ctr_enc:
        pxor RNOT, RNOT;
 
        ret
-.size _gcry_serpent_sse2_ctr_enc,.-_gcry_serpent_sse2_ctr_enc;
+ELF(.size _gcry_serpent_sse2_ctr_enc,.-_gcry_serpent_sse2_ctr_enc;)
 
 .align 8
 .globl _gcry_serpent_sse2_cbc_dec
-.type   _gcry_serpent_sse2_cbc_dec,@function;
+ELF(.type   _gcry_serpent_sse2_cbc_dec,@function;)
 _gcry_serpent_sse2_cbc_dec:
        /* input:
         *      %rdi: ctx, CTX
@@ -793,11 +800,11 @@ _gcry_serpent_sse2_cbc_dec:
        pxor RNOT, RNOT;
 
        ret
-.size _gcry_serpent_sse2_cbc_dec,.-_gcry_serpent_sse2_cbc_dec;
+ELF(.size _gcry_serpent_sse2_cbc_dec,.-_gcry_serpent_sse2_cbc_dec;)
 
 .align 8
 .globl _gcry_serpent_sse2_cfb_dec
-.type   _gcry_serpent_sse2_cfb_dec,@function;
+ELF(.type   _gcry_serpent_sse2_cfb_dec,@function;)
 _gcry_serpent_sse2_cfb_dec:
        /* input:
         *      %rdi: ctx, CTX
@@ -857,7 +864,312 @@ _gcry_serpent_sse2_cfb_dec:
        pxor RNOT, RNOT;
 
        ret
-.size _gcry_serpent_sse2_cfb_dec,.-_gcry_serpent_sse2_cfb_dec;
+ELF(.size _gcry_serpent_sse2_cfb_dec,.-_gcry_serpent_sse2_cfb_dec;)
+
+.align 8
+.globl _gcry_serpent_sse2_ocb_enc
+ELF(.type _gcry_serpent_sse2_ocb_enc,@function;)
+
+_gcry_serpent_sse2_ocb_enc:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (8 blocks)
+        *      %rdx: src (8 blocks)
+        *      %rcx: offset
+        *      %r8 : checksum
+        *      %r9 : L pointers (void *L[8])
+        */
+
+       subq $(4 * 8), %rsp;
+
+       movq %r10, (0 * 8)(%rsp);
+       movq %r11, (1 * 8)(%rsp);
+       movq %r12, (2 * 8)(%rsp);
+       movq %r13, (3 * 8)(%rsp);
+
+       movdqu (%rcx), RTMP0;
+       movdqu (%r8), RTMP1;
+
+       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+       /* Checksum_i = Checksum_{i-1} xor P_i  */
+       /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)  */
+
+#define OCB_INPUT(n, lreg, xreg) \
+         movdqu (n * 16)(%rdx), xreg; \
+         movdqu (lreg), RNOT; \
+         pxor RNOT, RTMP0; \
+         pxor xreg, RTMP1; \
+         pxor RTMP0, xreg; \
+         movdqu RTMP0, (n * 16)(%rsi);
+       movq (0 * 8)(%r9), %r10;
+       movq (1 * 8)(%r9), %r11;
+       movq (2 * 8)(%r9), %r12;
+       movq (3 * 8)(%r9), %r13;
+       OCB_INPUT(0, %r10, RA0);
+       OCB_INPUT(1, %r11, RA1);
+       OCB_INPUT(2, %r12, RA2);
+       OCB_INPUT(3, %r13, RA3);
+       movq (4 * 8)(%r9), %r10;
+       movq (5 * 8)(%r9), %r11;
+       movq (6 * 8)(%r9), %r12;
+       movq (7 * 8)(%r9), %r13;
+       OCB_INPUT(4, %r10, RB0);
+       OCB_INPUT(5, %r11, RB1);
+       OCB_INPUT(6, %r12, RB2);
+       OCB_INPUT(7, %r13, RB3);
+#undef OCB_INPUT
+
+       movdqu RTMP0, (%rcx);
+       movdqu RTMP1, (%r8);
+
+       movq (0 * 8)(%rsp), %r10;
+       movq (1 * 8)(%rsp), %r11;
+       movq (2 * 8)(%rsp), %r12;
+       movq (3 * 8)(%rsp), %r13;
+
+       call __serpent_enc_blk8;
+
+       addq $(4 * 8), %rsp;
+
+       pxor_u((0 * 16)(%rsi), RA4, RTMP0);
+       pxor_u((1 * 16)(%rsi), RA1, RTMP0);
+       pxor_u((2 * 16)(%rsi), RA2, RTMP0);
+       pxor_u((3 * 16)(%rsi), RA0, RTMP0);
+       pxor_u((4 * 16)(%rsi), RB4, RTMP0);
+       pxor_u((5 * 16)(%rsi), RB1, RTMP0);
+       pxor_u((6 * 16)(%rsi), RB2, RTMP0);
+       pxor_u((7 * 16)(%rsi), RB0, RTMP0);
+
+       movdqu RA4, (0 * 16)(%rsi);
+       movdqu RA1, (1 * 16)(%rsi);
+       movdqu RA2, (2 * 16)(%rsi);
+       movdqu RA0, (3 * 16)(%rsi);
+       movdqu RB4, (4 * 16)(%rsi);
+       movdqu RB1, (5 * 16)(%rsi);
+       movdqu RB2, (6 * 16)(%rsi);
+       movdqu RB0, (7 * 16)(%rsi);
+
+       /* clear the used registers */
+       pxor RA0, RA0;
+       pxor RA1, RA1;
+       pxor RA2, RA2;
+       pxor RA3, RA3;
+       pxor RA4, RA4;
+       pxor RB0, RB0;
+       pxor RB1, RB1;
+       pxor RB2, RB2;
+       pxor RB3, RB3;
+       pxor RB4, RB4;
+       pxor RTMP0, RTMP0;
+       pxor RTMP1, RTMP1;
+       pxor RTMP2, RTMP2;
+       pxor RNOT, RNOT;
+
+       ret;
+ELF(.size _gcry_serpent_sse2_ocb_enc,.-_gcry_serpent_sse2_ocb_enc;)
+
+.align 8
+.globl _gcry_serpent_sse2_ocb_dec
+ELF(.type _gcry_serpent_sse2_ocb_dec,@function;)
+
+_gcry_serpent_sse2_ocb_dec:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (8 blocks)
+        *      %rdx: src (8 blocks)
+        *      %rcx: offset
+        *      %r8 : checksum
+        *      %r9 : L pointers (void *L[8])
+        */
+
+       subq $(4 * 8), %rsp;
+
+       movq %r10, (0 * 8)(%rsp);
+       movq %r11, (1 * 8)(%rsp);
+       movq %r12, (2 * 8)(%rsp);
+       movq %r13, (3 * 8)(%rsp);
+
+       movdqu (%rcx), RTMP0;
+
+       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+       /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i)  */
+
+#define OCB_INPUT(n, lreg, xreg) \
+         movdqu (n * 16)(%rdx), xreg; \
+         movdqu (lreg), RNOT; \
+         pxor RNOT, RTMP0; \
+         pxor RTMP0, xreg; \
+         movdqu RTMP0, (n * 16)(%rsi);
+       movq (0 * 8)(%r9), %r10;
+       movq (1 * 8)(%r9), %r11;
+       movq (2 * 8)(%r9), %r12;
+       movq (3 * 8)(%r9), %r13;
+       OCB_INPUT(0, %r10, RA0);
+       OCB_INPUT(1, %r11, RA1);
+       OCB_INPUT(2, %r12, RA2);
+       OCB_INPUT(3, %r13, RA3);
+       movq (4 * 8)(%r9), %r10;
+       movq (5 * 8)(%r9), %r11;
+       movq (6 * 8)(%r9), %r12;
+       movq (7 * 8)(%r9), %r13;
+       OCB_INPUT(4, %r10, RB0);
+       OCB_INPUT(5, %r11, RB1);
+       OCB_INPUT(6, %r12, RB2);
+       OCB_INPUT(7, %r13, RB3);
+#undef OCB_INPUT
+
+       movdqu RTMP0, (%rcx);
+
+       movq (0 * 8)(%rsp), %r10;
+       movq (1 * 8)(%rsp), %r11;
+       movq (2 * 8)(%rsp), %r12;
+       movq (3 * 8)(%rsp), %r13;
+
+       call __serpent_dec_blk8;
+
+       addq $(4 * 8), %rsp;
+
+       movdqu (%r8), RTMP0;
+
+       pxor_u((0 * 16)(%rsi), RA0, RTMP1);
+       pxor_u((1 * 16)(%rsi), RA1, RTMP1);
+       pxor_u((2 * 16)(%rsi), RA2, RTMP1);
+       pxor_u((3 * 16)(%rsi), RA3, RTMP1);
+       pxor_u((4 * 16)(%rsi), RB0, RTMP1);
+       pxor_u((5 * 16)(%rsi), RB1, RTMP1);
+       pxor_u((6 * 16)(%rsi), RB2, RTMP1);
+       pxor_u((7 * 16)(%rsi), RB3, RTMP1);
+
+       /* Checksum_i = Checksum_{i-1} xor P_i  */
+
+       movdqu RA0, (0 * 16)(%rsi);
+       pxor RA0, RTMP0;
+       movdqu RA1, (1 * 16)(%rsi);
+       pxor RA1, RTMP0;
+       movdqu RA2, (2 * 16)(%rsi);
+       pxor RA2, RTMP0;
+       movdqu RA3, (3 * 16)(%rsi);
+       pxor RA3, RTMP0;
+       movdqu RB0, (4 * 16)(%rsi);
+       pxor RB0, RTMP0;
+       movdqu RB1, (5 * 16)(%rsi);
+       pxor RB1, RTMP0;
+       movdqu RB2, (6 * 16)(%rsi);
+       pxor RB2, RTMP0;
+       movdqu RB3, (7 * 16)(%rsi);
+       pxor RB3, RTMP0;
+
+       movdqu RTMP0, (%r8);
+
+       /* clear the used registers */
+       pxor RA0, RA0;
+       pxor RA1, RA1;
+       pxor RA2, RA2;
+       pxor RA3, RA3;
+       pxor RA4, RA4;
+       pxor RB0, RB0;
+       pxor RB1, RB1;
+       pxor RB2, RB2;
+       pxor RB3, RB3;
+       pxor RB4, RB4;
+       pxor RTMP0, RTMP0;
+       pxor RTMP1, RTMP1;
+       pxor RTMP2, RTMP2;
+       pxor RNOT, RNOT;
+
+       ret;
+ELF(.size _gcry_serpent_sse2_ocb_dec,.-_gcry_serpent_sse2_ocb_dec;)
+
+.align 8
+.globl _gcry_serpent_sse2_ocb_auth
+ELF(.type _gcry_serpent_sse2_ocb_auth,@function;)
+
+_gcry_serpent_sse2_ocb_auth:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: abuf (8 blocks)
+        *      %rdx: offset
+        *      %rcx: checksum
+        *      %r8 : L pointers (void *L[8])
+        */
+
+       subq $(4 * 8), %rsp;
+
+       movq %r10, (0 * 8)(%rsp);
+       movq %r11, (1 * 8)(%rsp);
+       movq %r12, (2 * 8)(%rsp);
+       movq %r13, (3 * 8)(%rsp);
+
+       movdqu (%rdx), RTMP0;
+
+       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+       /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i)  */
+
+#define OCB_INPUT(n, lreg, xreg) \
+         movdqu (n * 16)(%rsi), xreg; \
+         movdqu (lreg), RNOT; \
+         pxor RNOT, RTMP0; \
+         pxor RTMP0, xreg;
+       movq (0 * 8)(%r8), %r10;
+       movq (1 * 8)(%r8), %r11;
+       movq (2 * 8)(%r8), %r12;
+       movq (3 * 8)(%r8), %r13;
+       OCB_INPUT(0, %r10, RA0);
+       OCB_INPUT(1, %r11, RA1);
+       OCB_INPUT(2, %r12, RA2);
+       OCB_INPUT(3, %r13, RA3);
+       movq (4 * 8)(%r8), %r10;
+       movq (5 * 8)(%r8), %r11;
+       movq (6 * 8)(%r8), %r12;
+       movq (7 * 8)(%r8), %r13;
+       OCB_INPUT(4, %r10, RB0);
+       OCB_INPUT(5, %r11, RB1);
+       OCB_INPUT(6, %r12, RB2);
+       OCB_INPUT(7, %r13, RB3);
+#undef OCB_INPUT
+
+       movdqu RTMP0, (%rdx);
+
+       movq (0 * 8)(%rsp), %r10;
+       movq (1 * 8)(%rsp), %r11;
+       movq (2 * 8)(%rsp), %r12;
+       movq (3 * 8)(%rsp), %r13;
+
+       call __serpent_enc_blk8;
+
+       addq $(4 * 8), %rsp;
+
+       movdqu (%rcx), RTMP0;
+       pxor RB4, RA4;
+       pxor RB1, RA1;
+       pxor RB2, RA2;
+       pxor RB0, RA0;
+
+       pxor RTMP0, RA2;
+       pxor RA4, RA1;
+       pxor RA2, RA0;
+
+       pxor RA1, RA0;
+       movdqu RA0, (%rcx);
+
+       /* clear the used registers */
+       pxor RA0, RA0;
+       pxor RA1, RA1;
+       pxor RA2, RA2;
+       pxor RA3, RA3;
+       pxor RA4, RA4;
+       pxor RB0, RB0;
+       pxor RB1, RB1;
+       pxor RB2, RB2;
+       pxor RB3, RB3;
+       pxor RB4, RB4;
+       pxor RTMP0, RTMP0;
+       pxor RTMP1, RTMP1;
+       pxor RTMP2, RTMP2;
+       pxor RNOT, RNOT;
+
+       ret;
+ELF(.size _gcry_serpent_sse2_ocb_auth,.-_gcry_serpent_sse2_ocb_auth;)
 
 #endif /*defined(USE_SERPENT)*/
 #endif /*__x86_64*/
index 0be49da..ef19d3b 100644 (file)
 #include "cipher.h"
 #include "bithelp.h"
 #include "bufhelp.h"
+#include "cipher-internal.h"
 #include "cipher-selftest.h"
 
 
 /* USE_SSE2 indicates whether to compile with AMD64 SSE2 code. */
 #undef USE_SSE2
-#if defined(__x86_64__) && defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS)
+#if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+    defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
 # define USE_SSE2 1
 #endif
 
 /* USE_AVX2 indicates whether to compile with AMD64 AVX2 code. */
 #undef USE_AVX2
-#if defined(__x86_64__) && defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS)
+#if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+    defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
 # if defined(ENABLE_AVX2_SUPPORT)
 #  define USE_AVX2 1
 # endif
@@ -86,6 +89,18 @@ typedef struct serpent_context
 } serpent_context_t;
 
 
+/* Assembly implementations use SystemV ABI, ABI conversion and additional
+ * stack to store XMM6-XMM15 needed on Win64. */
+#undef ASM_FUNC_ABI
+#if defined(USE_SSE2) || defined(USE_AVX2)
+# ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+#  define ASM_FUNC_ABI __attribute__((sysv_abi))
+# else
+#  define ASM_FUNC_ABI
+# endif
+#endif
+
+
 #ifdef USE_SSE2
 /* Assembler implementations of Serpent using SSE2.  Process 8 block in
    parallel.
@@ -93,37 +108,77 @@ typedef struct serpent_context
 extern void _gcry_serpent_sse2_ctr_enc(serpent_context_t *ctx,
                                       unsigned char *out,
                                       const unsigned char *in,
-                                      unsigned char *ctr);
+                                      unsigned char *ctr) ASM_FUNC_ABI;
 
 extern void _gcry_serpent_sse2_cbc_dec(serpent_context_t *ctx,
                                       unsigned char *out,
                                       const unsigned char *in,
-                                      unsigned char *iv);
+                                      unsigned char *iv) ASM_FUNC_ABI;
 
 extern void _gcry_serpent_sse2_cfb_dec(serpent_context_t *ctx,
                                       unsigned char *out,
                                       const unsigned char *in,
-                                      unsigned char *iv);
+                                      unsigned char *iv) ASM_FUNC_ABI;
+
+extern void _gcry_serpent_sse2_ocb_enc(serpent_context_t *ctx,
+                                      unsigned char *out,
+                                      const unsigned char *in,
+                                      unsigned char *offset,
+                                      unsigned char *checksum,
+                                      const u64 Ls[8]) ASM_FUNC_ABI;
+
+extern void _gcry_serpent_sse2_ocb_dec(serpent_context_t *ctx,
+                                      unsigned char *out,
+                                      const unsigned char *in,
+                                      unsigned char *offset,
+                                      unsigned char *checksum,
+                                      const u64 Ls[8]) ASM_FUNC_ABI;
+
+extern void _gcry_serpent_sse2_ocb_auth(serpent_context_t *ctx,
+                                       const unsigned char *abuf,
+                                       unsigned char *offset,
+                                       unsigned char *checksum,
+                                       const u64 Ls[8]) ASM_FUNC_ABI;
 #endif
 
 #ifdef USE_AVX2
-/* Assembler implementations of Serpent using SSE2.  Process 16 block in
+/* Assembler implementations of Serpent using AVX2.  Process 16 block in
    parallel.
  */
 extern void _gcry_serpent_avx2_ctr_enc(serpent_context_t *ctx,
                                       unsigned char *out,
                                       const unsigned char *in,
-                                      unsigned char *ctr);
+                                      unsigned char *ctr) ASM_FUNC_ABI;
 
 extern void _gcry_serpent_avx2_cbc_dec(serpent_context_t *ctx,
                                       unsigned char *out,
                                       const unsigned char *in,
-                                      unsigned char *iv);
+                                      unsigned char *iv) ASM_FUNC_ABI;
 
 extern void _gcry_serpent_avx2_cfb_dec(serpent_context_t *ctx,
                                       unsigned char *out,
                                       const unsigned char *in,
-                                      unsigned char *iv);
+                                      unsigned char *iv) ASM_FUNC_ABI;
+
+extern void _gcry_serpent_avx2_ocb_enc(serpent_context_t *ctx,
+                                      unsigned char *out,
+                                      const unsigned char *in,
+                                      unsigned char *offset,
+                                      unsigned char *checksum,
+                                      const u64 Ls[16]) ASM_FUNC_ABI;
+
+extern void _gcry_serpent_avx2_ocb_dec(serpent_context_t *ctx,
+                                      unsigned char *out,
+                                      const unsigned char *in,
+                                      unsigned char *offset,
+                                      unsigned char *checksum,
+                                      const u64 Ls[16]) ASM_FUNC_ABI;
+
+extern void _gcry_serpent_avx2_ocb_auth(serpent_context_t *ctx,
+                                       const unsigned char *abuf,
+                                       unsigned char *offset,
+                                       unsigned char *checksum,
+                                       const u64 Ls[16]) ASM_FUNC_ABI;
 #endif
 
 #ifdef USE_NEON
@@ -144,6 +199,26 @@ extern void _gcry_serpent_neon_cfb_dec(serpent_context_t *ctx,
                                       unsigned char *out,
                                       const unsigned char *in,
                                       unsigned char *iv);
+
+extern void _gcry_serpent_neon_ocb_enc(serpent_context_t *ctx,
+                                      unsigned char *out,
+                                      const unsigned char *in,
+                                      unsigned char *offset,
+                                      unsigned char *checksum,
+                                      const void *Ls[8]);
+
+extern void _gcry_serpent_neon_ocb_dec(serpent_context_t *ctx,
+                                      unsigned char *out,
+                                      const unsigned char *in,
+                                      unsigned char *offset,
+                                      unsigned char *checksum,
+                                      const void *Ls[8]);
+
+extern void _gcry_serpent_neon_ocb_auth(serpent_context_t *ctx,
+                                       const unsigned char *abuf,
+                                       unsigned char *offset,
+                                       unsigned char *checksum,
+                                       const void *Ls[8]);
 #endif
 
 
@@ -1151,6 +1226,374 @@ _gcry_serpent_cfb_dec(void *context, unsigned char *iv,
   _gcry_burn_stack(burn_stack_depth);
 }
 
+/* Bulk encryption/decryption of complete blocks in OCB mode. */
+size_t
+_gcry_serpent_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
+                       const void *inbuf_arg, size_t nblocks, int encrypt)
+{
+#if defined(USE_AVX2) || defined(USE_SSE2) || defined(USE_NEON)
+  serpent_context_t *ctx = (void *)&c->context.c;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  unsigned char l_tmp[sizeof(serpent_block_t)];
+  int burn_stack_depth = 2 * sizeof (serpent_block_t);
+  u64 blkn = c->u_mode.ocb.data_nblocks;
+#else
+  (void)c;
+  (void)outbuf_arg;
+  (void)inbuf_arg;
+  (void)encrypt;
+#endif
+
+#ifdef USE_AVX2
+  if (ctx->use_avx2)
+    {
+      int did_use_avx2 = 0;
+      u64 Ls[16];
+      unsigned int n = 16 - (blkn % 16);
+      u64 *l;
+      int i;
+
+      if (nblocks >= 16)
+       {
+         for (i = 0; i < 16; i += 8)
+           {
+             /* Use u64 to store pointers for x32 support (assembly function
+              * assumes 64-bit pointers). */
+             Ls[(i + 0 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+             Ls[(i + 1 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+             Ls[(i + 2 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+             Ls[(i + 3 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
+             Ls[(i + 4 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+             Ls[(i + 5 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+             Ls[(i + 6 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+           }
+
+         Ls[(7 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
+         l = &Ls[(15 + n) % 16];
+
+         /* Process data in 16 block chunks. */
+         while (nblocks >= 16)
+           {
+             /* l_tmp will be used only every 65536-th block. */
+             blkn += 16;
+             *l = (uintptr_t)(void *)ocb_get_l(c, l_tmp, blkn - blkn % 16);
+
+             if (encrypt)
+               _gcry_serpent_avx2_ocb_enc(ctx, outbuf, inbuf, c->u_iv.iv,
+                                         c->u_ctr.ctr, Ls);
+             else
+               _gcry_serpent_avx2_ocb_dec(ctx, outbuf, inbuf, c->u_iv.iv,
+                                         c->u_ctr.ctr, Ls);
+
+             nblocks -= 16;
+             outbuf += 16 * sizeof(serpent_block_t);
+             inbuf  += 16 * sizeof(serpent_block_t);
+             did_use_avx2 = 1;
+           }
+       }
+
+      if (did_use_avx2)
+       {
+         /* serpent-avx2 assembly code does not use stack */
+         if (nblocks == 0)
+           burn_stack_depth = 0;
+       }
+
+      /* Use generic code to handle smaller chunks... */
+    }
+#endif
+
+#ifdef USE_SSE2
+  {
+    int did_use_sse2 = 0;
+    u64 Ls[8];
+    unsigned int n = 8 - (blkn % 8);
+    u64 *l;
+
+    if (nblocks >= 8)
+      {
+       /* Use u64 to store pointers for x32 support (assembly function
+         * assumes 64-bit pointers). */
+       Ls[(0 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+       Ls[(1 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+       Ls[(2 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+       Ls[(3 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
+       Ls[(4 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+       Ls[(5 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+       Ls[(6 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+       l = &Ls[(7 + n) % 8];
+
+       /* Process data in 8 block chunks. */
+       while (nblocks >= 8)
+         {
+           /* l_tmp will be used only every 65536-th block. */
+           blkn += 8;
+           *l = (uintptr_t)(void *)ocb_get_l(c, l_tmp, blkn - blkn % 8);
+
+           if (encrypt)
+             _gcry_serpent_sse2_ocb_enc(ctx, outbuf, inbuf, c->u_iv.iv,
+                                         c->u_ctr.ctr, Ls);
+           else
+             _gcry_serpent_sse2_ocb_dec(ctx, outbuf, inbuf, c->u_iv.iv,
+                                         c->u_ctr.ctr, Ls);
+
+           nblocks -= 8;
+           outbuf += 8 * sizeof(serpent_block_t);
+           inbuf  += 8 * sizeof(serpent_block_t);
+           did_use_sse2 = 1;
+         }
+      }
+
+    if (did_use_sse2)
+      {
+       /* serpent-sse2 assembly code does not use stack */
+       if (nblocks == 0)
+         burn_stack_depth = 0;
+      }
+
+    /* Use generic code to handle smaller chunks... */
+  }
+#endif
+
+#ifdef USE_NEON
+  if (ctx->use_neon)
+    {
+      int did_use_neon = 0;
+      const void *Ls[8];
+      unsigned int n = 8 - (blkn % 8);
+      const void **l;
+
+      if (nblocks >= 8)
+       {
+         Ls[(0 + n) % 8] = c->u_mode.ocb.L[0];
+         Ls[(1 + n) % 8] = c->u_mode.ocb.L[1];
+         Ls[(2 + n) % 8] = c->u_mode.ocb.L[0];
+         Ls[(3 + n) % 8] = c->u_mode.ocb.L[2];
+         Ls[(4 + n) % 8] = c->u_mode.ocb.L[0];
+         Ls[(5 + n) % 8] = c->u_mode.ocb.L[1];
+         Ls[(6 + n) % 8] = c->u_mode.ocb.L[0];
+         l = &Ls[(7 + n) % 8];
+
+         /* Process data in 8 block chunks. */
+         while (nblocks >= 8)
+           {
+             /* l_tmp will be used only every 65536-th block. */
+             blkn += 8;
+             *l = ocb_get_l(c, l_tmp, blkn - blkn % 8);
+
+             if (encrypt)
+               _gcry_serpent_neon_ocb_enc(ctx, outbuf, inbuf, c->u_iv.iv,
+                                         c->u_ctr.ctr, Ls);
+             else
+               _gcry_serpent_neon_ocb_dec(ctx, outbuf, inbuf, c->u_iv.iv,
+                                         c->u_ctr.ctr, Ls);
+
+             nblocks -= 8;
+             outbuf += 8 * sizeof(serpent_block_t);
+             inbuf  += 8 * sizeof(serpent_block_t);
+             did_use_neon = 1;
+           }
+       }
+
+      if (did_use_neon)
+       {
+         /* serpent-neon assembly code does not use stack */
+         if (nblocks == 0)
+           burn_stack_depth = 0;
+       }
+
+      /* Use generic code to handle smaller chunks... */
+    }
+#endif
+
+#if defined(USE_AVX2) || defined(USE_SSE2) || defined(USE_NEON)
+  c->u_mode.ocb.data_nblocks = blkn;
+
+  wipememory(&l_tmp, sizeof(l_tmp));
+
+  if (burn_stack_depth)
+    _gcry_burn_stack (burn_stack_depth + 4 * sizeof(void *));
+#endif
+
+  return nblocks;
+}
+
+/* Bulk authentication of complete blocks in OCB mode. */
+size_t
+_gcry_serpent_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
+                       size_t nblocks)
+{
+#if defined(USE_AVX2) || defined(USE_SSE2) || defined(USE_NEON)
+  serpent_context_t *ctx = (void *)&c->context.c;
+  const unsigned char *abuf = abuf_arg;
+  unsigned char l_tmp[sizeof(serpent_block_t)];
+  int burn_stack_depth = 2 * sizeof(serpent_block_t);
+  u64 blkn = c->u_mode.ocb.aad_nblocks;
+#else
+  (void)c;
+  (void)abuf_arg;
+#endif
+
+#ifdef USE_AVX2
+  if (ctx->use_avx2)
+    {
+      int did_use_avx2 = 0;
+      u64 Ls[16];
+      unsigned int n = 16 - (blkn % 16);
+      u64 *l;
+      int i;
+
+      if (nblocks >= 16)
+       {
+         for (i = 0; i < 16; i += 8)
+           {
+             /* Use u64 to store pointers for x32 support (assembly function
+              * assumes 64-bit pointers). */
+             Ls[(i + 0 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+             Ls[(i + 1 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+             Ls[(i + 2 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+             Ls[(i + 3 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
+             Ls[(i + 4 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+             Ls[(i + 5 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+             Ls[(i + 6 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+           }
+
+         Ls[(7 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
+         l = &Ls[(15 + n) % 16];
+
+         /* Process data in 16 block chunks. */
+         while (nblocks >= 16)
+           {
+             /* l_tmp will be used only every 65536-th block. */
+             blkn += 16;
+             *l = (uintptr_t)(void *)ocb_get_l(c, l_tmp, blkn - blkn % 16);
+
+             _gcry_serpent_avx2_ocb_auth(ctx, abuf, c->u_mode.ocb.aad_offset,
+                                         c->u_mode.ocb.aad_sum, Ls);
+
+             nblocks -= 16;
+             abuf += 16 * sizeof(serpent_block_t);
+             did_use_avx2 = 1;
+           }
+       }
+
+      if (did_use_avx2)
+       {
+         /* serpent-avx2 assembly code does not use stack */
+         if (nblocks == 0)
+           burn_stack_depth = 0;
+       }
+
+      /* Use generic code to handle smaller chunks... */
+    }
+#endif
+
+#ifdef USE_SSE2
+  {
+    int did_use_sse2 = 0;
+    u64 Ls[8];
+    unsigned int n = 8 - (blkn % 8);
+    u64 *l;
+
+    if (nblocks >= 8)
+      {
+       /* Use u64 to store pointers for x32 support (assembly function
+       * assumes 64-bit pointers). */
+       Ls[(0 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+       Ls[(1 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+       Ls[(2 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+       Ls[(3 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
+       Ls[(4 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+       Ls[(5 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+       Ls[(6 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+       l = &Ls[(7 + n) % 8];
+
+       /* Process data in 8 block chunks. */
+       while (nblocks >= 8)
+         {
+           /* l_tmp will be used only every 65536-th block. */
+           blkn += 8;
+           *l = (uintptr_t)(void *)ocb_get_l(c, l_tmp, blkn - blkn % 8);
+
+           _gcry_serpent_sse2_ocb_auth(ctx, abuf, c->u_mode.ocb.aad_offset,
+                                       c->u_mode.ocb.aad_sum, Ls);
+
+           nblocks -= 8;
+           abuf += 8 * sizeof(serpent_block_t);
+           did_use_sse2 = 1;
+         }
+      }
+
+    if (did_use_sse2)
+      {
+       /* serpent-avx2 assembly code does not use stack */
+       if (nblocks == 0)
+         burn_stack_depth = 0;
+      }
+
+    /* Use generic code to handle smaller chunks... */
+  }
+#endif
+
+#ifdef USE_NEON
+  if (ctx->use_neon)
+    {
+      int did_use_neon = 0;
+      const void *Ls[8];
+      unsigned int n = 8 - (blkn % 8);
+      const void **l;
+
+      if (nblocks >= 8)
+       {
+         Ls[(0 + n) % 8] = c->u_mode.ocb.L[0];
+         Ls[(1 + n) % 8] = c->u_mode.ocb.L[1];
+         Ls[(2 + n) % 8] = c->u_mode.ocb.L[0];
+         Ls[(3 + n) % 8] = c->u_mode.ocb.L[2];
+         Ls[(4 + n) % 8] = c->u_mode.ocb.L[0];
+         Ls[(5 + n) % 8] = c->u_mode.ocb.L[1];
+         Ls[(6 + n) % 8] = c->u_mode.ocb.L[0];
+         l = &Ls[(7 + n) % 8];
+
+         /* Process data in 8 block chunks. */
+         while (nblocks >= 8)
+           {
+             /* l_tmp will be used only every 65536-th block. */
+             blkn += 8;
+             *l = ocb_get_l(c, l_tmp, blkn - blkn % 8);
+
+             _gcry_serpent_neon_ocb_auth(ctx, abuf, c->u_mode.ocb.aad_offset,
+                                         c->u_mode.ocb.aad_sum, Ls);
+
+             nblocks -= 8;
+             abuf += 8 * sizeof(serpent_block_t);
+             did_use_neon = 1;
+           }
+       }
+
+      if (did_use_neon)
+       {
+         /* serpent-neon assembly code does not use stack */
+         if (nblocks == 0)
+           burn_stack_depth = 0;
+       }
+
+      /* Use generic code to handle smaller chunks... */
+    }
+#endif
+
+#if defined(USE_AVX2) || defined(USE_SSE2) || defined(USE_NEON)
+  c->u_mode.ocb.aad_nblocks = blkn;
+
+  wipememory(&l_tmp, sizeof(l_tmp));
+
+  if (burn_stack_depth)
+    _gcry_burn_stack (burn_stack_depth + 4 * sizeof(void *));
+#endif
+
+  return nblocks;
+}
+
 \f
 
 /* Run the self-tests for SERPENT-CTR-128, tests IV increment of bulk CTR
@@ -1291,18 +1734,54 @@ serpent_test (void)
 }
 
 \f
+static gcry_cipher_oid_spec_t serpent128_oids[] =
+  {
+    {"1.3.6.1.4.1.11591.13.2.1", GCRY_CIPHER_MODE_ECB },
+    {"1.3.6.1.4.1.11591.13.2.2", GCRY_CIPHER_MODE_CBC },
+    {"1.3.6.1.4.1.11591.13.2.3", GCRY_CIPHER_MODE_OFB },
+    {"1.3.6.1.4.1.11591.13.2.4", GCRY_CIPHER_MODE_CFB },
+    { NULL }
+  };
+
+static gcry_cipher_oid_spec_t serpent192_oids[] =
+  {
+    {"1.3.6.1.4.1.11591.13.2.21", GCRY_CIPHER_MODE_ECB },
+    {"1.3.6.1.4.1.11591.13.2.22", GCRY_CIPHER_MODE_CBC },
+    {"1.3.6.1.4.1.11591.13.2.23", GCRY_CIPHER_MODE_OFB },
+    {"1.3.6.1.4.1.11591.13.2.24", GCRY_CIPHER_MODE_CFB },
+    { NULL }
+  };
 
-/* "SERPENT" is an alias for "SERPENT128".  */
-static const char *cipher_spec_serpent128_aliases[] =
+static gcry_cipher_oid_spec_t serpent256_oids[] =
+  {
+    {"1.3.6.1.4.1.11591.13.2.41", GCRY_CIPHER_MODE_ECB },
+    {"1.3.6.1.4.1.11591.13.2.42", GCRY_CIPHER_MODE_CBC },
+    {"1.3.6.1.4.1.11591.13.2.43", GCRY_CIPHER_MODE_OFB },
+    {"1.3.6.1.4.1.11591.13.2.44", GCRY_CIPHER_MODE_CFB },
+    { NULL }
+  };
+
+static const char *serpent128_aliases[] =
   {
     "SERPENT",
+    "SERPENT-128",
+    NULL
+  };
+static const char *serpent192_aliases[] =
+  {
+    "SERPENT-192",
+    NULL
+  };
+static const char *serpent256_aliases[] =
+  {
+    "SERPENT-256",
     NULL
   };
 
 gcry_cipher_spec_t _gcry_cipher_spec_serpent128 =
   {
     GCRY_CIPHER_SERPENT128, {0, 0},
-    "SERPENT128", cipher_spec_serpent128_aliases, NULL, 16, 128,
+    "SERPENT128", serpent128_aliases, serpent128_oids, 16, 128,
     sizeof (serpent_context_t),
     serpent_setkey, serpent_encrypt, serpent_decrypt
   };
@@ -1310,7 +1789,7 @@ gcry_cipher_spec_t _gcry_cipher_spec_serpent128 =
 gcry_cipher_spec_t _gcry_cipher_spec_serpent192 =
   {
     GCRY_CIPHER_SERPENT192, {0, 0},
-    "SERPENT192", NULL, NULL, 16, 192,
+    "SERPENT192", serpent192_aliases, serpent192_oids, 16, 192,
     sizeof (serpent_context_t),
     serpent_setkey, serpent_encrypt, serpent_decrypt
   };
@@ -1318,7 +1797,7 @@ gcry_cipher_spec_t _gcry_cipher_spec_serpent192 =
 gcry_cipher_spec_t _gcry_cipher_spec_serpent256 =
   {
     GCRY_CIPHER_SERPENT256, {0, 0},
-    "SERPENT256", NULL, NULL, 16, 256,
+    "SERPENT256", serpent256_aliases, serpent256_oids, 16, 256,
     sizeof (serpent_context_t),
     serpent_setkey, serpent_encrypt, serpent_decrypt
   };
diff --git a/cipher/sha1-armv7-neon.S b/cipher/sha1-armv7-neon.S
new file mode 100644 (file)
index 0000000..f314d8e
--- /dev/null
@@ -0,0 +1,525 @@
+/* sha1-armv7-neon.S - ARM/NEON accelerated SHA-1 transform function
+ * Copyright (C) 2013-2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * Based on sha1.c:
+ *  Copyright (C) 1998, 2001, 2002, 2003, 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) && \
+    defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \
+    defined(HAVE_GCC_INLINE_ASM_NEON) && defined(USE_SHA1)
+
+.syntax unified
+.fpu neon
+.arm
+
+.text
+
+#ifdef __PIC__
+#  define GET_DATA_POINTER(reg, name, rtmp) \
+               ldr reg, 1f; \
+               ldr rtmp, 2f; \
+               b 3f; \
+       1:      .word _GLOBAL_OFFSET_TABLE_-(3f+8); \
+       2:      .word name(GOT); \
+       3:      add reg, pc, reg; \
+               ldr reg, [reg, rtmp];
+#else
+#  define GET_DATA_POINTER(reg, name, rtmp) ldr reg, =name
+#endif
+
+/* Context structure */
+
+#define state_h0 0
+#define state_h1 4
+#define state_h2 8
+#define state_h3 12
+#define state_h4 16
+
+
+/* Constants */
+
+#define K1  0x5A827999
+#define K2  0x6ED9EBA1
+#define K3  0x8F1BBCDC
+#define K4  0xCA62C1D6
+.align 4
+gcry_sha1_armv7_neon_K_VEC:
+.LK_VEC:
+.LK1:  .long K1, K1, K1, K1
+.LK2:  .long K2, K2, K2, K2
+.LK3:  .long K3, K3, K3, K3
+.LK4:  .long K4, K4, K4, K4
+
+
+/* Register macros */
+
+#define RSTATE r0
+#define RDATA r1
+#define RNBLKS r2
+#define ROLDSTACK r3
+#define RWK lr
+
+#define _a r4
+#define _b r5
+#define _c r6
+#define _d r7
+#define _e r8
+
+#define RT0 r9
+#define RT1 r10
+#define RT2 r11
+#define RT3 r12
+
+#define W0 q0
+#define W1 q1
+#define W2 q2
+#define W3 q3
+#define W4 q4
+#define W5 q5
+#define W6 q6
+#define W7 q7
+
+#define tmp0 q8
+#define tmp1 q9
+#define tmp2 q10
+#define tmp3 q11
+
+#define qK1 q12
+#define qK2 q13
+#define qK3 q14
+#define qK4 q15
+
+
+/* Round function macros. */
+
+#define WK_offs(i) (((i) & 15) * 4)
+
+#define _R_F1(a,b,c,d,e,i,pre1,pre2,pre3,i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       ldr RT3, [sp, WK_offs(i)]; \
+               pre1(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+       bic RT0, d, b; \
+       add e, e, a, ror #(32 - 5); \
+       and RT1, c, b; \
+               pre2(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+       add RT0, RT0, RT3; \
+       add e, e, RT1; \
+       ror b, #(32 - 30); \
+               pre3(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+       add e, e, RT0;
+
+#define _R_F2(a,b,c,d,e,i,pre1,pre2,pre3,i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       ldr RT3, [sp, WK_offs(i)]; \
+               pre1(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+       eor RT0, d, b; \
+       add e, e, a, ror #(32 - 5); \
+       eor RT0, RT0, c; \
+               pre2(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+       add e, e, RT3; \
+       ror b, #(32 - 30); \
+               pre3(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+       add e, e, RT0; \
+
+#define _R_F3(a,b,c,d,e,i,pre1,pre2,pre3,i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       ldr RT3, [sp, WK_offs(i)]; \
+               pre1(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+       eor RT0, b, c; \
+       and RT1, b, c; \
+       add e, e, a, ror #(32 - 5); \
+               pre2(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+       and RT0, RT0, d; \
+       add RT1, RT1, RT3; \
+       add e, e, RT0; \
+       ror b, #(32 - 30); \
+               pre3(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+       add e, e, RT1;
+
+#define _R_F4(a,b,c,d,e,i,pre1,pre2,pre3,i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       _R_F2(a,b,c,d,e,i,pre1,pre2,pre3,i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28)
+
+#define _R(a,b,c,d,e,f,i,pre1,pre2,pre3,i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+       _R_##f(a,b,c,d,e,i,pre1,pre2,pre3,i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28)
+
+#define R(a,b,c,d,e,f,i) \
+       _R_##f(a,b,c,d,e,i,dummy,dummy,dummy,i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28)
+
+#define dummy(...)
+
+
+/* Input expansion macros. */
+
+/********* Precalc macros for rounds 0-15 *************************************/
+
+#define W_PRECALC_00_15() \
+       add       RWK, sp, #(WK_offs(0));                       \
+       \
+       vld1.32   {tmp0, tmp1}, [RDATA]!;                       \
+       vrev32.8  W0, tmp0;             /* big => little */     \
+       vld1.32   {tmp2, tmp3}, [RDATA]!;                       \
+       vadd.u32  tmp0, W0, curK;                               \
+       vrev32.8  W7, tmp1;             /* big => little */     \
+       vrev32.8  W6, tmp2;             /* big => little */     \
+       vadd.u32  tmp1, W7, curK;                               \
+       vrev32.8  W5, tmp3;             /* big => little */     \
+       vadd.u32  tmp2, W6, curK;                               \
+       vst1.32   {tmp0, tmp1}, [RWK]!;                         \
+       vadd.u32  tmp3, W5, curK;                               \
+       vst1.32   {tmp2, tmp3}, [RWK];                          \
+
+#define WPRECALC_00_15_0(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       vld1.32   {tmp0, tmp1}, [RDATA]!;                       \
+
+#define WPRECALC_00_15_1(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       add       RWK, sp, #(WK_offs(0));                       \
+
+#define WPRECALC_00_15_2(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       vrev32.8  W0, tmp0;             /* big => little */     \
+
+#define WPRECALC_00_15_3(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       vld1.32   {tmp2, tmp3}, [RDATA]!;                       \
+
+#define WPRECALC_00_15_4(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       vadd.u32  tmp0, W0, curK;                               \
+
+#define WPRECALC_00_15_5(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       vrev32.8  W7, tmp1;             /* big => little */     \
+
+#define WPRECALC_00_15_6(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       vrev32.8  W6, tmp2;             /* big => little */     \
+
+#define WPRECALC_00_15_7(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       vadd.u32  tmp1, W7, curK;                               \
+
+#define WPRECALC_00_15_8(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       vrev32.8  W5, tmp3;             /* big => little */     \
+
+#define WPRECALC_00_15_9(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       vadd.u32  tmp2, W6, curK;                               \
+
+#define WPRECALC_00_15_10(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       vst1.32   {tmp0, tmp1}, [RWK]!;                         \
+
+#define WPRECALC_00_15_11(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       vadd.u32  tmp3, W5, curK;                               \
+
+#define WPRECALC_00_15_12(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       vst1.32   {tmp2, tmp3}, [RWK];                          \
+
+
+/********* Precalc macros for rounds 16-31 ************************************/
+
+#define WPRECALC_16_31_0(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       veor      tmp0, tmp0;                   \
+       vext.8    W, W_m16, W_m12, #8;          \
+
+#define WPRECALC_16_31_1(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       add       RWK, sp, #(WK_offs(i));       \
+       vext.8    tmp0, W_m04, tmp0, #4;        \
+
+#define WPRECALC_16_31_2(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       veor      tmp0, tmp0, W_m16;            \
+       veor.32   W, W, W_m08;                  \
+
+#define WPRECALC_16_31_3(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       veor      tmp1, tmp1;                   \
+       veor      W, W, tmp0;                   \
+
+#define WPRECALC_16_31_4(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       vshl.u32  tmp0, W, #1;                  \
+
+#define WPRECALC_16_31_5(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       vext.8    tmp1, tmp1, W, #(16-12);      \
+       vshr.u32  W, W, #31;                    \
+
+#define WPRECALC_16_31_6(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       vorr      tmp0, tmp0, W;                \
+       vshr.u32  W, tmp1, #30;                 \
+
+#define WPRECALC_16_31_7(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       vshl.u32  tmp1, tmp1, #2;               \
+
+#define WPRECALC_16_31_8(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       veor      tmp0, tmp0, W;                \
+
+#define WPRECALC_16_31_9(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       veor      W, tmp0, tmp1;                \
+
+#define WPRECALC_16_31_10(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       vadd.u32  tmp0, W, curK;                \
+
+#define WPRECALC_16_31_11(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       vst1.32   {tmp0}, [RWK];
+
+
+/********* Precalc macros for rounds 32-79 ************************************/
+
+#define WPRECALC_32_79_0(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       veor W, W_m28; \
+
+#define WPRECALC_32_79_1(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       vext.8 tmp0, W_m08, W_m04, #8; \
+
+#define WPRECALC_32_79_2(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       veor W, W_m16; \
+
+#define WPRECALC_32_79_3(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       veor W, tmp0; \
+
+#define WPRECALC_32_79_4(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       add RWK, sp, #(WK_offs(i&~3)); \
+
+#define WPRECALC_32_79_5(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       vshl.u32 tmp1, W, #2; \
+
+#define WPRECALC_32_79_6(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       vshr.u32 tmp0, W, #30; \
+
+#define WPRECALC_32_79_7(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       vorr W, tmp0, tmp1; \
+
+#define WPRECALC_32_79_8(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       vadd.u32 tmp0, W, curK; \
+
+#define WPRECALC_32_79_9(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+       vst1.32 {tmp0}, [RWK];
+
+
+/* Other functional macros */
+
+#define CLEAR_REG(reg) veor reg, reg;
+
+
+/*
+ * Transform nblks*64 bytes (nblks*16 32-bit words) at DATA.
+ *
+ * unsigned int
+ * _gcry_sha1_transform_armv7_neon (void *ctx, const unsigned char *data,
+ *                                  size_t nblks)
+ */
+.align 3
+.globl _gcry_sha1_transform_armv7_neon
+.type  _gcry_sha1_transform_armv7_neon,%function;
+_gcry_sha1_transform_armv7_neon:
+  /* input:
+   *   r0: ctx, CTX
+   *   r1: data (64*nblks bytes)
+   *   r2: nblks
+   */
+
+  cmp RNBLKS, #0;
+  beq .Ldo_nothing;
+
+  push {r4-r12, lr};
+
+  GET_DATA_POINTER(RT3, .LK_VEC, _a);
+  vpush {q4-q7};
+
+  mov ROLDSTACK, sp;
+
+  /* Align stack. */
+  sub sp, #(16*4);
+  and sp, #(~(16-1));
+
+  vld1.32 {qK1-qK2}, [RT3]!; /* Load K1,K2 */
+
+  /* Get the values of the chaining variables. */
+  ldm RSTATE, {_a-_e};
+
+  vld1.32 {qK3-qK4}, [RT3]; /* Load K3,K4 */
+
+#undef curK
+#define curK qK1
+  /* Precalc 0-15. */
+  W_PRECALC_00_15();
+
+  b .Loop;
+
+.ltorg
+.Loop:
+  /* Transform 0-15 + Precalc 16-31. */
+  _R( _a, _b, _c, _d, _e, F1,  0, WPRECALC_16_31_0, WPRECALC_16_31_1, WPRECALC_16_31_2, 16, W4, W5, W6, W7, W0, _, _, _ );
+  _R( _e, _a, _b, _c, _d, F1,  1, WPRECALC_16_31_3, WPRECALC_16_31_4, WPRECALC_16_31_5, 16, W4, W5, W6, W7, W0, _, _, _ );
+  _R( _d, _e, _a, _b, _c, F1,  2, WPRECALC_16_31_6, WPRECALC_16_31_7, WPRECALC_16_31_8, 16, W4, W5, W6, W7, W0, _, _, _ );
+  _R( _c, _d, _e, _a, _b, F1,  3, WPRECALC_16_31_9, WPRECALC_16_31_10,WPRECALC_16_31_11,16, W4, W5, W6, W7, W0, _, _, _ );
+
+#undef curK
+#define curK qK2
+  _R( _b, _c, _d, _e, _a, F1,  4, WPRECALC_16_31_0, WPRECALC_16_31_1, WPRECALC_16_31_2, 20, W3, W4, W5, W6, W7, _, _, _ );
+  _R( _a, _b, _c, _d, _e, F1,  5, WPRECALC_16_31_3, WPRECALC_16_31_4, WPRECALC_16_31_5, 20, W3, W4, W5, W6, W7, _, _, _ );
+  _R( _e, _a, _b, _c, _d, F1,  6, WPRECALC_16_31_6, WPRECALC_16_31_7, WPRECALC_16_31_8, 20, W3, W4, W5, W6, W7, _, _, _ );
+  _R( _d, _e, _a, _b, _c, F1,  7, WPRECALC_16_31_9, WPRECALC_16_31_10,WPRECALC_16_31_11,20, W3, W4, W5, W6, W7, _, _, _ );
+
+  _R( _c, _d, _e, _a, _b, F1,  8, WPRECALC_16_31_0, WPRECALC_16_31_1, WPRECALC_16_31_2, 24, W2, W3, W4, W5, W6, _, _, _ );
+  _R( _b, _c, _d, _e, _a, F1,  9, WPRECALC_16_31_3, WPRECALC_16_31_4, WPRECALC_16_31_5, 24, W2, W3, W4, W5, W6, _, _, _ );
+  _R( _a, _b, _c, _d, _e, F1, 10, WPRECALC_16_31_6, WPRECALC_16_31_7, WPRECALC_16_31_8, 24, W2, W3, W4, W5, W6, _, _, _ );
+  _R( _e, _a, _b, _c, _d, F1, 11, WPRECALC_16_31_9, WPRECALC_16_31_10,WPRECALC_16_31_11,24, W2, W3, W4, W5, W6, _, _, _ );
+
+  _R( _d, _e, _a, _b, _c, F1, 12, WPRECALC_16_31_0, WPRECALC_16_31_1, WPRECALC_16_31_2, 28, W1, W2, W3, W4, W5, _, _, _ );
+  _R( _c, _d, _e, _a, _b, F1, 13, WPRECALC_16_31_3, WPRECALC_16_31_4, WPRECALC_16_31_5, 28, W1, W2, W3, W4, W5, _, _, _ );
+  _R( _b, _c, _d, _e, _a, F1, 14, WPRECALC_16_31_6, WPRECALC_16_31_7, WPRECALC_16_31_8, 28, W1, W2, W3, W4, W5, _, _, _ );
+  _R( _a, _b, _c, _d, _e, F1, 15, WPRECALC_16_31_9, WPRECALC_16_31_10,WPRECALC_16_31_11,28, W1, W2, W3, W4, W5, _, _, _ );
+
+  /* Transform 16-63 + Precalc 32-79. */
+  _R( _e, _a, _b, _c, _d, F1, 16, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 32, W0, W1, W2, W3, W4, W5, W6, W7);
+  _R( _d, _e, _a, _b, _c, F1, 17, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 32, W0, W1, W2, W3, W4, W5, W6, W7);
+  _R( _c, _d, _e, _a, _b, F1, 18, WPRECALC_32_79_6, dummy,            WPRECALC_32_79_7, 32, W0, W1, W2, W3, W4, W5, W6, W7);
+  _R( _b, _c, _d, _e, _a, F1, 19, WPRECALC_32_79_8, dummy,            WPRECALC_32_79_9, 32, W0, W1, W2, W3, W4, W5, W6, W7);
+
+  _R( _a, _b, _c, _d, _e, F2, 20, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 36, W7, W0, W1, W2, W3, W4, W5, W6);
+  _R( _e, _a, _b, _c, _d, F2, 21, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 36, W7, W0, W1, W2, W3, W4, W5, W6);
+  _R( _d, _e, _a, _b, _c, F2, 22, WPRECALC_32_79_6, dummy,            WPRECALC_32_79_7, 36, W7, W0, W1, W2, W3, W4, W5, W6);
+  _R( _c, _d, _e, _a, _b, F2, 23, WPRECALC_32_79_8, dummy,            WPRECALC_32_79_9, 36, W7, W0, W1, W2, W3, W4, W5, W6);
+
+#undef curK
+#define curK qK3
+  _R( _b, _c, _d, _e, _a, F2, 24, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 40, W6, W7, W0, W1, W2, W3, W4, W5);
+  _R( _a, _b, _c, _d, _e, F2, 25, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 40, W6, W7, W0, W1, W2, W3, W4, W5);
+  _R( _e, _a, _b, _c, _d, F2, 26, WPRECALC_32_79_6, dummy,            WPRECALC_32_79_7, 40, W6, W7, W0, W1, W2, W3, W4, W5);
+  _R( _d, _e, _a, _b, _c, F2, 27, WPRECALC_32_79_8, dummy,            WPRECALC_32_79_9, 40, W6, W7, W0, W1, W2, W3, W4, W5);
+
+  _R( _c, _d, _e, _a, _b, F2, 28, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 44, W5, W6, W7, W0, W1, W2, W3, W4);
+  _R( _b, _c, _d, _e, _a, F2, 29, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 44, W5, W6, W7, W0, W1, W2, W3, W4);
+  _R( _a, _b, _c, _d, _e, F2, 30, WPRECALC_32_79_6, dummy,            WPRECALC_32_79_7, 44, W5, W6, W7, W0, W1, W2, W3, W4);
+  _R( _e, _a, _b, _c, _d, F2, 31, WPRECALC_32_79_8, dummy,            WPRECALC_32_79_9, 44, W5, W6, W7, W0, W1, W2, W3, W4);
+
+  _R( _d, _e, _a, _b, _c, F2, 32, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 48, W4, W5, W6, W7, W0, W1, W2, W3);
+  _R( _c, _d, _e, _a, _b, F2, 33, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 48, W4, W5, W6, W7, W0, W1, W2, W3);
+  _R( _b, _c, _d, _e, _a, F2, 34, WPRECALC_32_79_6, dummy,            WPRECALC_32_79_7, 48, W4, W5, W6, W7, W0, W1, W2, W3);
+  _R( _a, _b, _c, _d, _e, F2, 35, WPRECALC_32_79_8, dummy,            WPRECALC_32_79_9, 48, W4, W5, W6, W7, W0, W1, W2, W3);
+
+  _R( _e, _a, _b, _c, _d, F2, 36, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 52, W3, W4, W5, W6, W7, W0, W1, W2);
+  _R( _d, _e, _a, _b, _c, F2, 37, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 52, W3, W4, W5, W6, W7, W0, W1, W2);
+  _R( _c, _d, _e, _a, _b, F2, 38, WPRECALC_32_79_6, dummy,            WPRECALC_32_79_7, 52, W3, W4, W5, W6, W7, W0, W1, W2);
+  _R( _b, _c, _d, _e, _a, F2, 39, WPRECALC_32_79_8, dummy,            WPRECALC_32_79_9, 52, W3, W4, W5, W6, W7, W0, W1, W2);
+
+  _R( _a, _b, _c, _d, _e, F3, 40, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 56, W2, W3, W4, W5, W6, W7, W0, W1);
+  _R( _e, _a, _b, _c, _d, F3, 41, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 56, W2, W3, W4, W5, W6, W7, W0, W1);
+  _R( _d, _e, _a, _b, _c, F3, 42, WPRECALC_32_79_6, dummy,            WPRECALC_32_79_7, 56, W2, W3, W4, W5, W6, W7, W0, W1);
+  _R( _c, _d, _e, _a, _b, F3, 43, WPRECALC_32_79_8, dummy,            WPRECALC_32_79_9, 56, W2, W3, W4, W5, W6, W7, W0, W1);
+
+#undef curK
+#define curK qK4
+  _R( _b, _c, _d, _e, _a, F3, 44, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 60, W1, W2, W3, W4, W5, W6, W7, W0);
+  _R( _a, _b, _c, _d, _e, F3, 45, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 60, W1, W2, W3, W4, W5, W6, W7, W0);
+  _R( _e, _a, _b, _c, _d, F3, 46, WPRECALC_32_79_6, dummy,            WPRECALC_32_79_7, 60, W1, W2, W3, W4, W5, W6, W7, W0);
+  _R( _d, _e, _a, _b, _c, F3, 47, WPRECALC_32_79_8, dummy,            WPRECALC_32_79_9, 60, W1, W2, W3, W4, W5, W6, W7, W0);
+
+  _R( _c, _d, _e, _a, _b, F3, 48, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 64, W0, W1, W2, W3, W4, W5, W6, W7);
+  _R( _b, _c, _d, _e, _a, F3, 49, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 64, W0, W1, W2, W3, W4, W5, W6, W7);
+  _R( _a, _b, _c, _d, _e, F3, 50, WPRECALC_32_79_6, dummy,            WPRECALC_32_79_7, 64, W0, W1, W2, W3, W4, W5, W6, W7);
+  _R( _e, _a, _b, _c, _d, F3, 51, WPRECALC_32_79_8, dummy,            WPRECALC_32_79_9, 64, W0, W1, W2, W3, W4, W5, W6, W7);
+
+  _R( _d, _e, _a, _b, _c, F3, 52, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 68, W7, W0, W1, W2, W3, W4, W5, W6);
+  _R( _c, _d, _e, _a, _b, F3, 53, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 68, W7, W0, W1, W2, W3, W4, W5, W6);
+  _R( _b, _c, _d, _e, _a, F3, 54, WPRECALC_32_79_6, dummy,            WPRECALC_32_79_7, 68, W7, W0, W1, W2, W3, W4, W5, W6);
+  _R( _a, _b, _c, _d, _e, F3, 55, WPRECALC_32_79_8, dummy,            WPRECALC_32_79_9, 68, W7, W0, W1, W2, W3, W4, W5, W6);
+
+  _R( _e, _a, _b, _c, _d, F3, 56, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 72, W6, W7, W0, W1, W2, W3, W4, W5);
+  _R( _d, _e, _a, _b, _c, F3, 57, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 72, W6, W7, W0, W1, W2, W3, W4, W5);
+  _R( _c, _d, _e, _a, _b, F3, 58, WPRECALC_32_79_6, dummy,            WPRECALC_32_79_7, 72, W6, W7, W0, W1, W2, W3, W4, W5);
+  _R( _b, _c, _d, _e, _a, F3, 59, WPRECALC_32_79_8, dummy,            WPRECALC_32_79_9, 72, W6, W7, W0, W1, W2, W3, W4, W5);
+
+  subs RNBLKS, #1;
+
+  _R( _a, _b, _c, _d, _e, F4, 60, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 76, W5, W6, W7, W0, W1, W2, W3, W4);
+  _R( _e, _a, _b, _c, _d, F4, 61, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 76, W5, W6, W7, W0, W1, W2, W3, W4);
+  _R( _d, _e, _a, _b, _c, F4, 62, WPRECALC_32_79_6, dummy,            WPRECALC_32_79_7, 76, W5, W6, W7, W0, W1, W2, W3, W4);
+  _R( _c, _d, _e, _a, _b, F4, 63, WPRECALC_32_79_8, dummy,            WPRECALC_32_79_9, 76, W5, W6, W7, W0, W1, W2, W3, W4);
+
+  beq .Lend;
+
+  /* Transform 64-79 + Precalc 0-15 of next block. */
+#undef curK
+#define curK qK1
+  _R( _b, _c, _d, _e, _a, F4, 64, WPRECALC_00_15_0, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+  _R( _a, _b, _c, _d, _e, F4, 65, WPRECALC_00_15_1, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+  _R( _e, _a, _b, _c, _d, F4, 66, WPRECALC_00_15_2, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+  _R( _d, _e, _a, _b, _c, F4, 67, WPRECALC_00_15_3, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+
+  _R( _c, _d, _e, _a, _b, F4, 68, dummy,            dummy, dummy, _, _, _, _, _, _, _, _, _ );
+  _R( _b, _c, _d, _e, _a, F4, 69, dummy,            dummy, dummy, _, _, _, _, _, _, _, _, _ );
+  _R( _a, _b, _c, _d, _e, F4, 70, WPRECALC_00_15_4, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+  _R( _e, _a, _b, _c, _d, F4, 71, WPRECALC_00_15_5, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+
+  _R( _d, _e, _a, _b, _c, F4, 72, dummy,            dummy, dummy, _, _, _, _, _, _, _, _, _ );
+  _R( _c, _d, _e, _a, _b, F4, 73, dummy,            dummy, dummy, _, _, _, _, _, _, _, _, _ );
+  _R( _b, _c, _d, _e, _a, F4, 74, WPRECALC_00_15_6, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+  _R( _a, _b, _c, _d, _e, F4, 75, WPRECALC_00_15_7, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+
+  _R( _e, _a, _b, _c, _d, F4, 76, WPRECALC_00_15_8, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+  _R( _d, _e, _a, _b, _c, F4, 77, WPRECALC_00_15_9, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+  _R( _c, _d, _e, _a, _b, F4, 78, WPRECALC_00_15_10, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+  _R( _b, _c, _d, _e, _a, F4, 79, WPRECALC_00_15_11, dummy, WPRECALC_00_15_12, _, _, _, _, _, _, _, _, _ );
+
+  /* Update the chaining variables. */
+  ldm RSTATE, {RT0-RT3};
+  add _a, RT0;
+  ldr RT0, [RSTATE, #state_h4];
+  add _b, RT1;
+  add _c, RT2;
+  add _d, RT3;
+  add _e, RT0;
+  stm RSTATE, {_a-_e};
+
+  b .Loop;
+
+.ltorg
+.Lend:
+  /* Transform 64-79 + Clear XMM registers. */
+  R( _b, _c, _d, _e, _a, F4, 64 );
+  R( _a, _b, _c, _d, _e, F4, 65 ); CLEAR_REG(tmp0);
+  R( _e, _a, _b, _c, _d, F4, 66 ); CLEAR_REG(tmp1);
+  R( _d, _e, _a, _b, _c, F4, 67 ); CLEAR_REG(W0);
+  R( _c, _d, _e, _a, _b, F4, 68 ); CLEAR_REG(W1);
+  R( _b, _c, _d, _e, _a, F4, 69 ); CLEAR_REG(W2);
+  R( _a, _b, _c, _d, _e, F4, 70 ); CLEAR_REG(W3);
+  R( _e, _a, _b, _c, _d, F4, 71 ); CLEAR_REG(W4);
+  R( _d, _e, _a, _b, _c, F4, 72 ); CLEAR_REG(W5);
+  R( _c, _d, _e, _a, _b, F4, 73 ); CLEAR_REG(W6);
+  R( _b, _c, _d, _e, _a, F4, 74 ); CLEAR_REG(W7);
+  R( _a, _b, _c, _d, _e, F4, 75 );
+  R( _e, _a, _b, _c, _d, F4, 76 );
+  R( _d, _e, _a, _b, _c, F4, 77 );
+  R( _c, _d, _e, _a, _b, F4, 78 );
+  R( _b, _c, _d, _e, _a, F4, 79 );
+
+  mov sp, ROLDSTACK;
+
+  /* Update the chaining variables. */
+  ldm RSTATE, {RT0-RT3};
+  add _a, RT0;
+  ldr RT0, [RSTATE, #state_h4];
+  add _b, RT1;
+  add _c, RT2;
+  add _d, RT3;
+  vpop {q4-q7};
+  add _e, RT0;
+  stm RSTATE, {_a-_e};
+
+  /* burn_stack */
+  mov r0, #(16*4 + 16*4 + 15);
+
+  pop {r4-r12, pc};
+
+.Ldo_nothing:
+  mov r0, #0;
+  bx lr
+
+#endif
diff --git a/cipher/sha1-avx-amd64.S b/cipher/sha1-avx-amd64.S
new file mode 100644 (file)
index 0000000..062a45b
--- /dev/null
@@ -0,0 +1,428 @@
+/* sha1-avx-amd64.S - Intel AVX accelerated SHA-1 transform function
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * Based on sha1.c:
+ *  Copyright (C) 1998, 2001, 2002, 2003, 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Intel SSSE3 accelerated SHA-1 implementation based on white paper:
+ *  "Improving the Performance of the Secure Hash Algorithm (SHA-1)"
+ *  http://software.intel.com/en-us/articles/improving-the-performance-of-the-secure-hash-algorithm-1
+ */
+
+#ifdef __x86_64__
+#include <config.h>
+
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
+    defined(HAVE_GCC_INLINE_ASM_BMI2) && \
+    defined(HAVE_GCC_INLINE_ASM_AVX2) && defined(USE_SHA1)
+
+#ifdef __PIC__
+#  define RIP (%rip)
+#else
+#  define RIP
+#endif
+
+
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
+
+
+/* Context structure */
+
+#define state_h0 0
+#define state_h1 4
+#define state_h2 8
+#define state_h3 12
+#define state_h4 16
+
+
+/* Constants */
+
+.data
+#define K1  0x5A827999
+#define K2  0x6ED9EBA1
+#define K3  0x8F1BBCDC
+#define K4  0xCA62C1D6
+.align 16
+.LK_XMM:
+.LK1:  .long K1, K1, K1, K1
+.LK2:  .long K2, K2, K2, K2
+.LK3:  .long K3, K3, K3, K3
+.LK4:  .long K4, K4, K4, K4
+
+.Lbswap_shufb_ctl:
+       .long 0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f
+
+
+/* Register macros */
+
+#define RSTATE %r8
+#define RDATA %r9
+#define ROLDSTACK %r10
+#define RNBLKS %r11
+
+#define a %eax
+#define b %ebx
+#define c %ecx
+#define d %edx
+#define e %edi
+
+#define RT0 %esi
+#define RT1 %ebp
+
+#define Wtmp0 %xmm0
+#define Wtmp1 %xmm1
+
+#define W0 %xmm2
+#define W1 %xmm3
+#define W2 %xmm4
+#define W3 %xmm5
+#define W4 %xmm6
+#define W5 %xmm7
+#define W6 %xmm8
+#define W7 %xmm9
+
+#define BSWAP_REG %xmm10
+
+
+/* Round function macros. */
+
+#define WK(i) (((i) & 15) * 4)(%rsp)
+
+#define R_F1(a,b,c,d,e,i) \
+       movl c, RT0; \
+       addl WK(i), e; \
+       xorl d, RT0; \
+       movl a, RT1; \
+       andl b, RT0; \
+       shldl $30, b, b; \
+       xorl d, RT0; \
+       leal (RT0,e), e; \
+       shldl $5, RT1, RT1; \
+       addl RT1, e;
+
+#define R_F2(a,b,c,d,e,i) \
+       movl c, RT0; \
+       addl WK(i), e; \
+       xorl b, RT0; \
+       shldl $30, b, b; \
+       xorl d, RT0; \
+       movl a, RT1; \
+       leal (RT0,e), e; \
+       shldl $5, RT1, RT1; \
+       addl RT1, e;
+
+#define R_F3(a,b,c,d,e,i) \
+       movl c, RT0; \
+       movl b, RT1; \
+       xorl b, RT0; \
+       andl c, RT1; \
+       andl d, RT0; \
+       addl RT1, e; \
+       addl WK(i), e; \
+       shldl $30, b, b; \
+       movl a, RT1; \
+       leal (RT0,e), e; \
+       shldl $5, RT1, RT1; \
+       addl RT1, e;
+
+#define R_F4(a,b,c,d,e,i) R_F2(a,b,c,d,e,i)
+
+#define R(a,b,c,d,e,f,i) \
+       R_##f(a,b,c,d,e,i)
+
+
+/* Input expansion macros. */
+
+#define W_PRECALC_00_15_0(i, W, tmp0) \
+       vmovdqu (4*(i))(RDATA), tmp0;
+
+#define W_PRECALC_00_15_1(i, W, tmp0) \
+       vpshufb BSWAP_REG, tmp0, W;
+
+#define W_PRECALC_00_15_2(i, W, tmp0) \
+       vpaddd (.LK_XMM + ((i)/20)*16) RIP, W, tmp0;
+
+#define W_PRECALC_00_15_3(i, W, tmp0) \
+       vmovdqa tmp0, WK(i&~3);
+
+#define W_PRECALC_16_31_0(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
+       vpalignr $8, W_m16, W_m12, W; \
+       vpsrldq $4, W_m04, tmp0; \
+       vpxor W_m08, W, W;
+
+#define W_PRECALC_16_31_1(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
+       vpxor W_m16, tmp0, tmp0; \
+       vpxor tmp0, W, W; \
+       vpslld $1, W, tmp0; \
+       vpslldq $12, W, tmp1; \
+       vpsrld $31, W, W;
+
+#define W_PRECALC_16_31_2(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
+       vpor W, tmp0, tmp0; \
+       vpsrld $30, tmp1, W; \
+       vpslld $2, tmp1, tmp1;
+
+#define W_PRECALC_16_31_3(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
+       vpxor W, tmp0, tmp0; \
+       vpxor tmp1, tmp0, W; \
+       vpaddd (.LK_XMM + ((i)/20)*16) RIP, W, tmp0; \
+       vmovdqa tmp0, WK((i)&~3);
+
+#define W_PRECALC_32_79_0(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
+       vpxor W_m28, W, W; \
+       vpalignr $8, W_m08, W_m04, tmp0;
+
+#define W_PRECALC_32_79_1(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
+       vpxor W_m16, W, W; \
+       vpxor tmp0, W, W;
+
+#define W_PRECALC_32_79_2(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
+       vpsrld $30, W, tmp0; \
+       vpslld $2, W, W;
+
+#define W_PRECALC_32_79_3(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
+       vpor W, tmp0, W; \
+       vpaddd (.LK_XMM + ((i)/20)*16) RIP, W, tmp0; \
+       vmovdqa tmp0, WK((i)&~3);
+
+
+/*
+ * Transform nblks*64 bytes (nblks*16 32-bit words) at DATA.
+ *
+ * unsigned int
+ * _gcry_sha1_transform_amd64_avx (void *ctx, const unsigned char *data,
+ *                                  size_t nblks)
+ */
+.text
+.globl _gcry_sha1_transform_amd64_avx
+ELF(.type _gcry_sha1_transform_amd64_avx,@function)
+.align 16
+_gcry_sha1_transform_amd64_avx:
+  /* input:
+   *   %rdi: ctx, CTX
+   *   %rsi: data (64*nblks bytes)
+   *   %rdx: nblks
+   */
+
+  xorl %eax, %eax;
+  cmpq $0, %rdx;
+  jz .Lret;
+
+  vzeroupper;
+
+  movq %rdx, RNBLKS;
+  movq %rdi, RSTATE;
+  movq %rsi, RDATA;
+  pushq %rbx;
+  pushq %rbp;
+
+  movq %rsp, ROLDSTACK;
+
+  subq $(16*4), %rsp;
+  andq $(~31), %rsp;
+
+  /* Get the values of the chaining variables. */
+  movl state_h0(RSTATE), a;
+  movl state_h1(RSTATE), b;
+  movl state_h2(RSTATE), c;
+  movl state_h3(RSTATE), d;
+  movl state_h4(RSTATE), e;
+
+  movdqa .Lbswap_shufb_ctl RIP, BSWAP_REG;
+
+  /* Precalc 0-15. */
+  W_PRECALC_00_15_0(0, W0, Wtmp0);
+  W_PRECALC_00_15_1(1, W0, Wtmp0);
+  W_PRECALC_00_15_2(2, W0, Wtmp0);
+  W_PRECALC_00_15_3(3, W0, Wtmp0);
+  W_PRECALC_00_15_0(4, W7, Wtmp0);
+  W_PRECALC_00_15_1(5, W7, Wtmp0);
+  W_PRECALC_00_15_2(6, W7, Wtmp0);
+  W_PRECALC_00_15_3(7, W7, Wtmp0);
+  W_PRECALC_00_15_0(8, W6, Wtmp0);
+  W_PRECALC_00_15_1(9, W6, Wtmp0);
+  W_PRECALC_00_15_2(10, W6, Wtmp0);
+  W_PRECALC_00_15_3(11, W6, Wtmp0);
+  W_PRECALC_00_15_0(12, W5, Wtmp0);
+  W_PRECALC_00_15_1(13, W5, Wtmp0);
+  W_PRECALC_00_15_2(14, W5, Wtmp0);
+  W_PRECALC_00_15_3(15, W5, Wtmp0);
+
+.align 8
+.Loop:
+  addq $64, RDATA;
+
+  /* Transform 0-15 + Precalc 16-31. */
+  R( a, b, c, d, e, F1,  0 ); W_PRECALC_16_31_0(16, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
+  R( e, a, b, c, d, F1,  1 ); W_PRECALC_16_31_1(17, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
+  R( d, e, a, b, c, F1,  2 ); W_PRECALC_16_31_2(18, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
+  R( c, d, e, a, b, F1,  3 ); W_PRECALC_16_31_3(19, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
+  R( b, c, d, e, a, F1,  4 ); W_PRECALC_16_31_0(20, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
+  R( a, b, c, d, e, F1,  5 ); W_PRECALC_16_31_1(21, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
+  R( e, a, b, c, d, F1,  6 ); W_PRECALC_16_31_2(22, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
+  R( d, e, a, b, c, F1,  7 ); W_PRECALC_16_31_3(23, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
+  R( c, d, e, a, b, F1,  8 ); W_PRECALC_16_31_0(24, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
+  R( b, c, d, e, a, F1,  9 ); W_PRECALC_16_31_1(25, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
+  R( a, b, c, d, e, F1, 10 ); W_PRECALC_16_31_2(26, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
+  R( e, a, b, c, d, F1, 11 ); W_PRECALC_16_31_3(27, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
+  R( d, e, a, b, c, F1, 12 ); W_PRECALC_16_31_0(28, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
+  R( c, d, e, a, b, F1, 13 ); W_PRECALC_16_31_1(29, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
+  R( b, c, d, e, a, F1, 14 ); W_PRECALC_16_31_2(30, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
+  R( a, b, c, d, e, F1, 15 ); W_PRECALC_16_31_3(31, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
+
+  /* Transform 16-63 + Precalc 32-79. */
+  R( e, a, b, c, d, F1, 16 ); W_PRECALC_32_79_0(32, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+  R( d, e, a, b, c, F1, 17 ); W_PRECALC_32_79_1(33, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+  R( c, d, e, a, b, F1, 18 ); W_PRECALC_32_79_2(34, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+  R( b, c, d, e, a, F1, 19 ); W_PRECALC_32_79_3(35, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+  R( a, b, c, d, e, F2, 20 ); W_PRECALC_32_79_0(36, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+  R( e, a, b, c, d, F2, 21 ); W_PRECALC_32_79_1(37, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+  R( d, e, a, b, c, F2, 22 ); W_PRECALC_32_79_2(38, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+  R( c, d, e, a, b, F2, 23 ); W_PRECALC_32_79_3(39, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+  R( b, c, d, e, a, F2, 24 ); W_PRECALC_32_79_0(40, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+  R( a, b, c, d, e, F2, 25 ); W_PRECALC_32_79_1(41, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+  R( e, a, b, c, d, F2, 26 ); W_PRECALC_32_79_2(42, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+  R( d, e, a, b, c, F2, 27 ); W_PRECALC_32_79_3(43, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+  R( c, d, e, a, b, F2, 28 ); W_PRECALC_32_79_0(44, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+  R( b, c, d, e, a, F2, 29 ); W_PRECALC_32_79_1(45, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+  R( a, b, c, d, e, F2, 30 ); W_PRECALC_32_79_2(46, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+  R( e, a, b, c, d, F2, 31 ); W_PRECALC_32_79_3(47, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+  R( d, e, a, b, c, F2, 32 ); W_PRECALC_32_79_0(48, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
+  R( c, d, e, a, b, F2, 33 ); W_PRECALC_32_79_1(49, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
+  R( b, c, d, e, a, F2, 34 ); W_PRECALC_32_79_2(50, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
+  R( a, b, c, d, e, F2, 35 ); W_PRECALC_32_79_3(51, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
+  R( e, a, b, c, d, F2, 36 ); W_PRECALC_32_79_0(52, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
+  R( d, e, a, b, c, F2, 37 ); W_PRECALC_32_79_1(53, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
+  R( c, d, e, a, b, F2, 38 ); W_PRECALC_32_79_2(54, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
+  R( b, c, d, e, a, F2, 39 ); W_PRECALC_32_79_3(55, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
+  R( a, b, c, d, e, F3, 40 ); W_PRECALC_32_79_0(56, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
+  R( e, a, b, c, d, F3, 41 ); W_PRECALC_32_79_1(57, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
+  R( d, e, a, b, c, F3, 42 ); W_PRECALC_32_79_2(58, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
+  R( c, d, e, a, b, F3, 43 ); W_PRECALC_32_79_3(59, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
+  R( b, c, d, e, a, F3, 44 ); W_PRECALC_32_79_0(60, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
+  R( a, b, c, d, e, F3, 45 ); W_PRECALC_32_79_1(61, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
+  R( e, a, b, c, d, F3, 46 ); W_PRECALC_32_79_2(62, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
+  R( d, e, a, b, c, F3, 47 ); W_PRECALC_32_79_3(63, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
+  R( c, d, e, a, b, F3, 48 ); W_PRECALC_32_79_0(64, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+  R( b, c, d, e, a, F3, 49 ); W_PRECALC_32_79_1(65, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+  R( a, b, c, d, e, F3, 50 ); W_PRECALC_32_79_2(66, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+  R( e, a, b, c, d, F3, 51 ); W_PRECALC_32_79_3(67, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+  R( d, e, a, b, c, F3, 52 ); W_PRECALC_32_79_0(68, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+  R( c, d, e, a, b, F3, 53 ); W_PRECALC_32_79_1(69, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+  R( b, c, d, e, a, F3, 54 ); W_PRECALC_32_79_2(70, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+  R( a, b, c, d, e, F3, 55 ); W_PRECALC_32_79_3(71, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+  R( e, a, b, c, d, F3, 56 ); W_PRECALC_32_79_0(72, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+  R( d, e, a, b, c, F3, 57 ); W_PRECALC_32_79_1(73, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+  R( c, d, e, a, b, F3, 58 ); W_PRECALC_32_79_2(74, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+  R( b, c, d, e, a, F3, 59 ); W_PRECALC_32_79_3(75, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+  R( a, b, c, d, e, F4, 60 ); W_PRECALC_32_79_0(76, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+  R( e, a, b, c, d, F4, 61 ); W_PRECALC_32_79_1(77, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+  R( d, e, a, b, c, F4, 62 ); W_PRECALC_32_79_2(78, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+  R( c, d, e, a, b, F4, 63 ); W_PRECALC_32_79_3(79, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+
+  decq RNBLKS;
+  jz .Lend;
+
+  /* Transform 64-79 + Precalc 0-15 of next block. */
+  R( b, c, d, e, a, F4, 64 ); W_PRECALC_00_15_0(0, W0, Wtmp0);
+  R( a, b, c, d, e, F4, 65 ); W_PRECALC_00_15_1(1, W0, Wtmp0);
+  R( e, a, b, c, d, F4, 66 ); W_PRECALC_00_15_2(2, W0, Wtmp0);
+  R( d, e, a, b, c, F4, 67 ); W_PRECALC_00_15_3(3, W0, Wtmp0);
+  R( c, d, e, a, b, F4, 68 ); W_PRECALC_00_15_0(4, W7, Wtmp0);
+  R( b, c, d, e, a, F4, 69 ); W_PRECALC_00_15_1(5, W7, Wtmp0);
+  R( a, b, c, d, e, F4, 70 ); W_PRECALC_00_15_2(6, W7, Wtmp0);
+  R( e, a, b, c, d, F4, 71 ); W_PRECALC_00_15_3(7, W7, Wtmp0);
+  R( d, e, a, b, c, F4, 72 ); W_PRECALC_00_15_0(8, W6, Wtmp0);
+  R( c, d, e, a, b, F4, 73 ); W_PRECALC_00_15_1(9, W6, Wtmp0);
+  R( b, c, d, e, a, F4, 74 ); W_PRECALC_00_15_2(10, W6, Wtmp0);
+  R( a, b, c, d, e, F4, 75 ); W_PRECALC_00_15_3(11, W6, Wtmp0);
+  R( e, a, b, c, d, F4, 76 ); W_PRECALC_00_15_0(12, W5, Wtmp0);
+  R( d, e, a, b, c, F4, 77 ); W_PRECALC_00_15_1(13, W5, Wtmp0);
+  R( c, d, e, a, b, F4, 78 );
+  addl state_h0(RSTATE), a;   W_PRECALC_00_15_2(14, W5, Wtmp0);
+  R( b, c, d, e, a, F4, 79 ); W_PRECALC_00_15_3(15, W5, Wtmp0);
+
+  /* Update the chaining variables. */
+  addl state_h3(RSTATE), d;
+  addl state_h2(RSTATE), c;
+  addl state_h1(RSTATE), b;
+  addl state_h4(RSTATE), e;
+
+  movl d, state_h3(RSTATE);
+  movl c, state_h2(RSTATE);
+  movl b, state_h1(RSTATE);
+  movl a, state_h0(RSTATE);
+  movl e, state_h4(RSTATE);
+
+  jmp .Loop;
+
+.align 16
+.Lend:
+  vzeroall;
+
+  /* Transform 64-79. */
+  R( b, c, d, e, a, F4, 64 );
+  R( a, b, c, d, e, F4, 65 );
+  R( e, a, b, c, d, F4, 66 );
+  R( d, e, a, b, c, F4, 67 );
+  R( c, d, e, a, b, F4, 68 );
+  R( b, c, d, e, a, F4, 69 );
+  R( a, b, c, d, e, F4, 70 );
+  R( e, a, b, c, d, F4, 71 );
+  R( d, e, a, b, c, F4, 72 );
+  R( c, d, e, a, b, F4, 73 );
+  R( b, c, d, e, a, F4, 74 );
+  R( a, b, c, d, e, F4, 75 );
+  R( e, a, b, c, d, F4, 76 );
+  R( d, e, a, b, c, F4, 77 );
+  R( c, d, e, a, b, F4, 78 );
+  addl state_h0(RSTATE), a;
+  R( b, c, d, e, a, F4, 79 );
+
+  /* Update the chaining variables. */
+  addl state_h3(RSTATE), d;
+  addl state_h2(RSTATE), c;
+  addl state_h1(RSTATE), b;
+  addl state_h4(RSTATE), e;
+
+  movl d, state_h3(RSTATE);
+  movl c, state_h2(RSTATE);
+  movl b, state_h1(RSTATE);
+  movl a, state_h0(RSTATE);
+  movl e, state_h4(RSTATE);
+
+  movq ROLDSTACK, %rsp;
+
+  popq %rbp;
+  popq %rbx;
+
+  /* burn_stack */
+  movl $(16*4 + 2*8 + 31), %eax;
+
+.Lret:
+  ret;
+
+#endif
+#endif
diff --git a/cipher/sha1-avx-bmi2-amd64.S b/cipher/sha1-avx-bmi2-amd64.S
new file mode 100644 (file)
index 0000000..22bcbb3
--- /dev/null
@@ -0,0 +1,425 @@
+/* sha1-avx-bmi2-amd64.S - Intel AVX/BMI2 accelerated SHA-1 transform function
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * Based on sha1.c:
+ *  Copyright (C) 1998, 2001, 2002, 2003, 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Intel SSSE3 accelerated SHA-1 implementation based on white paper:
+ *  "Improving the Performance of the Secure Hash Algorithm (SHA-1)"
+ *  http://software.intel.com/en-us/articles/improving-the-performance-of-the-secure-hash-algorithm-1
+ */
+
+#ifdef __x86_64__
+#include <config.h>
+
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
+    defined(HAVE_GCC_INLINE_ASM_BMI2) && \
+    defined(HAVE_GCC_INLINE_ASM_AVX) && defined(USE_SHA1)
+
+#ifdef __PIC__
+#  define RIP (%rip)
+#else
+#  define RIP
+#endif
+
+
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
+
+
+/* Context structure */
+
+#define state_h0 0
+#define state_h1 4
+#define state_h2 8
+#define state_h3 12
+#define state_h4 16
+
+
+/* Constants */
+
+.data
+#define K1  0x5A827999
+#define K2  0x6ED9EBA1
+#define K3  0x8F1BBCDC
+#define K4  0xCA62C1D6
+.align 16
+.LK_XMM:
+.LK1:  .long K1, K1, K1, K1
+.LK2:  .long K2, K2, K2, K2
+.LK3:  .long K3, K3, K3, K3
+.LK4:  .long K4, K4, K4, K4
+
+.Lbswap_shufb_ctl:
+       .long 0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f
+
+
+/* Register macros */
+
+#define RSTATE %r8
+#define RDATA %r9
+#define ROLDSTACK %r10
+#define RNBLKS %r11
+
+#define a %eax
+#define b %ebx
+#define c %ecx
+#define d %edx
+#define e %edi
+
+#define RT0 %esi
+#define RT1 %ebp
+
+#define Wtmp0 %xmm0
+#define Wtmp1 %xmm1
+
+#define W0 %xmm2
+#define W1 %xmm3
+#define W2 %xmm4
+#define W3 %xmm5
+#define W4 %xmm6
+#define W5 %xmm7
+#define W6 %xmm8
+#define W7 %xmm9
+
+#define BSWAP_REG %xmm10
+
+
+/* Round function macros. */
+
+#define WK(i) (((i) & 15) * 4)(%rsp)
+
+#define R_F1(a,b,c,d,e,i) \
+       movl c, RT0; \
+       andn d, b, RT1; \
+       addl WK(i), e; \
+       andl b, RT0; \
+       rorxl $2, b, b; \
+       addl RT1, e; \
+       leal (RT0,e), e; \
+       rorxl $27, a, RT1; \
+       addl RT1, e;
+
+#define R_F2(a,b,c,d,e,i) \
+       movl c, RT0; \
+       addl WK(i), e; \
+       xorl b, RT0; \
+       rorxl $2, b, b; \
+       xorl d, RT0; \
+       leal (RT0,e), e; \
+       rorxl $27, a, RT1; \
+       addl RT1, e;
+
+#define R_F3(a,b,c,d,e,i) \
+       movl c, RT0; \
+       movl b, RT1; \
+       xorl b, RT0; \
+       andl c, RT1; \
+       andl d, RT0; \
+       addl RT1, e; \
+       addl WK(i), e; \
+       rorxl $2, b, b; \
+       leal (RT0,e), e; \
+       rorxl $27, a, RT1; \
+       addl RT1, e;
+
+#define R_F4(a,b,c,d,e,i) R_F2(a,b,c,d,e,i)
+
+#define R(a,b,c,d,e,f,i) \
+       R_##f(a,b,c,d,e,i)
+
+
+/* Input expansion macros. */
+
+#define W_PRECALC_00_15_0(i, W, tmp0) \
+       vmovdqu (4*(i))(RDATA), tmp0;
+
+#define W_PRECALC_00_15_1(i, W, tmp0) \
+       vpshufb BSWAP_REG, tmp0, W;
+
+#define W_PRECALC_00_15_2(i, W, tmp0) \
+       vpaddd (.LK_XMM + ((i)/20)*16) RIP, W, tmp0;
+
+#define W_PRECALC_00_15_3(i, W, tmp0) \
+       vmovdqa tmp0, WK(i&~3);
+
+#define W_PRECALC_16_31_0(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
+       vpalignr $8, W_m16, W_m12, W; \
+       vpsrldq $4, W_m04, tmp0; \
+       vpxor W_m08, W, W;
+
+#define W_PRECALC_16_31_1(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
+       vpxor W_m16, tmp0, tmp0; \
+       vpxor tmp0, W, W; \
+       vpslld $1, W, tmp0; \
+       vpslldq $12, W, tmp1; \
+       vpsrld $31, W, W;
+
+#define W_PRECALC_16_31_2(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
+       vpor W, tmp0, tmp0; \
+       vpsrld $30, tmp1, W; \
+       vpslld $2, tmp1, tmp1;
+
+#define W_PRECALC_16_31_3(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
+       vpxor W, tmp0, tmp0; \
+       vpxor tmp1, tmp0, W; \
+       vpaddd (.LK_XMM + ((i)/20)*16) RIP, W, tmp0; \
+       vmovdqa tmp0, WK((i)&~3);
+
+#define W_PRECALC_32_79_0(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
+       vpxor W_m28, W, W; \
+       vpalignr $8, W_m08, W_m04, tmp0;
+
+#define W_PRECALC_32_79_1(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
+       vpxor W_m16, W, W; \
+       vpxor tmp0, W, W;
+
+#define W_PRECALC_32_79_2(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
+       vpsrld $30, W, tmp0; \
+       vpslld $2, W, W;
+
+#define W_PRECALC_32_79_3(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
+       vpor W, tmp0, W; \
+       vpaddd (.LK_XMM + ((i)/20)*16) RIP, W, tmp0; \
+       vmovdqa tmp0, WK((i)&~3);
+
+
+/*
+ * Transform nblks*64 bytes (nblks*16 32-bit words) at DATA.
+ *
+ * unsigned int
+ * _gcry_sha1_transform_amd64_avx_bmi2 (void *ctx, const unsigned char *data,
+ *                                      size_t nblks)
+ */
+.text
+.globl _gcry_sha1_transform_amd64_avx_bmi2
+ELF(.type _gcry_sha1_transform_amd64_avx_bmi2,@function)
+.align 16
+_gcry_sha1_transform_amd64_avx_bmi2:
+  /* input:
+   *   %rdi: ctx, CTX
+   *   %rsi: data (64*nblks bytes)
+   *   %rdx: nblks
+   */
+
+  xorl %eax, %eax;
+  cmpq $0, %rdx;
+  jz .Lret;
+
+  vzeroupper;
+
+  movq %rdx, RNBLKS;
+  movq %rdi, RSTATE;
+  movq %rsi, RDATA;
+  pushq %rbx;
+  pushq %rbp;
+
+  movq %rsp, ROLDSTACK;
+
+  subq $(16*4), %rsp;
+  andq $(~31), %rsp;
+
+  /* Get the values of the chaining variables. */
+  movl state_h0(RSTATE), a;
+  movl state_h1(RSTATE), b;
+  movl state_h2(RSTATE), c;
+  movl state_h3(RSTATE), d;
+  movl state_h4(RSTATE), e;
+
+  movdqa .Lbswap_shufb_ctl RIP, BSWAP_REG;
+
+  /* Precalc 0-15. */
+  W_PRECALC_00_15_0(0, W0, Wtmp0);
+  W_PRECALC_00_15_1(1, W0, Wtmp0);
+  W_PRECALC_00_15_2(2, W0, Wtmp0);
+  W_PRECALC_00_15_3(3, W0, Wtmp0);
+  W_PRECALC_00_15_0(4, W7, Wtmp0);
+  W_PRECALC_00_15_1(5, W7, Wtmp0);
+  W_PRECALC_00_15_2(6, W7, Wtmp0);
+  W_PRECALC_00_15_3(7, W7, Wtmp0);
+  W_PRECALC_00_15_0(8, W6, Wtmp0);
+  W_PRECALC_00_15_1(9, W6, Wtmp0);
+  W_PRECALC_00_15_2(10, W6, Wtmp0);
+  W_PRECALC_00_15_3(11, W6, Wtmp0);
+  W_PRECALC_00_15_0(12, W5, Wtmp0);
+  W_PRECALC_00_15_1(13, W5, Wtmp0);
+  W_PRECALC_00_15_2(14, W5, Wtmp0);
+  W_PRECALC_00_15_3(15, W5, Wtmp0);
+
+.align 8
+.Loop:
+  addq $64, RDATA;
+
+  /* Transform 0-15 + Precalc 16-31. */
+  R( a, b, c, d, e, F1,  0 ); W_PRECALC_16_31_0(16, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
+  R( e, a, b, c, d, F1,  1 ); W_PRECALC_16_31_1(17, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
+  R( d, e, a, b, c, F1,  2 ); W_PRECALC_16_31_2(18, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
+  R( c, d, e, a, b, F1,  3 ); W_PRECALC_16_31_3(19, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
+  R( b, c, d, e, a, F1,  4 ); W_PRECALC_16_31_0(20, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
+  R( a, b, c, d, e, F1,  5 ); W_PRECALC_16_31_1(21, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
+  R( e, a, b, c, d, F1,  6 ); W_PRECALC_16_31_2(22, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
+  R( d, e, a, b, c, F1,  7 ); W_PRECALC_16_31_3(23, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
+  R( c, d, e, a, b, F1,  8 ); W_PRECALC_16_31_0(24, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
+  R( b, c, d, e, a, F1,  9 ); W_PRECALC_16_31_1(25, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
+  R( a, b, c, d, e, F1, 10 ); W_PRECALC_16_31_2(26, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
+  R( e, a, b, c, d, F1, 11 ); W_PRECALC_16_31_3(27, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
+  R( d, e, a, b, c, F1, 12 ); W_PRECALC_16_31_0(28, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
+  R( c, d, e, a, b, F1, 13 ); W_PRECALC_16_31_1(29, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
+  R( b, c, d, e, a, F1, 14 ); W_PRECALC_16_31_2(30, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
+  R( a, b, c, d, e, F1, 15 ); W_PRECALC_16_31_3(31, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
+
+  /* Transform 16-63 + Precalc 32-79. */
+  R( e, a, b, c, d, F1, 16 ); W_PRECALC_32_79_0(32, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+  R( d, e, a, b, c, F1, 17 ); W_PRECALC_32_79_1(33, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+  R( c, d, e, a, b, F1, 18 ); W_PRECALC_32_79_2(34, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+  R( b, c, d, e, a, F1, 19 ); W_PRECALC_32_79_3(35, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+  R( a, b, c, d, e, F2, 20 ); W_PRECALC_32_79_0(36, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+  R( e, a, b, c, d, F2, 21 ); W_PRECALC_32_79_1(37, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+  R( d, e, a, b, c, F2, 22 ); W_PRECALC_32_79_2(38, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+  R( c, d, e, a, b, F2, 23 ); W_PRECALC_32_79_3(39, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+  R( b, c, d, e, a, F2, 24 ); W_PRECALC_32_79_0(40, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+  R( a, b, c, d, e, F2, 25 ); W_PRECALC_32_79_1(41, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+  R( e, a, b, c, d, F2, 26 ); W_PRECALC_32_79_2(42, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+  R( d, e, a, b, c, F2, 27 ); W_PRECALC_32_79_3(43, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+  R( c, d, e, a, b, F2, 28 ); W_PRECALC_32_79_0(44, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+  R( b, c, d, e, a, F2, 29 ); W_PRECALC_32_79_1(45, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+  R( a, b, c, d, e, F2, 30 ); W_PRECALC_32_79_2(46, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+  R( e, a, b, c, d, F2, 31 ); W_PRECALC_32_79_3(47, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+  R( d, e, a, b, c, F2, 32 ); W_PRECALC_32_79_0(48, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
+  R( c, d, e, a, b, F2, 33 ); W_PRECALC_32_79_1(49, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
+  R( b, c, d, e, a, F2, 34 ); W_PRECALC_32_79_2(50, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
+  R( a, b, c, d, e, F2, 35 ); W_PRECALC_32_79_3(51, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
+  R( e, a, b, c, d, F2, 36 ); W_PRECALC_32_79_0(52, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
+  R( d, e, a, b, c, F2, 37 ); W_PRECALC_32_79_1(53, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
+  R( c, d, e, a, b, F2, 38 ); W_PRECALC_32_79_2(54, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
+  R( b, c, d, e, a, F2, 39 ); W_PRECALC_32_79_3(55, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
+  R( a, b, c, d, e, F3, 40 ); W_PRECALC_32_79_0(56, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
+  R( e, a, b, c, d, F3, 41 ); W_PRECALC_32_79_1(57, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
+  R( d, e, a, b, c, F3, 42 ); W_PRECALC_32_79_2(58, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
+  R( c, d, e, a, b, F3, 43 ); W_PRECALC_32_79_3(59, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
+  R( b, c, d, e, a, F3, 44 ); W_PRECALC_32_79_0(60, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
+  R( a, b, c, d, e, F3, 45 ); W_PRECALC_32_79_1(61, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
+  R( e, a, b, c, d, F3, 46 ); W_PRECALC_32_79_2(62, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
+  R( d, e, a, b, c, F3, 47 ); W_PRECALC_32_79_3(63, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
+  R( c, d, e, a, b, F3, 48 ); W_PRECALC_32_79_0(64, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+  R( b, c, d, e, a, F3, 49 ); W_PRECALC_32_79_1(65, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+  R( a, b, c, d, e, F3, 50 ); W_PRECALC_32_79_2(66, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+  R( e, a, b, c, d, F3, 51 ); W_PRECALC_32_79_3(67, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+  R( d, e, a, b, c, F3, 52 ); W_PRECALC_32_79_0(68, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+  R( c, d, e, a, b, F3, 53 ); W_PRECALC_32_79_1(69, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+  R( b, c, d, e, a, F3, 54 ); W_PRECALC_32_79_2(70, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+  R( a, b, c, d, e, F3, 55 ); W_PRECALC_32_79_3(71, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+  R( e, a, b, c, d, F3, 56 ); W_PRECALC_32_79_0(72, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+  R( d, e, a, b, c, F3, 57 ); W_PRECALC_32_79_1(73, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+  R( c, d, e, a, b, F3, 58 ); W_PRECALC_32_79_2(74, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+  R( b, c, d, e, a, F3, 59 ); W_PRECALC_32_79_3(75, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+  R( a, b, c, d, e, F4, 60 ); W_PRECALC_32_79_0(76, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+  R( e, a, b, c, d, F4, 61 ); W_PRECALC_32_79_1(77, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+  R( d, e, a, b, c, F4, 62 ); W_PRECALC_32_79_2(78, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+  R( c, d, e, a, b, F4, 63 ); W_PRECALC_32_79_3(79, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+
+  decq RNBLKS;
+  jz .Lend;
+
+  /* Transform 64-79 + Precalc 0-15 of next block. */
+  R( b, c, d, e, a, F4, 64 ); W_PRECALC_00_15_0(0, W0, Wtmp0);
+  R( a, b, c, d, e, F4, 65 ); W_PRECALC_00_15_1(1, W0, Wtmp0);
+  R( e, a, b, c, d, F4, 66 ); W_PRECALC_00_15_2(2, W0, Wtmp0);
+  R( d, e, a, b, c, F4, 67 ); W_PRECALC_00_15_3(3, W0, Wtmp0);
+  R( c, d, e, a, b, F4, 68 ); W_PRECALC_00_15_0(4, W7, Wtmp0);
+  R( b, c, d, e, a, F4, 69 ); W_PRECALC_00_15_1(5, W7, Wtmp0);
+  R( a, b, c, d, e, F4, 70 ); W_PRECALC_00_15_2(6, W7, Wtmp0);
+  R( e, a, b, c, d, F4, 71 ); W_PRECALC_00_15_3(7, W7, Wtmp0);
+  R( d, e, a, b, c, F4, 72 ); W_PRECALC_00_15_0(8, W6, Wtmp0);
+  R( c, d, e, a, b, F4, 73 ); W_PRECALC_00_15_1(9, W6, Wtmp0);
+  R( b, c, d, e, a, F4, 74 ); W_PRECALC_00_15_2(10, W6, Wtmp0);
+  R( a, b, c, d, e, F4, 75 ); W_PRECALC_00_15_3(11, W6, Wtmp0);
+  R( e, a, b, c, d, F4, 76 ); W_PRECALC_00_15_0(12, W5, Wtmp0);
+  R( d, e, a, b, c, F4, 77 ); W_PRECALC_00_15_1(13, W5, Wtmp0);
+  R( c, d, e, a, b, F4, 78 );
+  addl state_h0(RSTATE), a;   W_PRECALC_00_15_2(14, W5, Wtmp0);
+  R( b, c, d, e, a, F4, 79 ); W_PRECALC_00_15_3(15, W5, Wtmp0);
+
+  /* Update the chaining variables. */
+  addl state_h3(RSTATE), d;
+  addl state_h2(RSTATE), c;
+  addl state_h1(RSTATE), b;
+  addl state_h4(RSTATE), e;
+
+  movl d, state_h3(RSTATE);
+  movl c, state_h2(RSTATE);
+  movl b, state_h1(RSTATE);
+  movl a, state_h0(RSTATE);
+  movl e, state_h4(RSTATE);
+
+  jmp .Loop;
+
+.align 16
+.Lend:
+  vzeroall;
+
+  /* Transform 64-79. */
+  R( b, c, d, e, a, F4, 64 );
+  R( a, b, c, d, e, F4, 65 );
+  R( e, a, b, c, d, F4, 66 );
+  R( d, e, a, b, c, F4, 67 );
+  R( c, d, e, a, b, F4, 68 );
+  R( b, c, d, e, a, F4, 69 );
+  R( a, b, c, d, e, F4, 70 );
+  R( e, a, b, c, d, F4, 71 );
+  R( d, e, a, b, c, F4, 72 );
+  R( c, d, e, a, b, F4, 73 );
+  R( b, c, d, e, a, F4, 74 );
+  R( a, b, c, d, e, F4, 75 );
+  R( e, a, b, c, d, F4, 76 );
+  R( d, e, a, b, c, F4, 77 );
+  R( c, d, e, a, b, F4, 78 );
+  addl state_h0(RSTATE), a;
+  R( b, c, d, e, a, F4, 79 );
+
+  /* Update the chaining variables. */
+  addl state_h3(RSTATE), d;
+  addl state_h2(RSTATE), c;
+  addl state_h1(RSTATE), b;
+  addl state_h4(RSTATE), e;
+
+  movl d, state_h3(RSTATE);
+  movl c, state_h2(RSTATE);
+  movl b, state_h1(RSTATE);
+  movl a, state_h0(RSTATE);
+  movl e, state_h4(RSTATE);
+
+  movq ROLDSTACK, %rsp;
+
+  popq %rbp;
+  popq %rbx;
+
+  /* burn_stack */
+  movl $(16*4 + 2*8 + 31), %eax;
+
+.Lret:
+  ret;
+
+#endif
+#endif
index 5e5716b..98a19e6 100644 (file)
@@ -1,5 +1,5 @@
 /* sha1-ssse3-amd64.S - Intel SSSE3 accelerated SHA-1 transform function
- * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * Based on sha1.c:
  *  Copyright (C) 1998, 2001, 2002, 2003, 2008 Free Software Foundation, Inc.
@@ -29,7 +29,8 @@
 #ifdef __x86_64__
 #include <config.h>
 
-#if defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && \
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
     defined(HAVE_GCC_INLINE_ASM_SSSE3) && defined(USE_SHA1)
 
 #ifdef __PIC__
 #endif
 
 
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
+
+
 /* Context structure */
 
 #define state_h0 0
@@ -71,6 +79,7 @@
 #define RSTATE %r8
 #define RDATA %r9
 #define ROLDSTACK %r10
+#define RNBLKS %r11
 
 #define a %eax
 #define b %ebx
 
 
 /*
- * Transform 64 bytes (16 32-bit words) at DATA.
+ * Transform nblks*64 bytes (nblks*16 32-bit words) at DATA.
  *
  * unsigned int
- * _gcry_sha1_transform_amd64_ssse3 (void *ctx, const unsigned char *data)
+ * _gcry_sha1_transform_amd64_ssse3 (void *ctx, const unsigned char *data,
+ *                                   size_t nblks)
  */
 .text
 .globl _gcry_sha1_transform_amd64_ssse3
-.type _gcry_sha1_transform_amd64_ssse3,@function
+ELF(.type _gcry_sha1_transform_amd64_ssse3,@function)
 .align 16
 _gcry_sha1_transform_amd64_ssse3:
   /* input:
    *   %rdi: ctx, CTX
-   *   %rsi: data (64 bytes)
-   *   %rdx: ...
+   *   %rsi: data (64*nblks bytes)
+   *   %rdx: nblks
    */
 
+  xorl %eax, %eax;
+  cmpq $0, %rdx;
+  jz .Lret;
+
+  movq %rdx, RNBLKS;
   movq %rdi, RSTATE;
   movq %rsi, RDATA;
   pushq %rbx;
@@ -264,6 +279,10 @@ _gcry_sha1_transform_amd64_ssse3:
   W_PRECALC_00_15_2(14, W5, Wtmp0);
   W_PRECALC_00_15_3(15, W5, Wtmp0);
 
+.align 8
+.Loop:
+  addq $64, RDATA;
+
   /* Transform 0-15 + Precalc 16-31. */
   R( a, b, c, d, e, F1,  0 ); W_PRECALC_16_31_0(16, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
   R( e, a, b, c, d, F1,  1 ); W_PRECALC_16_31_1(17, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
@@ -332,6 +351,44 @@ _gcry_sha1_transform_amd64_ssse3:
   R( d, e, a, b, c, F4, 62 ); W_PRECALC_32_79_2(78, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
   R( c, d, e, a, b, F4, 63 ); W_PRECALC_32_79_3(79, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
 
+  decq RNBLKS;
+  jz .Lend;
+
+  /* Transform 64-79 + Precalc 0-15 of next block. */
+  R( b, c, d, e, a, F4, 64 ); W_PRECALC_00_15_0(0, W0, Wtmp0);
+  R( a, b, c, d, e, F4, 65 ); W_PRECALC_00_15_1(1, W0, Wtmp0);
+  R( e, a, b, c, d, F4, 66 ); W_PRECALC_00_15_2(2, W0, Wtmp0);
+  R( d, e, a, b, c, F4, 67 ); W_PRECALC_00_15_3(3, W0, Wtmp0);
+  R( c, d, e, a, b, F4, 68 ); W_PRECALC_00_15_0(4, W7, Wtmp0);
+  R( b, c, d, e, a, F4, 69 ); W_PRECALC_00_15_1(5, W7, Wtmp0);
+  R( a, b, c, d, e, F4, 70 ); W_PRECALC_00_15_2(6, W7, Wtmp0);
+  R( e, a, b, c, d, F4, 71 ); W_PRECALC_00_15_3(7, W7, Wtmp0);
+  R( d, e, a, b, c, F4, 72 ); W_PRECALC_00_15_0(8, W6, Wtmp0);
+  R( c, d, e, a, b, F4, 73 ); W_PRECALC_00_15_1(9, W6, Wtmp0);
+  R( b, c, d, e, a, F4, 74 ); W_PRECALC_00_15_2(10, W6, Wtmp0);
+  R( a, b, c, d, e, F4, 75 ); W_PRECALC_00_15_3(11, W6, Wtmp0);
+  R( e, a, b, c, d, F4, 76 ); W_PRECALC_00_15_0(12, W5, Wtmp0);
+  R( d, e, a, b, c, F4, 77 ); W_PRECALC_00_15_1(13, W5, Wtmp0);
+  R( c, d, e, a, b, F4, 78 );
+  addl state_h0(RSTATE), a;   W_PRECALC_00_15_2(14, W5, Wtmp0);
+  R( b, c, d, e, a, F4, 79 ); W_PRECALC_00_15_3(15, W5, Wtmp0);
+
+  /* Update the chaining variables. */
+  addl state_h3(RSTATE), d;
+  addl state_h2(RSTATE), c;
+  addl state_h1(RSTATE), b;
+  addl state_h4(RSTATE), e;
+
+  movl d, state_h3(RSTATE);
+  movl c, state_h2(RSTATE);
+  movl b, state_h1(RSTATE);
+  movl a, state_h0(RSTATE);
+  movl e, state_h4(RSTATE);
+
+  jmp .Loop;
+
+.align 16
+.Lend:
   /* Transform 64-79 + Clear XMM registers. */
   R( b, c, d, e, a, F4, 64 ); CLEAR_REG(BSWAP_REG);
   R( a, b, c, d, e, F4, 65 ); CLEAR_REG(Wtmp0);
@@ -348,19 +405,19 @@ _gcry_sha1_transform_amd64_ssse3:
   R( e, a, b, c, d, F4, 76 );
   R( d, e, a, b, c, F4, 77 );
   R( c, d, e, a, b, F4, 78 );
+  addl state_h0(RSTATE), a;
   R( b, c, d, e, a, F4, 79 );
 
   /* Update the chaining variables. */
-  addl state_h0(RSTATE), a;
-  addl state_h1(RSTATE), b;
-  addl state_h2(RSTATE), c;
   addl state_h3(RSTATE), d;
+  addl state_h2(RSTATE), c;
+  addl state_h1(RSTATE), b;
   addl state_h4(RSTATE), e;
 
-  movl a, state_h0(RSTATE);
-  movl b, state_h1(RSTATE);
-  movl c, state_h2(RSTATE);
   movl d, state_h3(RSTATE);
+  movl c, state_h2(RSTATE);
+  movl b, state_h1(RSTATE);
+  movl a, state_h0(RSTATE);
   movl e, state_h4(RSTATE);
 
   movq ROLDSTACK, %rsp;
@@ -371,6 +428,7 @@ _gcry_sha1_transform_amd64_ssse3:
   /* burn_stack */
   movl $(16*4 + 2*8 + 31), %eax;
 
+.Lret:
   ret;
 
 #endif
index 2e0b030..d15c2a2 100644 (file)
 #include "bithelp.h"
 #include "bufhelp.h"
 #include "cipher.h"
-#include "hash-common.h"
+#include "sha1.h"
 
 
 /* USE_SSSE3 indicates whether to compile with Intel SSSE3 code. */
 #undef USE_SSSE3
-#if defined(__x86_64__) && defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && \
-    defined(HAVE_GCC_INLINE_ASM_SSSE3)
+#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_SSSE3) && \
+    (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
 # define USE_SSSE3 1
 #endif
 
+/* USE_AVX indicates whether to compile with Intel AVX code. */
+#undef USE_AVX
+#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX) && \
+    (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define USE_AVX 1
+#endif
+
+/* USE_BMI2 indicates whether to compile with Intel AVX/BMI2 code. */
+#undef USE_BMI2
+#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX) && \
+    defined(HAVE_GCC_INLINE_ASM_BMI2) && \
+    (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define USE_BMI2 1
+#endif
+
+/* USE_NEON indicates whether to enable ARM NEON assembly code. */
+#undef USE_NEON
+#ifdef ENABLE_NEON_SUPPORT
+# if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) \
+     && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) \
+     && defined(HAVE_GCC_INLINE_ASM_NEON)
+#  define USE_NEON 1
+# endif
+#endif /*ENABLE_NEON_SUPPORT*/
+
 
 /* A macro to test whether P is properly aligned for an u32 type.
    Note that config.h provides a suitable replacement for uintptr_t if
 /* # define U32_ALIGNED_P(p) (!(((uintptr_t)p) % sizeof (u32))) */
 /* #endif */
 
-typedef struct
-{
-  gcry_md_block_ctx_t bctx;
-  u32           h0,h1,h2,h3,h4;
-#ifdef USE_SSSE3
-  unsigned int use_ssse3:1;
-#endif
-} SHA1_CONTEXT;
 
 static unsigned int
-transform (void *c, const unsigned char *data);
+transform (void *c, const unsigned char *data, size_t nblks);
 
 
 static void
 sha1_init (void *context, unsigned int flags)
 {
   SHA1_CONTEXT *hd = context;
+  unsigned int features = _gcry_get_hw_features ();
 
   (void)flags;
 
@@ -93,8 +114,31 @@ sha1_init (void *context, unsigned int flags)
   hd->bctx.bwrite = transform;
 
 #ifdef USE_SSSE3
-  hd->use_ssse3 = (_gcry_get_hw_features () & HWF_INTEL_SSSE3) != 0;
+  hd->use_ssse3 = (features & HWF_INTEL_SSSE3) != 0;
+#endif
+#ifdef USE_AVX
+  /* AVX implementation uses SHLD which is known to be slow on non-Intel CPUs.
+   * Therefore use this implementation on Intel CPUs only. */
+  hd->use_avx = (features & HWF_INTEL_AVX) && (features & HWF_INTEL_FAST_SHLD);
 #endif
+#ifdef USE_BMI2
+  hd->use_bmi2 = (features & HWF_INTEL_AVX) && (features & HWF_INTEL_BMI2);
+#endif
+#ifdef USE_NEON
+  hd->use_neon = (features & HWF_ARM_NEON) != 0;
+#endif
+  (void)features;
+}
+
+/*
+ * Initialize the context HD. This is used to prepare the use of
+ * _gcry_sha1_mixblock.  WARNING: This is a special purpose function
+ * for exclusive use by random-csprng.c.
+ */
+void
+_gcry_sha1_mixblock_init (SHA1_CONTEXT *hd)
+{
+  sha1_init (hd, 0);
 }
 
 
@@ -120,11 +164,18 @@ sha1_init (void *context, unsigned int flags)
                               } while(0)
 
 
+
+#ifdef USE_NEON
+unsigned int
+_gcry_sha1_transform_armv7_neon (void *state, const unsigned char *data,
+                                 size_t nblks);
+#endif
+
 /*
  * Transform NBLOCKS of each 64 bytes (16 32-bit words) at DATA.
  */
 static unsigned int
-_transform (void *ctx, const unsigned char *data)
+transform_blk (void *ctx, const unsigned char *data)
 {
   SHA1_CONTEXT *hd = ctx;
   const u32 *idata = (const void *)data;
@@ -234,24 +285,110 @@ _transform (void *ctx, const unsigned char *data)
 }
 
 
+/* Assembly implementations use SystemV ABI, ABI conversion and additional
+ * stack to store XMM6-XMM15 needed on Win64. */
+#undef ASM_FUNC_ABI
+#undef ASM_EXTRA_STACK
+#if defined(USE_SSSE3) || defined(USE_AVX) || defined(USE_BMI2)
+# ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+#  define ASM_FUNC_ABI __attribute__((sysv_abi))
+#  define ASM_EXTRA_STACK (10 * 16)
+# else
+#  define ASM_FUNC_ABI
+#  define ASM_EXTRA_STACK 0
+# endif
+#endif
+
+
 #ifdef USE_SSSE3
 unsigned int
-_gcry_sha1_transform_amd64_ssse3 (void *state, const unsigned char *data);
+_gcry_sha1_transform_amd64_ssse3 (void *state, const unsigned char *data,
+                                  size_t nblks) ASM_FUNC_ABI;
+#endif
+
+#ifdef USE_AVX
+unsigned int
+_gcry_sha1_transform_amd64_avx (void *state, const unsigned char *data,
+                                 size_t nblks) ASM_FUNC_ABI;
+#endif
+
+#ifdef USE_BMI2
+unsigned int
+_gcry_sha1_transform_amd64_avx_bmi2 (void *state, const unsigned char *data,
+                                     size_t nblks) ASM_FUNC_ABI;
 #endif
 
 
 static unsigned int
-transform (void *ctx, const unsigned char *data)
+transform (void *ctx, const unsigned char *data, size_t nblks)
 {
   SHA1_CONTEXT *hd = ctx;
+  unsigned int burn;
 
+#ifdef USE_BMI2
+  if (hd->use_bmi2)
+    return _gcry_sha1_transform_amd64_avx_bmi2 (&hd->h0, data, nblks)
+           + 4 * sizeof(void*) + ASM_EXTRA_STACK;
+#endif
+#ifdef USE_AVX
+  if (hd->use_avx)
+    return _gcry_sha1_transform_amd64_avx (&hd->h0, data, nblks)
+           + 4 * sizeof(void*) + ASM_EXTRA_STACK;
+#endif
 #ifdef USE_SSSE3
   if (hd->use_ssse3)
-    return _gcry_sha1_transform_amd64_ssse3 (&hd->h0, data)
+    return _gcry_sha1_transform_amd64_ssse3 (&hd->h0, data, nblks)
+           + 4 * sizeof(void*) + ASM_EXTRA_STACK;
+#endif
+#ifdef USE_NEON
+  if (hd->use_neon)
+    return _gcry_sha1_transform_armv7_neon (&hd->h0, data, nblks)
            + 4 * sizeof(void*);
 #endif
 
-  return _transform (hd, data);
+  do
+    {
+      burn = transform_blk (hd, data);
+      data += 64;
+    }
+  while (--nblks);
+
+#ifdef ASM_EXTRA_STACK
+  /* 'transform_blk' is typically inlined and XMM6-XMM15 are stored at
+   *  the prologue of this function. Therefore need to add ASM_EXTRA_STACK to
+   *  here too.
+   */
+  burn += ASM_EXTRA_STACK;
+#endif
+
+  return burn;
+}
+
+
+/*
+ * Apply the SHA-1 transform function on the buffer BLOCKOF64BYTE
+ * which must have a length 64 bytes.  BLOCKOF64BYTE must be 32-bit
+ * aligned.  Updates the 20 bytes in BLOCKOF64BYTE with its mixed
+ * content.  Returns the number of bytes which should be burned on the
+ * stack.  You need to use _gcry_sha1_mixblock_init to initialize the
+ * context.
+ * WARNING: This is a special purpose function for exclusive use by
+ * random-csprng.c.
+ */
+unsigned int
+_gcry_sha1_mixblock (SHA1_CONTEXT *hd, void *blockof64byte)
+{
+  u32 *p = blockof64byte;
+  unsigned int nburn;
+
+  nburn = transform (hd, blockof64byte, 1);
+  p[0] = hd->h0;
+  p[1] = hd->h1;
+  p[2] = hd->h2;
+  p[3] = hd->h3;
+  p[4] = hd->h4;
+
+  return nburn;
 }
 
 
@@ -308,11 +445,11 @@ sha1_final(void *context)
   /* append the 64 bit count */
   buf_put_be32(hd->bctx.buf + 56, msb);
   buf_put_be32(hd->bctx.buf + 60, lsb);
-  burn = transform( hd, hd->bctx.buf );
+  burn = transform( hd, hd->bctx.buf, 1 );
   _gcry_burn_stack (burn);
 
   p = hd->bctx.buf;
-#define X(a) do { *(u32*)p = be_bswap32(hd->h##a) ; p += 4; } while(0)
+#define X(a) do { buf_put_be32(p, hd->h##a); p += 4; } while(0)
   X(0);
   X(1);
   X(2);
@@ -457,7 +594,7 @@ gcry_md_spec_t _gcry_digest_spec_sha1 =
   {
     GCRY_MD_SHA1, {0, 1},
     "SHA1", asn, DIM (asn), oid_spec_sha1, 20,
-    sha1_init, _gcry_md_block_write, sha1_final, sha1_read,
+    sha1_init, _gcry_md_block_write, sha1_final, sha1_read, NULL,
     sizeof (SHA1_CONTEXT),
     run_selftests
   };
similarity index 54%
rename from cipher/rmd.h
rename to cipher/sha1.h
index a56ee49..6b87631 100644 (file)
@@ -1,5 +1,5 @@
-/* rmd.h - RIPE-MD hash functions
- *     Copyright (C) 1998, 2001, 2002 Free Software Foundation, Inc.
+/* sha1.h - SHA-1 context definition
+ * Copyright (C) 1998, 2001, 2002, 2003, 2008 Free Software Foundation, Inc.
  *
  * This file is part of Libgcrypt.
  *
  * GNU Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef G10_RMD_H
-#define G10_RMD_H
+#ifndef GCRY_SHA1_H
+#define GCRY_SHA1_H
 
 #include "hash-common.h"
 
-/* We need this here because random.c must have direct access. */
+/* We need this here for direct use by random-csprng.c. */
 typedef struct
 {
   gcry_md_block_ctx_t bctx;
-  u32  h0,h1,h2,h3,h4;
-} RMD160_CONTEXT;
+  u32          h0,h1,h2,h3,h4;
+  unsigned int use_ssse3:1;
+  unsigned int use_avx:1;
+  unsigned int use_bmi2:1;
+  unsigned int use_neon:1;
+} SHA1_CONTEXT;
 
-void _gcry_rmd160_init ( void *context );
-void _gcry_rmd160_mixblock ( RMD160_CONTEXT *hd, void *blockof64byte );
 
-#endif /*G10_RMD_H*/
+void _gcry_sha1_mixblock_init (SHA1_CONTEXT *hd);
+unsigned int _gcry_sha1_mixblock (SHA1_CONTEXT *hd, void *blockof64byte);
+
+#endif /*GCRY_SHA1_H*/
diff --git a/cipher/sha256-avx-amd64.S b/cipher/sha256-avx-amd64.S
new file mode 100644 (file)
index 0000000..8bf26bd
--- /dev/null
@@ -0,0 +1,528 @@
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Copyright (c) 2012, Intel Corporation
+;
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions are
+; met:
+;
+; * Redistributions of source code must retain the above copyright
+;   notice, this list of conditions and the following disclaimer.
+;
+; * Redistributions in binary form must reproduce the above copyright
+;   notice, this list of conditions and the following disclaimer in the
+;   documentation and/or other materials provided with the
+;   distribution.
+;
+; * Neither the name of the Intel Corporation nor the names of its
+;   contributors may be used to endorse or promote products derived from
+;   this software without specific prior written permission.
+;
+;
+; THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY
+; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR
+; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+; This code is described in an Intel White-Paper:
+; "Fast SHA-256 Implementations on Intel Architecture Processors"
+;
+; To find it, surf to http://www.intel.com/p/en_US/embedded
+; and search for that title.
+; The paper is expected to be released roughly at the end of April, 2012
+;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; This code schedules 1 blocks at a time, with 4 lanes per block
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+*/
+/*
+ * Conversion to GAS assembly and integration to libgcrypt
+ *  by Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * Note: Based on the SSSE3 implementation.
+ */
+
+#ifdef __x86_64
+#include <config.h>
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
+    defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
+    defined(HAVE_GCC_INLINE_ASM_AVX) && defined(USE_SHA256)
+
+#ifdef __PIC__
+#  define ADD_RIP +rip
+#else
+#  define ADD_RIP
+#endif
+
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
+
+.intel_syntax noprefix
+
+#define        VMOVDQ vmovdqu /* assume buffers not aligned */
+
+.macro ROR p1 p2
+       /* shld is faster than ror on Intel Sandybridge */
+       shld    \p1, \p1, (32 - \p2)
+.endm
+
+/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Define Macros*/
+
+/* addm [mem], reg
+ * Add reg to mem using reg-mem add and store */
+.macro addm p1 p2
+       add     \p2, \p1
+       mov     \p1, \p2
+.endm
+
+/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
+
+/* COPY_XMM_AND_BSWAP xmm, [mem], byte_flip_mask
+ * Load xmm with mem and byte swap each dword */
+.macro COPY_XMM_AND_BSWAP p1 p2 p3
+       VMOVDQ \p1, \p2
+       vpshufb \p1, \p1, \p3
+.endm
+
+/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
+
+X0 = xmm4
+X1 = xmm5
+X2 = xmm6
+X3 = xmm7
+
+XTMP0 = xmm0
+XTMP1 = xmm1
+XTMP2 = xmm2
+XTMP3 = xmm3
+XTMP4 = xmm8
+XFER  = xmm9
+
+SHUF_00BA = xmm10 /* shuffle xBxA -> 00BA */
+SHUF_DC00 = xmm11 /* shuffle xDxC -> DC00 */
+BYTE_FLIP_MASK = xmm12
+
+NUM_BLKS = rdx /* 3rd arg */
+CTX = rsi      /* 2nd arg */
+INP = rdi      /* 1st arg */
+
+SRND = rdi     /* clobbers INP */
+c = ecx
+d = r8d
+e = edx
+
+TBL = rbp
+a = eax
+b = ebx
+
+f = r9d
+g = r10d
+h = r11d
+
+y0 = r13d
+y1 = r14d
+y2 = r15d
+
+
+
+#define _INP_END_SIZE  8
+#define _INP_SIZE      8
+#define _XFER_SIZE     8
+#define _XMM_SAVE_SIZE 0
+/* STACK_SIZE plus pushes must be an odd multiple of 8 */
+#define _ALIGN_SIZE    8
+
+#define _INP_END       0
+#define _INP           (_INP_END  + _INP_END_SIZE)
+#define _XFER          (_INP      + _INP_SIZE)
+#define _XMM_SAVE      (_XFER     + _XFER_SIZE + _ALIGN_SIZE)
+#define STACK_SIZE     (_XMM_SAVE + _XMM_SAVE_SIZE)
+
+/* rotate_Xs
+ * Rotate values of symbols X0...X3 */
+.macro rotate_Xs
+X_ = X0
+X0 = X1
+X1 = X2
+X2 = X3
+X3 = X_
+.endm
+
+/* ROTATE_ARGS
+ * Rotate values of symbols a...h */
+.macro ROTATE_ARGS
+TMP_ = h
+h = g
+g = f
+f = e
+e = d
+d = c
+c = b
+b = a
+a = TMP_
+.endm
+
+.macro FOUR_ROUNDS_AND_SCHED
+               /* compute s0 four at a time and s1 two at a time
+                * compute W[-16] + W[-7] 4 at a time */
+       mov     y0, e           /* y0 = e */
+       ROR     y0, (25-11)     /* y0 = e >> (25-11) */
+       mov     y1, a           /* y1 = a */
+               vpalignr        XTMP0, X3, X2, 4        /* XTMP0 = W[-7] */
+       ROR     y1, (22-13)     /* y1 = a >> (22-13) */
+       xor     y0, e           /* y0 = e ^ (e >> (25-11)) */
+       mov     y2, f           /* y2 = f */
+       ROR     y0, (11-6)      /* y0 = (e >> (11-6)) ^ (e >> (25-6)) */
+       xor     y1, a           /* y1 = a ^ (a >> (22-13) */
+       xor     y2, g           /* y2 = f^g */
+               vpaddd  XTMP0, XTMP0, X0        /* XTMP0 = W[-7] + W[-16] */
+       xor     y0, e           /* y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) */
+       and     y2, e           /* y2 = (f^g)&e */
+       ROR     y1, (13-2)      /* y1 = (a >> (13-2)) ^ (a >> (22-2)) */
+               /* compute s0 */
+               vpalignr        XTMP1, X1, X0, 4        /* XTMP1 = W[-15] */
+       xor     y1, a           /* y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) */
+       ROR     y0, 6           /* y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) */
+       xor     y2, g           /* y2 = CH = ((f^g)&e)^g */
+       ROR     y1, 2           /* y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) */
+       add     y2, y0          /* y2 = S1 + CH */
+       add     y2, [rsp + _XFER + 0*4] /* y2 = k + w + S1 + CH */
+       mov     y0, a           /* y0 = a */
+       add     h, y2           /* h = h + S1 + CH + k + w */
+       mov     y2, a           /* y2 = a */
+               vpslld  XTMP2, XTMP1, (32-7)
+       or      y0, c           /* y0 = a|c */
+       add     d, h            /* d = d + h + S1 + CH + k + w */
+       and     y2, c           /* y2 = a&c */
+               vpsrld  XTMP3, XTMP1, 7
+       and     y0, b           /* y0 = (a|c)&b */
+       add     h, y1           /* h = h + S1 + CH + k + w + S0 */
+               vpor    XTMP3, XTMP3, XTMP2     /* XTMP1 = W[-15] ror 7 */
+       or      y0, y2          /* y0 = MAJ = (a|c)&b)|(a&c) */
+       lea     h, [h + y0]     /* h = h + S1 + CH + k + w + S0 + MAJ */
+
+ROTATE_ARGS
+       mov     y0, e           /* y0 = e */
+       mov     y1, a           /* y1 = a */
+       ROR     y0, (25-11)     /* y0 = e >> (25-11) */
+       xor     y0, e           /* y0 = e ^ (e >> (25-11)) */
+       mov     y2, f           /* y2 = f */
+       ROR     y1, (22-13)     /* y1 = a >> (22-13) */
+               vpslld  XTMP2, XTMP1, (32-18)
+       xor     y1, a           /* y1 = a ^ (a >> (22-13) */
+       ROR     y0, (11-6)      /* y0 = (e >> (11-6)) ^ (e >> (25-6)) */
+       xor     y2, g           /* y2 = f^g */
+               vpsrld  XTMP4, XTMP1, 18
+       ROR     y1, (13-2)      /* y1 = (a >> (13-2)) ^ (a >> (22-2)) */
+       xor     y0, e           /* y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) */
+       and     y2, e           /* y2 = (f^g)&e */
+       ROR     y0, 6           /* y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) */
+               vpxor   XTMP4, XTMP4, XTMP3
+       xor     y1, a           /* y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) */
+       xor     y2, g           /* y2 = CH = ((f^g)&e)^g */
+               vpsrld  XTMP1, XTMP1, 3 /* XTMP4 = W[-15] >> 3 */
+       add     y2, y0          /* y2 = S1 + CH */
+       add     y2, [rsp + _XFER + 1*4] /* y2 = k + w + S1 + CH */
+       ROR     y1, 2           /* y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) */
+               vpxor   XTMP1, XTMP1, XTMP2     /* XTMP1 = W[-15] ror 7 ^ W[-15] ror 18 */
+       mov     y0, a           /* y0 = a */
+       add     h, y2           /* h = h + S1 + CH + k + w */
+       mov     y2, a           /* y2 = a */
+               vpxor   XTMP1, XTMP1, XTMP4     /* XTMP1 = s0 */
+       or      y0, c           /* y0 = a|c */
+       add     d, h            /* d = d + h + S1 + CH + k + w */
+       and     y2, c           /* y2 = a&c */
+               /* compute low s1 */
+               vpshufd XTMP2, X3, 0b11111010   /* XTMP2 = W[-2] {BBAA} */
+       and     y0, b           /* y0 = (a|c)&b */
+       add     h, y1           /* h = h + S1 + CH + k + w + S0 */
+               vpaddd  XTMP0, XTMP0, XTMP1     /* XTMP0 = W[-16] + W[-7] + s0 */
+       or      y0, y2          /* y0 = MAJ = (a|c)&b)|(a&c) */
+       lea     h, [h + y0]     /* h = h + S1 + CH + k + w + S0 + MAJ */
+
+ROTATE_ARGS
+       mov     y0, e           /* y0 = e */
+       mov     y1, a           /* y1 = a */
+       ROR     y0, (25-11)     /* y0 = e >> (25-11) */
+       xor     y0, e           /* y0 = e ^ (e >> (25-11)) */
+       ROR     y1, (22-13)     /* y1 = a >> (22-13) */
+       mov     y2, f           /* y2 = f */
+       xor     y1, a           /* y1 = a ^ (a >> (22-13) */
+       ROR     y0, (11-6)      /* y0 = (e >> (11-6)) ^ (e >> (25-6)) */
+               vpsrlq  XTMP3, XTMP2, 17        /* XTMP2 = W[-2] ror 17 {xBxA} */
+       xor     y2, g           /* y2 = f^g */
+               vpsrlq  XTMP4, XTMP2, 19        /* XTMP3 = W[-2] ror 19 {xBxA} */
+       xor     y0, e           /* y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) */
+       and     y2, e           /* y2 = (f^g)&e */
+               vpsrld  XTMP2, XTMP2, 10        /* XTMP4 = W[-2] >> 10 {BBAA} */
+       ROR     y1, (13-2)      /* y1 = (a >> (13-2)) ^ (a >> (22-2)) */
+       xor     y1, a           /* y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) */
+       xor     y2, g           /* y2 = CH = ((f^g)&e)^g */
+       ROR     y0, 6           /* y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) */
+               vpxor   XTMP2, XTMP2, XTMP3
+       add     y2, y0          /* y2 = S1 + CH */
+       ROR     y1, 2           /* y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) */
+       add     y2, [rsp + _XFER + 2*4] /* y2 = k + w + S1 + CH */
+               vpxor   XTMP4, XTMP4, XTMP2     /* XTMP4 = s1 {xBxA} */
+       mov     y0, a           /* y0 = a */
+       add     h, y2           /* h = h + S1 + CH + k + w */
+       mov     y2, a           /* y2 = a */
+               vpshufb XTMP4, XTMP4, SHUF_00BA /* XTMP4 = s1 {00BA} */
+       or      y0, c           /* y0 = a|c */
+       add     d, h            /* d = d + h + S1 + CH + k + w */
+       and     y2, c           /* y2 = a&c */
+               vpaddd  XTMP0, XTMP0, XTMP4     /* XTMP0 = {..., ..., W[1], W[0]} */
+       and     y0, b           /* y0 = (a|c)&b */
+       add     h, y1           /* h = h + S1 + CH + k + w + S0 */
+               /* compute high s1 */
+               vpshufd XTMP2, XTMP0, 0b01010000 /* XTMP2 = W[-2] {DDCC} */
+       or      y0, y2          /* y0 = MAJ = (a|c)&b)|(a&c) */
+       lea     h, [h + y0]     /* h = h + S1 + CH + k + w + S0 + MAJ */
+
+ROTATE_ARGS
+       mov     y0, e           /* y0 = e */
+       ROR     y0, (25-11)     /* y0 = e >> (25-11) */
+       mov     y1, a           /* y1 = a */
+       ROR     y1, (22-13)     /* y1 = a >> (22-13) */
+       xor     y0, e           /* y0 = e ^ (e >> (25-11)) */
+       mov     y2, f           /* y2 = f */
+       ROR     y0, (11-6)      /* y0 = (e >> (11-6)) ^ (e >> (25-6)) */
+               vpsrlq  XTMP3, XTMP2, 17        /* XTMP2 = W[-2] ror 17 {xDxC} */
+       xor     y1, a           /* y1 = a ^ (a >> (22-13) */
+       xor     y2, g           /* y2 = f^g */
+               vpsrlq  X0, XTMP2, 19   /* XTMP3 = W[-2] ror 19 {xDxC} */
+       xor     y0, e           /* y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) */
+       and     y2, e           /* y2 = (f^g)&e */
+       ROR     y1, (13-2)      /* y1 = (a >> (13-2)) ^ (a >> (22-2)) */
+               vpsrld  XTMP2, XTMP2,    10     /* X0 = W[-2] >> 10 {DDCC} */
+       xor     y1, a           /* y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) */
+       ROR     y0, 6           /* y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) */
+       xor     y2, g           /* y2 = CH = ((f^g)&e)^g */
+               vpxor   XTMP2, XTMP2, XTMP3
+       ROR     y1, 2           /* y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) */
+       add     y2, y0          /* y2 = S1 + CH */
+       add     y2, [rsp + _XFER + 3*4] /* y2 = k + w + S1 + CH */
+               vpxor   X0, X0, XTMP2   /* X0 = s1 {xDxC} */
+       mov     y0, a           /* y0 = a */
+       add     h, y2           /* h = h + S1 + CH + k + w */
+       mov     y2, a           /* y2 = a */
+               vpshufb X0, X0, SHUF_DC00       /* X0 = s1 {DC00} */
+       or      y0, c           /* y0 = a|c */
+       add     d, h            /* d = d + h + S1 + CH + k + w */
+       and     y2, c           /* y2 = a&c */
+               vpaddd  X0, X0, XTMP0   /* X0 = {W[3], W[2], W[1], W[0]} */
+       and     y0, b           /* y0 = (a|c)&b */
+       add     h, y1           /* h = h + S1 + CH + k + w + S0 */
+       or      y0, y2          /* y0 = MAJ = (a|c)&b)|(a&c) */
+       lea     h, [h + y0]     /* h = h + S1 + CH + k + w + S0 + MAJ */
+
+ROTATE_ARGS
+rotate_Xs
+.endm
+
+/* input is [rsp + _XFER + %1 * 4] */
+.macro DO_ROUND i1
+       mov     y0, e           /* y0 = e */
+       ROR     y0, (25-11)     /* y0 = e >> (25-11) */
+       mov     y1, a           /* y1 = a */
+       xor     y0, e           /* y0 = e ^ (e >> (25-11)) */
+       ROR     y1, (22-13)     /* y1 = a >> (22-13) */
+       mov     y2, f           /* y2 = f */
+       xor     y1, a           /* y1 = a ^ (a >> (22-13) */
+       ROR     y0, (11-6)      /* y0 = (e >> (11-6)) ^ (e >> (25-6)) */
+       xor     y2, g           /* y2 = f^g */
+       xor     y0, e           /* y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) */
+       ROR     y1, (13-2)      /* y1 = (a >> (13-2)) ^ (a >> (22-2)) */
+       and     y2, e           /* y2 = (f^g)&e */
+       xor     y1, a           /* y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) */
+       ROR     y0, 6           /* y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) */
+       xor     y2, g           /* y2 = CH = ((f^g)&e)^g */
+       add     y2, y0          /* y2 = S1 + CH */
+       ROR     y1, 2           /* y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) */
+       add     y2, [rsp + _XFER + \i1 * 4]     /* y2 = k + w + S1 + CH */
+       mov     y0, a           /* y0 = a */
+       add     h, y2           /* h = h + S1 + CH + k + w */
+       mov     y2, a           /* y2 = a */
+       or      y0, c           /* y0 = a|c */
+       add     d, h            /* d = d + h + S1 + CH + k + w */
+       and     y2, c           /* y2 = a&c */
+       and     y0, b           /* y0 = (a|c)&b */
+       add     h, y1           /* h = h + S1 + CH + k + w + S0 */
+       or      y0, y2          /* y0 = MAJ = (a|c)&b)|(a&c) */
+       lea     h, [h + y0]     /* h = h + S1 + CH + k + w + S0 + MAJ */
+       ROTATE_ARGS
+.endm
+
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; void sha256_avx(void *input_data, UINT32 digest[8], UINT64 num_blks)
+;; arg 1 : pointer to input data
+;; arg 2 : pointer to digest
+;; arg 3 : Num blocks
+*/
+.text
+.globl _gcry_sha256_transform_amd64_avx
+ELF(.type  _gcry_sha256_transform_amd64_avx,@function;)
+.align 16
+_gcry_sha256_transform_amd64_avx:
+       vzeroupper
+
+       push    rbx
+       push    rbp
+       push    r13
+       push    r14
+       push    r15
+
+       sub     rsp, STACK_SIZE
+
+       shl     NUM_BLKS, 6     /* convert to bytes */
+       jz      .Ldone_hash
+       add     NUM_BLKS, INP   /* pointer to end of data */
+       mov     [rsp + _INP_END], NUM_BLKS
+
+       /* load initial digest */
+       mov     a,[4*0 + CTX]
+       mov     b,[4*1 + CTX]
+       mov     c,[4*2 + CTX]
+       mov     d,[4*3 + CTX]
+       mov     e,[4*4 + CTX]
+       mov     f,[4*5 + CTX]
+       mov     g,[4*6 + CTX]
+       mov     h,[4*7 + CTX]
+
+       vmovdqa BYTE_FLIP_MASK, [.LPSHUFFLE_BYTE_FLIP_MASK ADD_RIP]
+       vmovdqa SHUF_00BA, [.L_SHUF_00BA ADD_RIP]
+       vmovdqa SHUF_DC00, [.L_SHUF_DC00 ADD_RIP]
+
+.Loop0:
+       lea     TBL, [.LK256 ADD_RIP]
+
+       /* byte swap first 16 dwords */
+       COPY_XMM_AND_BSWAP      X0, [INP + 0*16], BYTE_FLIP_MASK
+       COPY_XMM_AND_BSWAP      X1, [INP + 1*16], BYTE_FLIP_MASK
+       COPY_XMM_AND_BSWAP      X2, [INP + 2*16], BYTE_FLIP_MASK
+       COPY_XMM_AND_BSWAP      X3, [INP + 3*16], BYTE_FLIP_MASK
+
+       mov     [rsp + _INP], INP
+
+       /* schedule 48 input dwords, by doing 3 rounds of 16 each */
+       mov     SRND, 3
+.align 16
+.Loop1:
+       vpaddd  XFER, X0, [TBL + 0*16]
+       vmovdqa [rsp + _XFER], XFER
+       FOUR_ROUNDS_AND_SCHED
+
+       vpaddd  XFER, X0, [TBL + 1*16]
+       vmovdqa [rsp + _XFER], XFER
+       FOUR_ROUNDS_AND_SCHED
+
+       vpaddd  XFER, X0, [TBL + 2*16]
+       vmovdqa [rsp + _XFER], XFER
+       FOUR_ROUNDS_AND_SCHED
+
+       vpaddd  XFER, X0, [TBL + 3*16]
+       vmovdqa [rsp + _XFER], XFER
+       add     TBL, 4*16
+       FOUR_ROUNDS_AND_SCHED
+
+       sub     SRND, 1
+       jne     .Loop1
+
+       mov     SRND, 2
+.Loop2:
+       vpaddd  X0, X0, [TBL + 0*16]
+       vmovdqa [rsp + _XFER], X0
+       DO_ROUND        0
+       DO_ROUND        1
+       DO_ROUND        2
+       DO_ROUND        3
+       vpaddd  X1, X1, [TBL + 1*16]
+       vmovdqa [rsp + _XFER], X1
+       add     TBL, 2*16
+       DO_ROUND        0
+       DO_ROUND        1
+       DO_ROUND        2
+       DO_ROUND        3
+
+       vmovdqa X0, X2
+       vmovdqa X1, X3
+
+       sub     SRND, 1
+       jne     .Loop2
+
+       addm    [4*0 + CTX],a
+       addm    [4*1 + CTX],b
+       addm    [4*2 + CTX],c
+       addm    [4*3 + CTX],d
+       addm    [4*4 + CTX],e
+       addm    [4*5 + CTX],f
+       addm    [4*6 + CTX],g
+       addm    [4*7 + CTX],h
+
+       mov     INP, [rsp + _INP]
+       add     INP, 64
+       cmp     INP, [rsp + _INP_END]
+       jne     .Loop0
+
+       vzeroall
+
+.Ldone_hash:
+       add     rsp, STACK_SIZE
+
+       pop     r15
+       pop     r14
+       pop     r13
+       pop     rbp
+       pop     rbx
+
+       mov     eax, STACK_SIZE + 5*8
+
+       ret
+
+
+.data
+.align 16
+.LK256:
+       .long   0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+       .long   0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+       .long   0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+       .long   0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+       .long   0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+       .long   0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+       .long   0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+       .long   0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+       .long   0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+       .long   0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+       .long   0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+       .long   0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+       .long   0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+       .long   0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+       .long   0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+       .long   0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+
+.LPSHUFFLE_BYTE_FLIP_MASK: .octa 0x0c0d0e0f08090a0b0405060700010203
+
+/* shuffle xBxA -> 00BA */
+.L_SHUF_00BA:              .octa 0xFFFFFFFFFFFFFFFF0b0a090803020100
+
+/* shuffle xDxC -> DC00 */
+.L_SHUF_DC00:              .octa 0x0b0a090803020100FFFFFFFFFFFFFFFF
+
+#endif
+#endif
diff --git a/cipher/sha256-avx2-bmi2-amd64.S b/cipher/sha256-avx2-bmi2-amd64.S
new file mode 100644 (file)
index 0000000..74b6063
--- /dev/null
@@ -0,0 +1,814 @@
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Copyright (c) 2012, Intel Corporation
+;
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions are
+; met:
+;
+; * Redistributions of source code must retain the above copyright
+;   notice, this list of conditions and the following disclaimer.
+;
+; * Redistributions in binary form must reproduce the above copyright
+;   notice, this list of conditions and the following disclaimer in the
+;   documentation and/or other materials provided with the
+;   distribution.
+;
+; * Neither the name of the Intel Corporation nor the names of its
+;   contributors may be used to endorse or promote products derived from
+;   this software without specific prior written permission.
+;
+;
+; THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY
+; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR
+; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+; This code is described in an Intel White-Paper:
+; "Fast SHA-256 Implementations on Intel Architecture Processors"
+;
+; To find it, surf to http://www.intel.com/p/en_US/embedded
+; and search for that title.
+; The paper is expected to be released roughly at the end of April, 2012
+;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; This code schedules 2 blocks at a time, with 4 lanes per block
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+*/
+/*
+ * Conversion to GAS assembly and integration to libgcrypt
+ *  by Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ */
+
+#ifdef __x86_64
+#include <config.h>
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
+    defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
+    defined(HAVE_GCC_INLINE_ASM_AVX2) && defined(HAVE_GCC_INLINE_ASM_BMI2) && \
+    defined(USE_SHA256)
+
+#ifdef __PIC__
+#  define ADD_RIP +rip
+#else
+#  define ADD_RIP
+#endif
+
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
+
+.intel_syntax noprefix
+
+#define        VMOVDQ vmovdqu /* ; assume buffers not aligned  */
+
+/* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Define Macros */
+
+/*  addm [mem], reg */
+/*  Add reg to mem using reg-mem add and store */
+.macro addm p1 p2
+       add     \p2, \p1
+       mov     \p1, \p2
+.endm
+
+/* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
+
+X0 = ymm4
+X1 = ymm5
+X2 = ymm6
+X3 = ymm7
+
+/*  XMM versions of above */
+XWORD0 = xmm4
+XWORD1 = xmm5
+XWORD2 = xmm6
+XWORD3 = xmm7
+
+XTMP0 = ymm0
+XTMP1 = ymm1
+XTMP2 = ymm2
+XTMP3 = ymm3
+XTMP4 = ymm8
+XFER =  ymm9
+XTMP5 = ymm11
+
+SHUF_00BA = ymm10 /*  shuffle xBxA -> 00BA */
+SHUF_DC00 = ymm12 /*  shuffle xDxC -> DC00 */
+BYTE_FLIP_MASK = ymm13
+
+X_BYTE_FLIP_MASK = xmm13 /*  XMM version of BYTE_FLIP_MASK */
+
+NUM_BLKS = rdx /*  3rd arg */
+CTX =  rsi     /*  2nd arg */
+INP =  rdi     /*  1st arg */
+c =    ecx
+d =    r8d
+e =    edx     /*  clobbers NUM_BLKS */
+y3 =   edi     /*  clobbers INP */
+
+TBL =  rbp
+SRND = CTX     /*  SRND is same register as CTX */
+
+a =    eax
+b =    ebx
+f =    r9d
+g =    r10d
+h =    r11d
+old_h =        r11d
+
+T1 = r12d
+y0 = r13d
+y1 = r14d
+y2 = r15d
+
+
+_XFER_SIZE     = 2*64*4        /*  2 blocks, 64 rounds, 4 bytes/round */
+_XMM_SAVE_SIZE  = 0
+_INP_END_SIZE  = 8
+_INP_SIZE      = 8
+_CTX_SIZE      = 8
+_RSP_SIZE      = 8
+
+_XFER          = 0
+_XMM_SAVE      = _XFER     + _XFER_SIZE
+_INP_END       = _XMM_SAVE + _XMM_SAVE_SIZE
+_INP           = _INP_END  + _INP_END_SIZE
+_CTX           = _INP      + _INP_SIZE
+_RSP           = _CTX      + _CTX_SIZE
+STACK_SIZE     = _RSP      + _RSP_SIZE
+
+/*  rotate_Xs */
+/*  Rotate values of symbols X0...X3 */
+.macro rotate_Xs
+X_ = X0
+X0 = X1
+X1 = X2
+X2 = X3
+X3 = X_
+.endm
+
+/*  ROTATE_ARGS */
+/*  Rotate values of symbols a...h */
+.macro ROTATE_ARGS
+old_h = h
+TMP_ = h
+h = g
+g = f
+f = e
+e = d
+d = c
+c = b
+b = a
+a = TMP_
+.endm
+
+.macro FOUR_ROUNDS_AND_SCHED XFER
+/* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
+
+       mov     y3, a           /*  y3 = a                                ; MAJA         */
+       rorx    y0, e, 25       /*  y0 = e >> 25                                ; S1A */
+       rorx    y1, e, 11       /*  y1 = e >> 11                                ; S1B */
+
+       add     h, [\XFER+0*4]          /*  h = k + w + h         ; --   */
+       or      y3, c           /*  y3 = a|c                              ; MAJA         */
+               vpalignr        XTMP0, X3, X2, 4        /*  XTMP0 = W[-7] */
+       mov     y2, f           /*  y2 = f                                ; CH   */
+       rorx    T1, a, 13       /*  T1 = a >> 13                                ; S0B */
+
+       xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11)              ; S1 */
+       xor     y2, g           /*  y2 = f^g                              ; CH   */
+               vpaddd  XTMP0, XTMP0, X0        /*  XTMP0 = W[-7] + W[-16]; y1 = (e >> 6)                                       ; S1 */
+       rorx    y1, e, 6        /*  y1 = (e >> 6)                               ; S1 */
+
+       and     y2, e           /*  y2 = (f^g)&e                          ; CH   */
+       xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11) ^ (e>>6)     ; S1 */
+       rorx    y1, a, 22       /*  y1 = a >> 22                                ; S0A */
+       add     d, h            /*  d = k + w + h + d                     ; --   */
+
+       and     y3, b           /*  y3 = (a|c)&b                          ; MAJA         */
+               vpalignr        XTMP1, X1, X0, 4        /*  XTMP1 = W[-15] */
+       xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13)              ; S0 */
+       rorx    T1, a, 2        /*  T1 = (a >> 2)                               ; S0 */
+
+       xor     y2, g           /*  y2 = CH = ((f^g)&e)^g                 ; CH   */
+               vpsrld  XTMP2, XTMP1, 7
+       xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13) ^ (a>>2)     ; S0 */
+       mov     T1, a           /*  T1 = a                                ; MAJB         */
+       and     T1, c           /*  T1 = a&c                              ; MAJB         */
+
+       add     y2, y0          /*  y2 = S1 + CH                          ; --   */
+               vpslld  XTMP3, XTMP1, (32-7)
+       or      y3, T1          /*  y3 = MAJ = (a|c)&b)|(a&c)             ; MAJ  */
+       add     h, y1           /*  h = k + w + h + S0                    ; --   */
+
+       add     d, y2           /*  d = k + w + h + d + S1 + CH = d + t1  ; --   */
+               vpor    XTMP3, XTMP3, XTMP2     /*  XTMP3 = W[-15] ror 7 */
+
+               vpsrld  XTMP2, XTMP1,18
+       add     h, y2           /*  h = k + w + h + S0 + S1 + CH = t1 + S0; --   */
+       lea     h, [h + y3]     /*  h = t1 + S0 + MAJ                     ; --   */
+
+
+ROTATE_ARGS
+
+/* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
+
+
+       mov     y3, a           /*  y3 = a                                ; MAJA         */
+       rorx    y0, e, 25       /*  y0 = e >> 25                                ; S1A */
+       rorx    y1, e, 11       /*  y1 = e >> 11                                ; S1B */
+       add     h, [\XFER+1*4]          /*  h = k + w + h         ; --   */
+       or      y3, c           /*  y3 = a|c                              ; MAJA         */
+
+
+               vpsrld  XTMP4, XTMP1, 3 /*  XTMP4 = W[-15] >> 3 */
+       mov     y2, f           /*  y2 = f                                ; CH   */
+       rorx    T1, a, 13       /*  T1 = a >> 13                                ; S0B */
+       xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11)              ; S1 */
+       xor     y2, g           /*  y2 = f^g                              ; CH   */
+
+
+       rorx    y1, e, 6        /*  y1 = (e >> 6)                               ; S1 */
+       xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11) ^ (e>>6)     ; S1 */
+       rorx    y1, a, 22       /*  y1 = a >> 22                                ; S0A */
+       and     y2, e           /*  y2 = (f^g)&e                          ; CH   */
+       add     d, h            /*  d = k + w + h + d                     ; --   */
+
+               vpslld  XTMP1, XTMP1, (32-18)
+       and     y3, b           /*  y3 = (a|c)&b                          ; MAJA         */
+       xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13)              ; S0 */
+
+               vpxor   XTMP3, XTMP3, XTMP1
+       rorx    T1, a, 2        /*  T1 = (a >> 2)                               ; S0 */
+       xor     y2, g           /*  y2 = CH = ((f^g)&e)^g                 ; CH   */
+
+               vpxor   XTMP3, XTMP3, XTMP2     /*  XTMP3 = W[-15] ror 7 ^ W[-15] ror 18 */
+       xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13) ^ (a>>2)     ; S0 */
+       mov     T1, a           /*  T1 = a                                ; MAJB         */
+       and     T1, c           /*  T1 = a&c                              ; MAJB         */
+       add     y2, y0          /*  y2 = S1 + CH                          ; --   */
+
+               vpxor   XTMP1, XTMP3, XTMP4     /*  XTMP1 = s0 */
+               vpshufd XTMP2, X3, 0b11111010   /*  XTMP2 = W[-2] {BBAA} */
+       or      y3, T1          /*  y3 = MAJ = (a|c)&b)|(a&c)             ; MAJ  */
+       add     h, y1           /*  h = k + w + h + S0                    ; --   */
+
+               vpaddd  XTMP0, XTMP0, XTMP1     /*  XTMP0 = W[-16] + W[-7] + s0 */
+       add     d, y2           /*  d = k + w + h + d + S1 + CH = d + t1  ; --   */
+       add     h, y2           /*  h = k + w + h + S0 + S1 + CH = t1 + S0; --   */
+       lea     h, [h + y3]     /*  h = t1 + S0 + MAJ                     ; --   */
+
+               vpsrld  XTMP4, XTMP2, 10        /*  XTMP4 = W[-2] >> 10 {BBAA} */
+
+
+ROTATE_ARGS
+
+/* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
+
+       mov     y3, a           /*  y3 = a                                ; MAJA         */
+       rorx    y0, e, 25       /*  y0 = e >> 25                                ; S1A */
+       add     h, [\XFER+2*4]          /*  h = k + w + h         ; --   */
+
+               vpsrlq  XTMP3, XTMP2, 19        /*  XTMP3 = W[-2] ror 19 {xBxA} */
+       rorx    y1, e, 11       /*  y1 = e >> 11                                ; S1B */
+       or      y3, c           /*  y3 = a|c                              ; MAJA         */
+       mov     y2, f           /*  y2 = f                                ; CH   */
+       xor     y2, g           /*  y2 = f^g                              ; CH   */
+
+       rorx    T1, a, 13       /*  T1 = a >> 13                                ; S0B */
+       xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11)              ; S1 */
+               vpsrlq  XTMP2, XTMP2, 17        /*  XTMP2 = W[-2] ror 17 {xBxA} */
+       and     y2, e           /*  y2 = (f^g)&e                          ; CH   */
+
+       rorx    y1, e, 6        /*  y1 = (e >> 6)                               ; S1 */
+               vpxor   XTMP2, XTMP2, XTMP3
+       add     d, h            /*  d = k + w + h + d                     ; --   */
+       and     y3, b           /*  y3 = (a|c)&b                          ; MAJA         */
+
+       xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11) ^ (e>>6)     ; S1 */
+       rorx    y1, a, 22       /*  y1 = a >> 22                                ; S0A */
+               vpxor   XTMP4, XTMP4, XTMP2     /*  XTMP4 = s1 {xBxA} */
+       xor     y2, g           /*  y2 = CH = ((f^g)&e)^g                 ; CH   */
+
+               vpshufb XTMP4, XTMP4, SHUF_00BA /*  XTMP4 = s1 {00BA} */
+       xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13)              ; S0 */
+       rorx    T1, a, 2        /*  T1 = (a >> 2)                               ; S0 */
+               vpaddd  XTMP0, XTMP0, XTMP4     /*  XTMP0 = {..., ..., W[1], W[0]} */
+
+       xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13) ^ (a>>2)     ; S0 */
+       mov     T1, a           /*  T1 = a                                ; MAJB         */
+       and     T1, c           /*  T1 = a&c                              ; MAJB         */
+       add     y2, y0          /*  y2 = S1 + CH                          ; --   */
+               vpshufd XTMP2, XTMP0, 0b1010000 /*  XTMP2 = W[-2] {DDCC} */
+
+       or      y3, T1          /*  y3 = MAJ = (a|c)&b)|(a&c)             ; MAJ  */
+       add     h, y1           /*  h = k + w + h + S0                    ; --   */
+       add     d, y2           /*  d = k + w + h + d + S1 + CH = d + t1  ; --   */
+       add     h, y2           /*  h = k + w + h + S0 + S1 + CH = t1 + S0; --   */
+
+       lea     h, [h + y3]     /*  h = t1 + S0 + MAJ                     ; --   */
+
+
+ROTATE_ARGS
+
+/* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
+
+       mov     y3, a           /*  y3 = a                                ; MAJA         */
+       rorx    y0, e, 25       /*  y0 = e >> 25                                ; S1A */
+       rorx    y1, e, 11       /*  y1 = e >> 11                                ; S1B */
+       add     h, [\XFER+3*4]          /*  h = k + w + h         ; --   */
+       or      y3, c           /*  y3 = a|c                              ; MAJA         */
+
+
+               vpsrld  XTMP5, XTMP2,   10      /*  XTMP5 = W[-2] >> 10 {DDCC} */
+       mov     y2, f           /*  y2 = f                                ; CH   */
+       rorx    T1, a, 13       /*  T1 = a >> 13                                ; S0B */
+       xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11)              ; S1 */
+       xor     y2, g           /*  y2 = f^g                              ; CH   */
+
+
+               vpsrlq  XTMP3, XTMP2, 19        /*  XTMP3 = W[-2] ror 19 {xDxC} */
+       rorx    y1, e, 6        /*  y1 = (e >> 6)                               ; S1 */
+       and     y2, e           /*  y2 = (f^g)&e                          ; CH   */
+       add     d, h            /*  d = k + w + h + d                     ; --   */
+       and     y3, b           /*  y3 = (a|c)&b                          ; MAJA         */
+
+               vpsrlq  XTMP2, XTMP2, 17        /*  XTMP2 = W[-2] ror 17 {xDxC} */
+       xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11) ^ (e>>6)     ; S1 */
+       xor     y2, g           /*  y2 = CH = ((f^g)&e)^g                 ; CH   */
+
+               vpxor   XTMP2, XTMP2, XTMP3
+       rorx    y1, a, 22       /*  y1 = a >> 22                                ; S0A */
+       add     y2, y0          /*  y2 = S1 + CH                          ; --   */
+
+               vpxor   XTMP5, XTMP5, XTMP2     /*  XTMP5 = s1 {xDxC} */
+       xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13)              ; S0 */
+       add     d, y2           /*  d = k + w + h + d + S1 + CH = d + t1  ; --   */
+
+       rorx    T1, a, 2        /*  T1 = (a >> 2)                               ; S0 */
+               vpshufb XTMP5, XTMP5, SHUF_DC00 /*  XTMP5 = s1 {DC00} */
+
+               vpaddd  X0, XTMP5, XTMP0        /*  X0 = {W[3], W[2], W[1], W[0]} */
+       xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13) ^ (a>>2)     ; S0 */
+       mov     T1, a           /*  T1 = a                                ; MAJB         */
+       and     T1, c           /*  T1 = a&c                              ; MAJB         */
+       or      y3, T1          /*  y3 = MAJ = (a|c)&b)|(a&c)             ; MAJ  */
+
+       add     h, y1           /*  h = k + w + h + S0                    ; --   */
+       add     h, y2           /*  h = k + w + h + S0 + S1 + CH = t1 + S0; --   */
+       lea     h, [h + y3]     /*  h = t1 + S0 + MAJ                     ; --   */
+
+ROTATE_ARGS
+rotate_Xs
+.endm
+
+.macro DO_4ROUNDS XFER
+/* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;; */
+
+       mov     y2, f           /*  y2 = f                                ; CH   */
+       rorx    y0, e, 25       /*  y0 = e >> 25                                ; S1A */
+       rorx    y1, e, 11       /*  y1 = e >> 11                                ; S1B */
+       xor     y2, g           /*  y2 = f^g                              ; CH   */
+
+       xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11)              ; S1 */
+       rorx    y1, e, 6        /*  y1 = (e >> 6)                               ; S1 */
+       and     y2, e           /*  y2 = (f^g)&e                          ; CH   */
+
+       xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11) ^ (e>>6)     ; S1 */
+       rorx    T1, a, 13       /*  T1 = a >> 13                                ; S0B */
+       xor     y2, g           /*  y2 = CH = ((f^g)&e)^g                 ; CH   */
+       rorx    y1, a, 22       /*  y1 = a >> 22                                ; S0A */
+       mov     y3, a           /*  y3 = a                                ; MAJA         */
+
+       xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13)              ; S0 */
+       rorx    T1, a, 2        /*  T1 = (a >> 2)                               ; S0 */
+       add     h, [\XFER + 4*0]                /*  h = k + w + h ; --   */
+       or      y3, c           /*  y3 = a|c                              ; MAJA         */
+
+       xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13) ^ (a>>2)     ; S0 */
+       mov     T1, a           /*  T1 = a                                ; MAJB         */
+       and     y3, b           /*  y3 = (a|c)&b                          ; MAJA         */
+       and     T1, c           /*  T1 = a&c                              ; MAJB         */
+       add     y2, y0          /*  y2 = S1 + CH                          ; --   */
+
+
+       add     d, h            /*  d = k + w + h + d                     ; --   */
+       or      y3, T1          /*  y3 = MAJ = (a|c)&b)|(a&c)             ; MAJ  */
+       add     h, y1           /*  h = k + w + h + S0                    ; --   */
+
+       add     d, y2           /*  d = k + w + h + d + S1 + CH = d + t1  ; --   */
+
+
+       /* add  h, y2           ; h = k + w + h + S0 + S1 + CH = t1 + S0; --     */
+
+       /* lea  h, [h + y3]     ; h = t1 + S0 + MAJ                     ; --     */
+
+       ROTATE_ARGS
+
+/* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;; */
+
+       add     old_h, y2       /*  h = k + w + h + S0 + S1 + CH = t1 + S0; --   */
+       mov     y2, f           /*  y2 = f                                ; CH   */
+       rorx    y0, e, 25       /*  y0 = e >> 25                                ; S1A */
+       rorx    y1, e, 11       /*  y1 = e >> 11                                ; S1B */
+       xor     y2, g           /*  y2 = f^g                              ; CH   */
+
+       xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11)              ; S1 */
+       rorx    y1, e, 6        /*  y1 = (e >> 6)                               ; S1 */
+       and     y2, e           /*  y2 = (f^g)&e                          ; CH   */
+       add     old_h, y3       /*  h = t1 + S0 + MAJ                     ; --   */
+
+       xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11) ^ (e>>6)     ; S1 */
+       rorx    T1, a, 13       /*  T1 = a >> 13                                ; S0B */
+       xor     y2, g           /*  y2 = CH = ((f^g)&e)^g                 ; CH   */
+       rorx    y1, a, 22       /*  y1 = a >> 22                                ; S0A */
+       mov     y3, a           /*  y3 = a                                ; MAJA         */
+
+       xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13)              ; S0 */
+       rorx    T1, a, 2        /*  T1 = (a >> 2)                               ; S0 */
+       add     h, [\XFER + 4*1]                /*  h = k + w + h ; --   */
+       or      y3, c           /*  y3 = a|c                              ; MAJA         */
+
+       xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13) ^ (a>>2)     ; S0 */
+       mov     T1, a           /*  T1 = a                                ; MAJB         */
+       and     y3, b           /*  y3 = (a|c)&b                          ; MAJA         */
+       and     T1, c           /*  T1 = a&c                              ; MAJB         */
+       add     y2, y0          /*  y2 = S1 + CH                          ; --   */
+
+
+       add     d, h            /*  d = k + w + h + d                     ; --   */
+       or      y3, T1          /*  y3 = MAJ = (a|c)&b)|(a&c)             ; MAJ  */
+       add     h, y1           /*  h = k + w + h + S0                    ; --   */
+
+       add     d, y2           /*  d = k + w + h + d + S1 + CH = d + t1  ; --   */
+
+
+       /* add  h, y2           ; h = k + w + h + S0 + S1 + CH = t1 + S0; --     */
+
+       /* lea  h, [h + y3]     ; h = t1 + S0 + MAJ                     ; --     */
+
+       ROTATE_ARGS
+
+/* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
+
+       add     old_h, y2       /*  h = k + w + h + S0 + S1 + CH = t1 + S0; --   */
+       mov     y2, f           /*  y2 = f                                ; CH   */
+       rorx    y0, e, 25       /*  y0 = e >> 25                                ; S1A */
+       rorx    y1, e, 11       /*  y1 = e >> 11                                ; S1B */
+       xor     y2, g           /*  y2 = f^g                              ; CH   */
+
+       xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11)              ; S1 */
+       rorx    y1, e, 6        /*  y1 = (e >> 6)                               ; S1 */
+       and     y2, e           /*  y2 = (f^g)&e                          ; CH   */
+       add     old_h, y3       /*  h = t1 + S0 + MAJ                     ; --   */
+
+       xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11) ^ (e>>6)     ; S1 */
+       rorx    T1, a, 13       /*  T1 = a >> 13                                ; S0B */
+       xor     y2, g           /*  y2 = CH = ((f^g)&e)^g                 ; CH   */
+       rorx    y1, a, 22       /*  y1 = a >> 22                                ; S0A */
+       mov     y3, a           /*  y3 = a                                ; MAJA         */
+
+       xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13)              ; S0 */
+       rorx    T1, a, 2        /*  T1 = (a >> 2)                               ; S0 */
+       add     h, [\XFER + 4*2]                /*  h = k + w + h ; --   */
+       or      y3, c           /*  y3 = a|c                              ; MAJA         */
+
+       xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13) ^ (a>>2)     ; S0 */
+       mov     T1, a           /*  T1 = a                                ; MAJB         */
+       and     y3, b           /*  y3 = (a|c)&b                          ; MAJA         */
+       and     T1, c           /*  T1 = a&c                              ; MAJB         */
+       add     y2, y0          /*  y2 = S1 + CH                          ; --   */
+
+
+       add     d, h            /*  d = k + w + h + d                     ; --   */
+       or      y3, T1          /*  y3 = MAJ = (a|c)&b)|(a&c)             ; MAJ  */
+       add     h, y1           /*  h = k + w + h + S0                    ; --   */
+
+       add     d, y2           /*  d = k + w + h + d + S1 + CH = d + t1  ; --   */
+
+
+       /* add  h, y2           ; h = k + w + h + S0 + S1 + CH = t1 + S0; --     */
+
+       /* lea  h, [h + y3]     ; h = t1 + S0 + MAJ                     ; --     */
+
+       ROTATE_ARGS
+
+/* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 3 ;;;;;;;;;;;;;;;;;;;;;;;;;;; */
+
+       add     old_h, y2       /*  h = k + w + h + S0 + S1 + CH = t1 + S0; --   */
+       mov     y2, f           /*  y2 = f                                ; CH   */
+       rorx    y0, e, 25       /*  y0 = e >> 25                                ; S1A */
+       rorx    y1, e, 11       /*  y1 = e >> 11                                ; S1B */
+       xor     y2, g           /*  y2 = f^g                              ; CH   */
+
+       xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11)              ; S1 */
+       rorx    y1, e, 6        /*  y1 = (e >> 6)                               ; S1 */
+       and     y2, e           /*  y2 = (f^g)&e                          ; CH   */
+       add     old_h, y3       /*  h = t1 + S0 + MAJ                     ; --   */
+
+       xor     y0, y1          /*  y0 = (e>>25) ^ (e>>11) ^ (e>>6)     ; S1 */
+       rorx    T1, a, 13       /*  T1 = a >> 13                                ; S0B */
+       xor     y2, g           /*  y2 = CH = ((f^g)&e)^g                 ; CH   */
+       rorx    y1, a, 22       /*  y1 = a >> 22                                ; S0A */
+       mov     y3, a           /*  y3 = a                                ; MAJA         */
+
+       xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13)              ; S0 */
+       rorx    T1, a, 2        /*  T1 = (a >> 2)                               ; S0 */
+       add     h, [\XFER + 4*3]                /*  h = k + w + h ; --   */
+       or      y3, c           /*  y3 = a|c                              ; MAJA         */
+
+       xor     y1, T1          /*  y1 = (a>>22) ^ (a>>13) ^ (a>>2)     ; S0 */
+       mov     T1, a           /*  T1 = a                                ; MAJB         */
+       and     y3, b           /*  y3 = (a|c)&b                          ; MAJA         */
+       and     T1, c           /*  T1 = a&c                              ; MAJB         */
+       add     y2, y0          /*  y2 = S1 + CH                          ; --   */
+
+
+       add     d, h            /*  d = k + w + h + d                     ; --   */
+       or      y3, T1          /*  y3 = MAJ = (a|c)&b)|(a&c)             ; MAJ  */
+       add     h, y1           /*  h = k + w + h + S0                    ; --   */
+
+       add     d, y2           /*  d = k + w + h + d + S1 + CH = d + t1  ; --   */
+
+
+       add     h, y2           /*  h = k + w + h + S0 + S1 + CH = t1 + S0; --   */
+
+       lea     h, [h + y3]     /*  h = t1 + S0 + MAJ                     ; --   */
+
+       ROTATE_ARGS
+.endm
+
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; void sha256_rorx(void *input_data, UINT32 digest[8], UINT64 num_blks)
+;; arg 1 : pointer to input data
+;; arg 2 : pointer to digest
+;; arg 3 : Num blocks
+*/
+.text
+.globl _gcry_sha256_transform_amd64_avx2
+ELF(.type _gcry_sha256_transform_amd64_avx2,@function)
+.align 32
+_gcry_sha256_transform_amd64_avx2:
+       push    rbx
+       push    rbp
+       push    r12
+       push    r13
+       push    r14
+       push    r15
+
+       vzeroupper
+
+       mov     rax, rsp
+       sub     rsp, STACK_SIZE
+       and     rsp, -32
+       mov     [rsp + _RSP], rax
+
+       shl     NUM_BLKS, 6     /*  convert to bytes */
+       jz      .Ldone_hash
+       lea     NUM_BLKS, [NUM_BLKS + INP - 64] /*  pointer to last block */
+       mov     [rsp + _INP_END], NUM_BLKS
+
+       cmp     INP, NUM_BLKS
+       je      .Lonly_one_block
+
+       /* ; load initial digest */
+       mov     a,[4*0 + CTX]
+       mov     b,[4*1 + CTX]
+       mov     c,[4*2 + CTX]
+       mov     d,[4*3 + CTX]
+       mov     e,[4*4 + CTX]
+       mov     f,[4*5 + CTX]
+       mov     g,[4*6 + CTX]
+       mov     h,[4*7 + CTX]
+
+       vmovdqa BYTE_FLIP_MASK, [.LPSHUFFLE_BYTE_FLIP_MASK ADD_RIP]
+       vmovdqa SHUF_00BA, [.L_SHUF_00BA ADD_RIP]
+       vmovdqa SHUF_DC00, [.L_SHUF_DC00 ADD_RIP]
+
+       mov     [rsp + _CTX], CTX
+
+.Loop0:
+       lea     TBL, [.LK256 ADD_RIP]
+
+       /* ; Load first 16 dwords from two blocks */
+       VMOVDQ  XTMP0, [INP + 0*32]
+       VMOVDQ  XTMP1, [INP + 1*32]
+       VMOVDQ  XTMP2, [INP + 2*32]
+       VMOVDQ  XTMP3, [INP + 3*32]
+
+       /* ; byte swap data */
+       vpshufb XTMP0, XTMP0, BYTE_FLIP_MASK
+       vpshufb XTMP1, XTMP1, BYTE_FLIP_MASK
+       vpshufb XTMP2, XTMP2, BYTE_FLIP_MASK
+       vpshufb XTMP3, XTMP3, BYTE_FLIP_MASK
+
+       /* ; transpose data into high/low halves */
+       vperm2i128      X0, XTMP0, XTMP2, 0x20
+       vperm2i128      X1, XTMP0, XTMP2, 0x31
+       vperm2i128      X2, XTMP1, XTMP3, 0x20
+       vperm2i128      X3, XTMP1, XTMP3, 0x31
+
+.Last_block_enter:
+       add     INP, 64
+       mov     [rsp + _INP], INP
+
+       /* ; schedule 48 input dwords, by doing 3 rounds of 12 each */
+       xor     SRND, SRND
+
+.align 16
+.Loop1:
+       vpaddd  XFER, X0, [TBL + SRND + 0*32]
+       vmovdqa [rsp + _XFER + SRND + 0*32], XFER
+       FOUR_ROUNDS_AND_SCHED   rsp + _XFER + SRND + 0*32
+
+       vpaddd  XFER, X0, [TBL + SRND + 1*32]
+       vmovdqa [rsp + _XFER + SRND + 1*32], XFER
+       FOUR_ROUNDS_AND_SCHED   rsp + _XFER + SRND + 1*32
+
+       vpaddd  XFER, X0, [TBL + SRND + 2*32]
+       vmovdqa [rsp + _XFER + SRND + 2*32], XFER
+       FOUR_ROUNDS_AND_SCHED   rsp + _XFER + SRND + 2*32
+
+       vpaddd  XFER, X0, [TBL + SRND + 3*32]
+       vmovdqa [rsp + _XFER + SRND + 3*32], XFER
+       FOUR_ROUNDS_AND_SCHED   rsp + _XFER + SRND + 3*32
+
+       add     SRND, 4*32
+       cmp     SRND, 3 * 4*32
+       jb      .Loop1
+
+.Loop2:
+       /* ; Do last 16 rounds with no scheduling */
+       vpaddd  XFER, X0, [TBL + SRND + 0*32]
+       vmovdqa [rsp + _XFER + SRND + 0*32], XFER
+       DO_4ROUNDS      rsp + _XFER + SRND + 0*32
+       vpaddd  XFER, X1, [TBL + SRND + 1*32]
+       vmovdqa [rsp + _XFER + SRND + 1*32], XFER
+       DO_4ROUNDS      rsp + _XFER + SRND + 1*32
+       add     SRND, 2*32
+
+       vmovdqa X0, X2
+       vmovdqa X1, X3
+
+       cmp     SRND, 4 * 4*32
+       jb      .Loop2
+
+       mov     CTX, [rsp + _CTX]
+       mov     INP, [rsp + _INP]
+
+       addm    [4*0 + CTX],a
+       addm    [4*1 + CTX],b
+       addm    [4*2 + CTX],c
+       addm    [4*3 + CTX],d
+       addm    [4*4 + CTX],e
+       addm    [4*5 + CTX],f
+       addm    [4*6 + CTX],g
+       addm    [4*7 + CTX],h
+
+       cmp     INP, [rsp + _INP_END]
+       ja      .Ldone_hash
+
+       /* ;;; Do second block using previously scheduled results */
+       xor     SRND, SRND
+.align 16
+.Loop3:
+       DO_4ROUNDS      rsp + _XFER + SRND + 0*32 + 16
+       DO_4ROUNDS      rsp + _XFER + SRND + 1*32 + 16
+       add     SRND, 2*32
+       cmp     SRND, 4 * 4*32
+       jb .Loop3
+
+       mov     CTX, [rsp + _CTX]
+       mov     INP, [rsp + _INP]
+       add     INP, 64
+
+       addm    [4*0 + CTX],a
+       addm    [4*1 + CTX],b
+       addm    [4*2 + CTX],c
+       addm    [4*3 + CTX],d
+       addm    [4*4 + CTX],e
+       addm    [4*5 + CTX],f
+       addm    [4*6 + CTX],g
+       addm    [4*7 + CTX],h
+
+       cmp     INP, [rsp + _INP_END]
+       jb      .Loop0
+       ja      .Ldone_hash
+
+.Ldo_last_block:
+       /* ;;; do last block */
+       lea     TBL, [.LK256 ADD_RIP]
+
+       VMOVDQ  XWORD0, [INP + 0*16]
+       VMOVDQ  XWORD1, [INP + 1*16]
+       VMOVDQ  XWORD2, [INP + 2*16]
+       VMOVDQ  XWORD3, [INP + 3*16]
+
+       vpshufb XWORD0, XWORD0, X_BYTE_FLIP_MASK
+       vpshufb XWORD1, XWORD1, X_BYTE_FLIP_MASK
+       vpshufb XWORD2, XWORD2, X_BYTE_FLIP_MASK
+       vpshufb XWORD3, XWORD3, X_BYTE_FLIP_MASK
+
+       jmp     .Last_block_enter
+
+.Lonly_one_block:
+
+       /* ; load initial digest */
+       mov     a,[4*0 + CTX]
+       mov     b,[4*1 + CTX]
+       mov     c,[4*2 + CTX]
+       mov     d,[4*3 + CTX]
+       mov     e,[4*4 + CTX]
+       mov     f,[4*5 + CTX]
+       mov     g,[4*6 + CTX]
+       mov     h,[4*7 + CTX]
+
+       vmovdqa BYTE_FLIP_MASK, [.LPSHUFFLE_BYTE_FLIP_MASK ADD_RIP]
+       vmovdqa SHUF_00BA, [.L_SHUF_00BA ADD_RIP]
+       vmovdqa SHUF_DC00, [.L_SHUF_DC00 ADD_RIP]
+
+       mov     [rsp + _CTX], CTX
+       jmp     .Ldo_last_block
+
+.Ldone_hash:
+       mov     rsp, [rsp + _RSP]
+
+       vzeroall
+
+       pop     r15
+       pop     r14
+       pop     r13
+       pop     r12
+       pop     rbp
+       pop     rbx
+
+       /* stack burn depth */
+       mov     eax, STACK_SIZE + 6*8 + 31
+
+       ret
+
+.data
+.align 64
+.LK256:
+       .long   0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+       .long   0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+       .long   0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+       .long   0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+       .long   0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+       .long   0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+       .long   0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+       .long   0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+       .long   0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+       .long   0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+       .long   0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+       .long   0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+       .long   0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+       .long   0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+       .long   0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+       .long   0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+       .long   0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+       .long   0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+       .long   0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+       .long   0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+       .long   0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+       .long   0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+       .long   0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+       .long   0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+       .long   0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+       .long   0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+       .long   0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+       .long   0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+       .long   0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+       .long   0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+       .long   0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+       .long   0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+
+.LPSHUFFLE_BYTE_FLIP_MASK:
+       .octa 0x0c0d0e0f08090a0b0405060700010203,0x0c0d0e0f08090a0b0405060700010203
+
+/*  shuffle xBxA -> 00BA */
+.L_SHUF_00BA:
+       .octa 0xFFFFFFFFFFFFFFFF0b0a090803020100,0xFFFFFFFFFFFFFFFF0b0a090803020100
+
+/*  shuffle xDxC -> DC00 */
+.L_SHUF_DC00:
+       .octa 0x0b0a090803020100FFFFFFFFFFFFFFFF,0x0b0a090803020100FFFFFFFFFFFFFFFF
+
+#endif
+#endif
index 9b27f8f..9ec87e4 100644 (file)
@@ -55,7 +55,8 @@
 
 #ifdef __x86_64
 #include <config.h>
-#if defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && \
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
     defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
     defined(HAVE_GCC_INLINE_ASM_SSSE3) && defined(USE_SHA256)
 
 #  define ADD_RIP
 #endif
 
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
+
 .intel_syntax noprefix
 
 #define        MOVDQ movdqu /* assume buffers not aligned */
@@ -206,7 +213,7 @@ a = TMP_
        add     h, y1           /* h = h + S1 + CH + k + w + S0 */
                por     XTMP1, XTMP2    /* XTMP1 = W[-15] ror 7 */
        or      y0, y2          /* y0 = MAJ = (a|c)&b)|(a&c) */
-       add     h, y0           /* h = h + S1 + CH + k + w + S0 + MAJ */
+       lea     h, [h + y0]     /* h = h + S1 + CH + k + w + S0 + MAJ */
 
 ROTATE_ARGS
                movdqa  XTMP2, XTMP3    /* XTMP2 = W[-15] */
@@ -247,7 +254,7 @@ ROTATE_ARGS
        add     h, y1           /* h = h + S1 + CH + k + w + S0 */
                paddd   XTMP0, XTMP1    /* XTMP0 = W[-16] + W[-7] + s0 */
        or      y0, y2          /* y0 = MAJ = (a|c)&b)|(a&c) */
-       add     h, y0           /* h = h + S1 + CH + k + w + S0 + MAJ */
+       lea     h, [h + y0]     /* h = h + S1 + CH + k + w + S0 + MAJ */
 
 ROTATE_ARGS
                movdqa  XTMP3, XTMP2    /* XTMP3 = W[-2] {BBAA} */
@@ -288,7 +295,7 @@ ROTATE_ARGS
                /* compute high s1 */
                pshufd  XTMP2, XTMP0, 0b01010000 /* XTMP2 = W[-2] {DDCC} */
        or      y0, y2          /* y0 = MAJ = (a|c)&b)|(a&c) */
-       add     h, y0           /* h = h + S1 + CH + k + w + S0 + MAJ */
+       lea     h, [h + y0]     /* h = h + S1 + CH + k + w + S0 + MAJ */
 
 ROTATE_ARGS
                movdqa  XTMP3, XTMP2    /* XTMP3 = W[-2] {DDCC} */
@@ -327,7 +334,7 @@ ROTATE_ARGS
        and     y0, b           /* y0 = (a|c)&b */
        add     h, y1           /* h = h + S1 + CH + k + w + S0 */
        or      y0, y2          /* y0 = MAJ = (a|c)&b)|(a&c) */
-       add     h, y0           /* h = h + S1 + CH + k + w + S0 + MAJ */
+       lea     h, [h + y0]     /* h = h + S1 + CH + k + w + S0 + MAJ */
 
 ROTATE_ARGS
 rotate_Xs
@@ -362,7 +369,7 @@ rotate_Xs
        and     y0, b           /* y0 = (a|c)&b */
        add     h, y1           /* h = h + S1 + CH + k + w + S0 */
        or      y0, y2          /* y0 = MAJ = (a|c)&b)|(a&c) */
-       add     h, y0           /* h = h + S1 + CH + k + w + S0 + MAJ */
+       lea     h, [h + y0]     /* h = h + S1 + CH + k + w + S0 + MAJ */
        ROTATE_ARGS
 .endm
 
@@ -376,7 +383,7 @@ rotate_Xs
 */
 .text
 .globl _gcry_sha256_transform_amd64_ssse3
-.type  _gcry_sha256_transform_amd64_ssse3,@function;
+ELF(.type  _gcry_sha256_transform_amd64_ssse3,@function;)
 .align 16
 _gcry_sha256_transform_amd64_ssse3:
        push    rbx
@@ -505,6 +512,7 @@ _gcry_sha256_transform_amd64_ssse3:
        pop     rbx
 
        mov     eax, STACK_SIZE + 5*8
+
        ret
 
 
index d92303c..1b82ee7 100644 (file)
 
 /* USE_SSSE3 indicates whether to compile with Intel SSSE3 code. */
 #undef USE_SSSE3
-#if defined(__x86_64__) && defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && \
-    defined(HAVE_GCC_INLINE_ASM_SSSE3) && \
-    defined(HAVE_INTEL_SYNTAX_PLATFORM_AS)
+#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_SSSE3) && \
+    defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
+    (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
 # define USE_SSSE3 1
 #endif
 
+/* USE_AVX indicates whether to compile with Intel AVX code. */
+#undef USE_AVX
+#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX) && \
+    defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
+    (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define USE_AVX 1
+#endif
+
+/* USE_AVX2 indicates whether to compile with Intel AVX2/BMI2 code. */
+#undef USE_AVX2
+#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX2) && \
+    defined(HAVE_GCC_INLINE_ASM_BMI2) && \
+    defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
+    (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define USE_AVX2 1
+#endif
+
 
 typedef struct {
   gcry_md_block_ctx_t bctx;
@@ -62,17 +82,24 @@ typedef struct {
 #ifdef USE_SSSE3
   unsigned int use_ssse3:1;
 #endif
+#ifdef USE_AVX
+  unsigned int use_avx:1;
+#endif
+#ifdef USE_AVX2
+  unsigned int use_avx2:1;
+#endif
 } SHA256_CONTEXT;
 
 
 static unsigned int
-transform (void *c, const unsigned char *data);
+transform (void *c, const unsigned char *data, size_t nblks);
 
 
 static void
 sha256_init (void *context, unsigned int flags)
 {
   SHA256_CONTEXT *hd = context;
+  unsigned int features = _gcry_get_hw_features ();
 
   (void)flags;
 
@@ -92,8 +119,17 @@ sha256_init (void *context, unsigned int flags)
   hd->bctx.bwrite = transform;
 
 #ifdef USE_SSSE3
-  hd->use_ssse3 = (_gcry_get_hw_features () & HWF_INTEL_SSSE3) != 0;
+  hd->use_ssse3 = (features & HWF_INTEL_SSSE3) != 0;
 #endif
+#ifdef USE_AVX
+  /* AVX implementation uses SHLD which is known to be slow on non-Intel CPUs.
+   * Therefore use this implementation on Intel CPUs only. */
+  hd->use_avx = (features & HWF_INTEL_AVX) && (features & HWF_INTEL_FAST_SHLD);
+#endif
+#ifdef USE_AVX2
+  hd->use_avx2 = (features & HWF_INTEL_AVX2) && (features & HWF_INTEL_BMI2);
+#endif
+  (void)features;
 }
 
 
@@ -101,6 +137,7 @@ static void
 sha224_init (void *context, unsigned int flags)
 {
   SHA256_CONTEXT *hd = context;
+  unsigned int features = _gcry_get_hw_features ();
 
   (void)flags;
 
@@ -120,61 +157,54 @@ sha224_init (void *context, unsigned int flags)
   hd->bctx.bwrite = transform;
 
 #ifdef USE_SSSE3
-  hd->use_ssse3 = (_gcry_get_hw_features () & HWF_INTEL_SSSE3) != 0;
+  hd->use_ssse3 = (features & HWF_INTEL_SSSE3) != 0;
+#endif
+#ifdef USE_AVX
+  /* AVX implementation uses SHLD which is known to be slow on non-Intel CPUs.
+   * Therefore use this implementation on Intel CPUs only. */
+  hd->use_avx = (features & HWF_INTEL_AVX) && (features & HWF_INTEL_FAST_SHLD);
 #endif
+#ifdef USE_AVX2
+  hd->use_avx2 = (features & HWF_INTEL_AVX2) && (features & HWF_INTEL_BMI2);
+#endif
+  (void)features;
 }
 
 
 /*
   Transform the message X which consists of 16 32-bit-words. See FIPS
   180-2 for details.  */
-#define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3))       /* (4.6) */
-#define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10))     /* (4.7) */
 #define R(a,b,c,d,e,f,g,h,k,w) do                                 \
           {                                                       \
             t1 = (h) + Sum1((e)) + Cho((e),(f),(g)) + (k) + (w);  \
             t2 = Sum0((a)) + Maj((a),(b),(c));                    \
-            h = g;                                                \
-            g = f;                                                \
-            f = e;                                                \
-            e = d + t1;                                           \
-            d = c;                                                \
-            c = b;                                                \
-            b = a;                                                \
-            a = t1 + t2;                                          \
+            d += t1;                                              \
+            h  = t1 + t2;                                         \
           } while (0)
 
 /* (4.2) same as SHA-1's F1.  */
-static inline u32
-Cho (u32 x, u32 y, u32 z)
-{
-  return (z ^ (x & (y ^ z)));
-}
+#define Cho(x, y, z)  (z ^ (x & (y ^ z)))
 
 /* (4.3) same as SHA-1's F3 */
-static inline u32
-Maj (u32 x, u32 y, u32 z)
-{
-  return ((x & y) | (z & (x|y)));
-}
+#define Maj(x, y, z)  ((x & y) + (z & (x ^ y)))
 
 /* (4.4) */
-static inline u32
-Sum0 (u32 x)
-{
-  return (ror (x, 2) ^ ror (x, 13) ^ ror (x, 22));
-}
+#define Sum0(x)       (ror (x, 2) ^ ror (x, 13) ^ ror (x, 22))
 
 /* (4.5) */
-static inline u32
-Sum1 (u32 x)
-{
-  return (ror (x, 6) ^ ror (x, 11) ^ ror (x, 25));
-}
+#define Sum1(x)       (ror (x, 6) ^ ror (x, 11) ^ ror (x, 25))
 
+/* Message expansion */
+#define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3))       /* (4.6) */
+#define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10))     /* (4.7) */
+#define I(i) ( w[i] = buf_get_be32(data + i * 4) )
+#define W(i) ( w[i&0x0f] =    S1(w[(i-2) &0x0f]) \
+                            +    w[(i-7) &0x0f]  \
+                            + S0(w[(i-15)&0x0f]) \
+                            +    w[(i-16)&0x0f] )
 
 static unsigned int
-_transform (void *ctx, const unsigned char *data)
+transform_blk (void *ctx, const unsigned char *data)
 {
   SHA256_CONTEXT *hd = ctx;
   static const u32 K[64] = {
@@ -197,8 +227,7 @@ _transform (void *ctx, const unsigned char *data)
   };
 
   u32 a,b,c,d,e,f,g,h,t1,t2;
-  u32 w[64];
-  int i;
+  u32 w[16];
 
   a = hd->h0;
   b = hd->h1;
@@ -209,60 +238,73 @@ _transform (void *ctx, const unsigned char *data)
   g = hd->h6;
   h = hd->h7;
 
-  for (i=0; i < 16; i++)
-    w[i] = buf_get_be32(data + i * 4);
-  for (; i < 64; i++)
-    w[i] = S1(w[i-2]) + w[i-7] + S0(w[i-15]) + w[i-16];
-
-  for (i=0; i < 64;)
-    {
-#if 0
-      R(a,b,c,d,e,f,g,h,K[i],w[i]);
-      i++;
-#else
-      t1 = h + Sum1 (e) + Cho (e, f, g) + K[i] + w[i];
-      t2 = Sum0 (a) + Maj (a, b, c);
-      d += t1;
-      h  = t1 + t2;
-
-      t1 = g + Sum1 (d) + Cho (d, e, f) + K[i+1] + w[i+1];
-      t2 = Sum0 (h) + Maj (h, a, b);
-      c += t1;
-      g  = t1 + t2;
-
-      t1 = f + Sum1 (c) + Cho (c, d, e) + K[i+2] + w[i+2];
-      t2 = Sum0 (g) + Maj (g, h, a);
-      b += t1;
-      f  = t1 + t2;
-
-      t1 = e + Sum1 (b) + Cho (b, c, d) + K[i+3] + w[i+3];
-      t2 = Sum0 (f) + Maj (f, g, h);
-      a += t1;
-      e  = t1 + t2;
-
-      t1 = d + Sum1 (a) + Cho (a, b, c) + K[i+4] + w[i+4];
-      t2 = Sum0 (e) + Maj (e, f, g);
-      h += t1;
-      d  = t1 + t2;
-
-      t1 = c + Sum1 (h) + Cho (h, a, b) + K[i+5] + w[i+5];
-      t2 = Sum0 (d) + Maj (d, e, f);
-      g += t1;
-      c  = t1 + t2;
-
-      t1 = b + Sum1 (g) + Cho (g, h, a) + K[i+6] + w[i+6];
-      t2 = Sum0 (c) + Maj (c, d, e);
-      f += t1;
-      b  = t1 + t2;
-
-      t1 = a + Sum1 (f) + Cho (f, g, h) + K[i+7] + w[i+7];
-      t2 = Sum0 (b) + Maj (b, c, d);
-      e += t1;
-      a  = t1 + t2;
-
-      i += 8;
-#endif
-    }
+  R(a, b, c, d, e, f, g, h, K[0], I(0));
+  R(h, a, b, c, d, e, f, g, K[1], I(1));
+  R(g, h, a, b, c, d, e, f, K[2], I(2));
+  R(f, g, h, a, b, c, d, e, K[3], I(3));
+  R(e, f, g, h, a, b, c, d, K[4], I(4));
+  R(d, e, f, g, h, a, b, c, K[5], I(5));
+  R(c, d, e, f, g, h, a, b, K[6], I(6));
+  R(b, c, d, e, f, g, h, a, K[7], I(7));
+  R(a, b, c, d, e, f, g, h, K[8], I(8));
+  R(h, a, b, c, d, e, f, g, K[9], I(9));
+  R(g, h, a, b, c, d, e, f, K[10], I(10));
+  R(f, g, h, a, b, c, d, e, K[11], I(11));
+  R(e, f, g, h, a, b, c, d, K[12], I(12));
+  R(d, e, f, g, h, a, b, c, K[13], I(13));
+  R(c, d, e, f, g, h, a, b, K[14], I(14));
+  R(b, c, d, e, f, g, h, a, K[15], I(15));
+
+  R(a, b, c, d, e, f, g, h, K[16], W(16));
+  R(h, a, b, c, d, e, f, g, K[17], W(17));
+  R(g, h, a, b, c, d, e, f, K[18], W(18));
+  R(f, g, h, a, b, c, d, e, K[19], W(19));
+  R(e, f, g, h, a, b, c, d, K[20], W(20));
+  R(d, e, f, g, h, a, b, c, K[21], W(21));
+  R(c, d, e, f, g, h, a, b, K[22], W(22));
+  R(b, c, d, e, f, g, h, a, K[23], W(23));
+  R(a, b, c, d, e, f, g, h, K[24], W(24));
+  R(h, a, b, c, d, e, f, g, K[25], W(25));
+  R(g, h, a, b, c, d, e, f, K[26], W(26));
+  R(f, g, h, a, b, c, d, e, K[27], W(27));
+  R(e, f, g, h, a, b, c, d, K[28], W(28));
+  R(d, e, f, g, h, a, b, c, K[29], W(29));
+  R(c, d, e, f, g, h, a, b, K[30], W(30));
+  R(b, c, d, e, f, g, h, a, K[31], W(31));
+
+  R(a, b, c, d, e, f, g, h, K[32], W(32));
+  R(h, a, b, c, d, e, f, g, K[33], W(33));
+  R(g, h, a, b, c, d, e, f, K[34], W(34));
+  R(f, g, h, a, b, c, d, e, K[35], W(35));
+  R(e, f, g, h, a, b, c, d, K[36], W(36));
+  R(d, e, f, g, h, a, b, c, K[37], W(37));
+  R(c, d, e, f, g, h, a, b, K[38], W(38));
+  R(b, c, d, e, f, g, h, a, K[39], W(39));
+  R(a, b, c, d, e, f, g, h, K[40], W(40));
+  R(h, a, b, c, d, e, f, g, K[41], W(41));
+  R(g, h, a, b, c, d, e, f, K[42], W(42));
+  R(f, g, h, a, b, c, d, e, K[43], W(43));
+  R(e, f, g, h, a, b, c, d, K[44], W(44));
+  R(d, e, f, g, h, a, b, c, K[45], W(45));
+  R(c, d, e, f, g, h, a, b, K[46], W(46));
+  R(b, c, d, e, f, g, h, a, K[47], W(47));
+
+  R(a, b, c, d, e, f, g, h, K[48], W(48));
+  R(h, a, b, c, d, e, f, g, K[49], W(49));
+  R(g, h, a, b, c, d, e, f, K[50], W(50));
+  R(f, g, h, a, b, c, d, e, K[51], W(51));
+  R(e, f, g, h, a, b, c, d, K[52], W(52));
+  R(d, e, f, g, h, a, b, c, K[53], W(53));
+  R(c, d, e, f, g, h, a, b, K[54], W(54));
+  R(b, c, d, e, f, g, h, a, K[55], W(55));
+  R(a, b, c, d, e, f, g, h, K[56], W(56));
+  R(h, a, b, c, d, e, f, g, K[57], W(57));
+  R(g, h, a, b, c, d, e, f, K[58], W(58));
+  R(f, g, h, a, b, c, d, e, K[59], W(59));
+  R(e, f, g, h, a, b, c, d, K[60], W(60));
+  R(d, e, f, g, h, a, b, c, K[61], W(61));
+  R(c, d, e, f, g, h, a, b, K[62], W(62));
+  R(b, c, d, e, f, g, h, a, K[63], W(63));
 
   hd->h0 += a;
   hd->h1 += b;
@@ -273,31 +315,87 @@ _transform (void *ctx, const unsigned char *data)
   hd->h6 += g;
   hd->h7 += h;
 
-  return /*burn_stack*/ 74*4+32;
+  return /*burn_stack*/ 26*4+32;
 }
 #undef S0
 #undef S1
 #undef R
 
 
+/* Assembly implementations use SystemV ABI, ABI conversion and additional
+ * stack to store XMM6-XMM15 needed on Win64. */
+#undef ASM_FUNC_ABI
+#undef ASM_EXTRA_STACK
+#if defined(USE_SSSE3) || defined(USE_AVX) || defined(USE_AVX2)
+# ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+#  define ASM_FUNC_ABI __attribute__((sysv_abi))
+#  define ASM_EXTRA_STACK (10 * 16)
+# else
+#  define ASM_FUNC_ABI
+#  define ASM_EXTRA_STACK 0
+# endif
+#endif
+
+
 #ifdef USE_SSSE3
 unsigned int _gcry_sha256_transform_amd64_ssse3(const void *input_data,
-                                               u32 state[8], size_t num_blks);
+                                                u32 state[8],
+                                                size_t num_blks) ASM_FUNC_ABI;
+#endif
+
+#ifdef USE_AVX
+unsigned int _gcry_sha256_transform_amd64_avx(const void *input_data,
+                                              u32 state[8],
+                                              size_t num_blks) ASM_FUNC_ABI;
+#endif
+
+#ifdef USE_AVX2
+unsigned int _gcry_sha256_transform_amd64_avx2(const void *input_data,
+                                               u32 state[8],
+                                               size_t num_blks) ASM_FUNC_ABI;
 #endif
 
 
 static unsigned int
-transform (void *ctx, const unsigned char *data)
+transform (void *ctx, const unsigned char *data, size_t nblks)
 {
   SHA256_CONTEXT *hd = ctx;
+  unsigned int burn;
+
+#ifdef USE_AVX2
+  if (hd->use_avx2)
+    return _gcry_sha256_transform_amd64_avx2 (data, &hd->h0, nblks)
+           + 4 * sizeof(void*) + ASM_EXTRA_STACK;
+#endif
+
+#ifdef USE_AVX
+  if (hd->use_avx)
+    return _gcry_sha256_transform_amd64_avx (data, &hd->h0, nblks)
+           + 4 * sizeof(void*) + ASM_EXTRA_STACK;
+#endif
 
 #ifdef USE_SSSE3
   if (hd->use_ssse3)
-    return _gcry_sha256_transform_amd64_ssse3 (data, &hd->h0, 1)
-           + 4 * sizeof(void*);
+    return _gcry_sha256_transform_amd64_ssse3 (data, &hd->h0, nblks)
+           + 4 * sizeof(void*) + ASM_EXTRA_STACK;
+#endif
+
+  do
+    {
+      burn = transform_blk (hd, data);
+      data += 64;
+    }
+  while (--nblks);
+
+#ifdef ASM_EXTRA_STACK
+  /* 'transform_blk' is typically inlined and XMM6-XMM15 are stored at
+   *  the prologue of this function. Therefore need to add ASM_EXTRA_STACK to
+   *  here too.
+   */
+  burn += ASM_EXTRA_STACK;
 #endif
 
-  return _transform (hd, data);
+  return burn;
 }
 
 
@@ -352,11 +450,11 @@ sha256_final(void *context)
   /* append the 64 bit count */
   buf_put_be32(hd->bctx.buf + 56, msb);
   buf_put_be32(hd->bctx.buf + 60, lsb);
-  burn = transform (hd, hd->bctx.buf);
+  burn = transform (hd, hd->bctx.buf, 1);
   _gcry_burn_stack (burn);
 
   p = hd->bctx.buf;
-#define X(a) do { *(u32*)p = be_bswap32(hd->h##a); p += 4; } while(0)
+#define X(a) do { buf_put_be32(p, hd->h##a); p += 4; } while(0)
   X(0);
   X(1);
   X(2);
@@ -531,7 +629,7 @@ gcry_md_spec_t _gcry_digest_spec_sha224 =
   {
     GCRY_MD_SHA224, {0, 1},
     "SHA224", asn224, DIM (asn224), oid_spec_sha224, 28,
-    sha224_init, _gcry_md_block_write, sha256_final, sha256_read,
+    sha224_init, _gcry_md_block_write, sha256_final, sha256_read, NULL,
     sizeof (SHA256_CONTEXT),
     run_selftests
   };
@@ -540,7 +638,7 @@ gcry_md_spec_t _gcry_digest_spec_sha256 =
   {
     GCRY_MD_SHA256, {0, 1},
     "SHA256", asn256, DIM (asn256), oid_spec_sha256, 32,
-    sha256_init, _gcry_md_block_write, sha256_final, sha256_read,
+    sha256_init, _gcry_md_block_write, sha256_final, sha256_read, NULL,
     sizeof (SHA256_CONTEXT),
     run_selftests
   };
diff --git a/cipher/sha512-arm.S b/cipher/sha512-arm.S
new file mode 100644 (file)
index 0000000..28f156e
--- /dev/null
@@ -0,0 +1,465 @@
+/* sha512-arm.S  -  ARM assembly implementation of SHA-512 transform
+ *
+ * Copyright (C) 2016 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <config.h>
+
+#if defined(__ARMEL__)
+#ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS
+
+.text
+
+.syntax unified
+.arm
+
+/* structure of SHA512_CONTEXT */
+#define hd_a 0
+#define hd_b ((hd_a) + 8)
+#define hd_c ((hd_b) + 8)
+#define hd_d ((hd_c) + 8)
+#define hd_e ((hd_d) + 8)
+#define hd_f ((hd_e) + 8)
+#define hd_g ((hd_f) + 8)
+#define hd_h ((hd_g) + 8)
+
+/* register macros */
+#define RK    %r2
+
+#define RElo %r0
+#define REhi %r1
+
+#define RT1lo %r3
+#define RT1hi %r4
+#define RT2lo %r5
+#define RT2hi %r6
+#define RWlo  %r7
+#define RWhi  %r8
+#define RT3lo %r9
+#define RT3hi %r10
+#define RT4lo %r11
+#define RT4hi %ip
+
+#define RRND  %lr
+
+/* variable offsets in stack */
+#define ctx (0)
+#define data ((ctx) + 4)
+#define nblks ((data) + 4)
+#define _a ((nblks) + 4)
+#define _b ((_a) + 8)
+#define _c ((_b) + 8)
+#define _d ((_c) + 8)
+#define _e ((_d) + 8)
+#define _f ((_e) + 8)
+#define _g ((_f) + 8)
+#define _h ((_g) + 8)
+
+#define w(i) ((_h) + 8 + ((i) % 16) * 8)
+
+#define STACK_MAX (w(15) + 8)
+
+/* helper macros */
+#define ldr_unaligned_be(rout, rsrc, offs, rtmp) \
+    ldrb rout, [rsrc, #((offs) + 3)]; \
+    ldrb rtmp, [rsrc, #((offs) + 2)]; \
+    orr rout, rout, rtmp, lsl #8; \
+    ldrb rtmp, [rsrc, #((offs) + 1)]; \
+    orr rout, rout, rtmp, lsl #16; \
+    ldrb rtmp, [rsrc, #((offs) + 0)]; \
+    orr rout, rout, rtmp, lsl #24;
+
+#ifdef __ARMEL__
+    /* bswap on little-endian */
+#ifdef HAVE_ARM_ARCH_V6
+    #define be_to_host(reg, rtmp) \
+       rev reg, reg;
+#else
+    #define be_to_host(reg, rtmp) \
+       eor rtmp, reg, reg, ror #16; \
+       mov rtmp, rtmp, lsr #8; \
+       bic rtmp, rtmp, #65280; \
+       eor reg, rtmp, reg, ror #8;
+#endif
+#else
+    /* nop on big-endian */
+    #define be_to_host(reg, rtmp) /*_*/
+#endif
+
+#define host_to_host(x, y) /*_*/
+
+#define read_u64_aligned_4(rin, offs, lo0, hi0, lo1, hi1, lo2, hi2, lo3, hi3, convert, rtmp) \
+    ldr lo0, [rin, #((offs) + 0 * 8 + 4)]; \
+    ldr hi0, [rin, #((offs) + 0 * 8 + 0)]; \
+    ldr lo1, [rin, #((offs) + 1 * 8 + 4)]; \
+    ldr hi1, [rin, #((offs) + 1 * 8 + 0)]; \
+    ldr lo2, [rin, #((offs) + 2 * 8 + 4)]; \
+    convert(lo0, rtmp); \
+    ldr hi2, [rin, #((offs) + 2 * 8 + 0)]; \
+    convert(hi0, rtmp); \
+    ldr lo3, [rin, #((offs) + 3 * 8 + 4)]; \
+    convert(lo1, rtmp); \
+    ldr hi3, [rin, #((offs) + 3 * 8 + 0)]; \
+    convert(hi1, rtmp); \
+    convert(lo2, rtmp); \
+    convert(hi2, rtmp); \
+    convert(lo3, rtmp); \
+    convert(hi3, rtmp);
+
+#define read_be64_aligned_4(rin, offs, lo0, hi0, lo1, hi1, lo2, hi2, lo3, hi3, rtmp0) \
+    read_u64_aligned_4(rin, offs, lo0, hi0, lo1, hi1, lo2, hi2, lo3, hi3, be_to_host, rtmp0)
+
+/* need to handle unaligned reads by byte reads */
+#define read_be64_unaligned_4(rin, offs, lo0, hi0, lo1, hi1, lo2, hi2, lo3, hi3, rtmp0) \
+    ldr_unaligned_be(lo0, rin, (offs) + 0 * 8 + 4, rtmp0); \
+    ldr_unaligned_be(hi0, rin, (offs) + 0 * 8 + 0, rtmp0); \
+    ldr_unaligned_be(lo1, rin, (offs) + 1 * 8 + 4, rtmp0); \
+    ldr_unaligned_be(hi1, rin, (offs) + 1 * 8 + 0, rtmp0); \
+    ldr_unaligned_be(lo2, rin, (offs) + 2 * 8 + 4, rtmp0); \
+    ldr_unaligned_be(hi2, rin, (offs) + 2 * 8 + 0, rtmp0); \
+    ldr_unaligned_be(lo3, rin, (offs) + 3 * 8 + 4, rtmp0); \
+    ldr_unaligned_be(hi3, rin, (offs) + 3 * 8 + 0, rtmp0);
+
+/***********************************************************************
+ * ARM assembly implementation of sha512 transform
+ ***********************************************************************/
+
+/* Round function */
+
+#define R(_a,_b,_c,_d,_e,_f,_g,_h,W,wi) \
+    /* Message expansion, t1 = _h + w[i] */ \
+    W(_a,_h,wi); \
+    \
+    /* w = Sum1(_e) */ \
+    mov RWlo, RElo, lsr#14; \
+    ldm RK!, {RT2lo-RT2hi}; \
+    mov RWhi, REhi, lsr#14; \
+    eor RWlo, RWlo, RElo, lsr#18; \
+    eor RWhi, RWhi, REhi, lsr#18; \
+    ldr RT3lo, [%sp, #(_f)]; \
+    adds RT1lo, RT2lo; /* t1 += K */ \
+    ldr RT3hi, [%sp, #(_f) + 4]; \
+    adc RT1hi, RT2hi; \
+    ldr RT4lo, [%sp, #(_g)]; \
+    eor RWlo, RWlo, RElo, lsl#23; \
+    ldr RT4hi, [%sp, #(_g) + 4]; \
+    eor RWhi, RWhi, REhi, lsl#23; \
+    eor RWlo, RWlo, REhi, lsl#18; \
+    eor RWhi, RWhi, RElo, lsl#18; \
+    eor RWlo, RWlo, REhi, lsl#14; \
+    eor RWhi, RWhi, RElo, lsl#14; \
+    eor RWlo, RWlo, REhi, lsr#9; \
+    eor RWhi, RWhi, RElo, lsr#9; \
+    \
+    /* Cho(_e,_f,_g) => (_e & _f) ^ (~_e & _g) */ \
+    adds RT1lo, RWlo; /* t1 += Sum1(_e) */ \
+    and RT3lo, RT3lo, RElo; \
+    adc RT1hi, RWhi; \
+    and RT3hi, RT3hi, REhi; \
+    bic RT4lo, RT4lo, RElo; \
+    bic RT4hi, RT4hi, REhi; \
+    eor RT3lo, RT3lo, RT4lo; \
+    eor RT3hi, RT3hi, RT4hi; \
+    \
+    /* Load D */ \
+    /* t1 += Cho(_e,_f,_g) */ \
+    ldr RElo, [%sp, #(_d)]; \
+    adds RT1lo, RT3lo; \
+    ldr REhi, [%sp, #(_d) + 4]; \
+    adc RT1hi, RT3hi; \
+    \
+    /* Load A */ \
+    ldr RT3lo, [%sp, #(_a)]; \
+    \
+    /* _d += t1 */ \
+    adds RElo, RT1lo; \
+    ldr RT3hi, [%sp, #(_a) + 4]; \
+    adc REhi, RT1hi; \
+    \
+    /* Store D */ \
+    str RElo, [%sp, #(_d)]; \
+    \
+    /* t2 = Sum0(_a) */ \
+    mov RT2lo, RT3lo, lsr#28; \
+    str REhi, [%sp, #(_d) + 4]; \
+    mov RT2hi, RT3hi, lsr#28; \
+    ldr RWlo, [%sp, #(_b)]; \
+    eor RT2lo, RT2lo, RT3lo, lsl#30; \
+    ldr RWhi, [%sp, #(_b) + 4]; \
+    eor RT2hi, RT2hi, RT3hi, lsl#30; \
+    eor RT2lo, RT2lo, RT3lo, lsl#25; \
+    eor RT2hi, RT2hi, RT3hi, lsl#25; \
+    eor RT2lo, RT2lo, RT3hi, lsl#4; \
+    eor RT2hi, RT2hi, RT3lo, lsl#4; \
+    eor RT2lo, RT2lo, RT3hi, lsr#2; \
+    eor RT2hi, RT2hi, RT3lo, lsr#2; \
+    eor RT2lo, RT2lo, RT3hi, lsr#7; \
+    eor RT2hi, RT2hi, RT3lo, lsr#7; \
+    \
+    /* t2 += t1 */ \
+    adds RT2lo, RT1lo; \
+    ldr RT1lo, [%sp, #(_c)]; \
+    adc RT2hi, RT1hi; \
+    \
+    /* Maj(_a,_b,_c) => ((_a & _b) ^ (_c & (_a ^ _b))) */ \
+    ldr RT1hi, [%sp, #(_c) + 4]; \
+    and RT4lo, RWlo, RT3lo; \
+    and RT4hi, RWhi, RT3hi; \
+    eor RWlo, RWlo, RT3lo; \
+    eor RWhi, RWhi, RT3hi; \
+    and RWlo, RWlo, RT1lo; \
+    and RWhi, RWhi, RT1hi; \
+    eor RWlo, RWlo, RT4lo; \
+    eor RWhi, RWhi, RT4hi; \
+
+/* Message expansion */
+
+#define W_0_63(_a,_h,i) \
+    ldr RT3lo, [%sp, #(w(i-2))]; \
+    adds RT2lo, RWlo; /* _h = t2 + Maj(_a,_b,_c) */ \
+    ldr RT3hi, [%sp, #(w(i-2)) + 4]; \
+    adc RT2hi, RWhi; \
+    /* nw = S1(w[i-2]) */ \
+    ldr RT1lo, [%sp, #(_h)]; /* Load H */ \
+    mov RWlo, RT3lo, lsr#19; \
+    str RT2lo, [%sp, #(_a)]; \
+    eor RWlo, RWlo, RT3lo, lsl#3; \
+    ldr RT1hi, [%sp, #(_h) + 4]; \
+    mov RWhi, RT3hi, lsr#19; \
+    ldr RT2lo, [%sp, #(w(i-7))]; \
+    eor RWhi, RWhi, RT3hi, lsl#3; \
+    str RT2hi, [%sp, #(_a) + 4]; \
+    eor RWlo, RWlo, RT3lo, lsr#6; \
+    ldr RT2hi, [%sp, #(w(i-7)) + 4]; \
+    eor RWhi, RWhi, RT3hi, lsr#6; \
+    eor RWlo, RWlo, RT3hi, lsl#13; \
+    eor RWhi, RWhi, RT3lo, lsl#13; \
+    eor RWlo, RWlo, RT3hi, lsr#29; \
+    eor RWhi, RWhi, RT3lo, lsr#29; \
+    ldr RT3lo, [%sp, #(w(i-15))]; \
+    eor RWlo, RWlo, RT3hi, lsl#26; \
+    ldr RT3hi, [%sp, #(w(i-15)) + 4]; \
+    \
+    adds RT2lo, RWlo; /* nw += w[i-7] */ \
+    ldr RWlo, [%sp, #(w(i-16))]; \
+    adc RT2hi, RWhi; \
+    mov RT4lo, RT3lo, lsr#1; /* S0(w[i-15]) */ \
+    ldr RWhi, [%sp, #(w(i-16)) + 4]; \
+    mov RT4hi, RT3hi, lsr#1; \
+    adds RT2lo, RWlo; /* nw += w[i-16] */ \
+    eor RT4lo, RT4lo, RT3lo, lsr#8; \
+    eor RT4hi, RT4hi, RT3hi, lsr#8; \
+    eor RT4lo, RT4lo, RT3lo, lsr#7; \
+    eor RT4hi, RT4hi, RT3hi, lsr#7; \
+    eor RT4lo, RT4lo, RT3hi, lsl#31; \
+    eor RT4hi, RT4hi, RT3lo, lsl#31; \
+    eor RT4lo, RT4lo, RT3hi, lsl#24; \
+    eor RT4hi, RT4hi, RT3lo, lsl#24; \
+    eor RT4lo, RT4lo, RT3hi, lsl#25; \
+    adc RT2hi, RWhi; \
+    \
+    /* nw += S0(w[i-15]) */ \
+    adds RT2lo, RT4lo; \
+    adc RT2hi, RT4hi; \
+    \
+    /* w[0] = nw */ \
+    str RT2lo, [%sp, #(w(i))]; \
+    adds RT1lo, RWlo; \
+    str RT2hi, [%sp, #(w(i)) + 4]; \
+    adc RT1hi, RWhi;
+
+#define W_64_79(_a,_h,i) \
+    adds RT2lo, RWlo; /* _h = t2 + Maj(_a,_b,_c) */ \
+    ldr RWlo, [%sp, #(w(i-16))]; \
+    adc RT2hi, RWhi; \
+    ldr RWhi, [%sp, #(w(i-16)) + 4]; \
+    ldr RT1lo, [%sp, #(_h)]; /* Load H */ \
+    ldr RT1hi, [%sp, #(_h) + 4]; \
+    str RT2lo, [%sp, #(_a)]; \
+    str RT2hi, [%sp, #(_a) + 4]; \
+    adds RT1lo, RWlo; \
+    adc RT1hi, RWhi;
+
+.align 3
+.globl _gcry_sha512_transform_arm
+.type  _gcry_sha512_transform_arm,%function;
+
+_gcry_sha512_transform_arm:
+       /* Input:
+        *      %r0: SHA512_CONTEXT
+        *      %r1: data
+        *      %r2: u64 k[] constants
+        *      %r3: nblks
+        */
+       push {%r4-%r11, %ip, %lr};
+       sub %sp, %sp, #STACK_MAX;
+       movs RWlo, %r3;
+       str %r0, [%sp, #(ctx)];
+
+       beq .Ldone;
+
+.Loop_blocks:
+       str RWlo, [%sp, #nblks];
+
+       /* Load context to stack */
+       add RWhi, %sp, #(_a);
+       ldm %r0!,  {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi}
+       stm RWhi!, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi}
+       ldm %r0,  {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi}
+       stm RWhi, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi}
+
+       /* Load input to w[16] */
+#ifndef __ARM_FEATURE_UNALIGNED
+       /* test if data is unaligned */
+       tst %r1, #3;
+       beq 1f;
+
+       /* unaligned load */
+       add RWhi, %sp, #(w(0));
+       read_be64_unaligned_4(%r1, 0 * 8, RT1lo, RT1hi, RT2lo, RT2hi, RT3lo, RT3hi, RT4lo, RT4hi, RWlo);
+       stm RWhi!, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi}
+
+       read_be64_unaligned_4(%r1, 4 * 8, RT1lo, RT1hi, RT2lo, RT2hi, RT3lo, RT3hi, RT4lo, RT4hi, RWlo);
+       stm RWhi!, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi}
+
+       read_be64_unaligned_4(%r1, 8 * 8, RT1lo, RT1hi, RT2lo, RT2hi, RT3lo, RT3hi, RT4lo, RT4hi, RWlo);
+       stm RWhi!, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi}
+
+       read_be64_unaligned_4(%r1, 12 * 8, RT1lo, RT1hi, RT2lo, RT2hi, RT3lo, RT3hi, RT4lo, RT4hi, RWlo);
+       b 2f;
+#endif
+1:
+       /* aligned load */
+       add RWhi, %sp, #(w(0));
+       read_be64_aligned_4(%r1, 0 * 8, RT1lo, RT1hi, RT2lo, RT2hi, RT3lo, RT3hi, RT4lo, RT4hi, RWlo);
+       stm RWhi!, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi}
+
+       read_be64_aligned_4(%r1, 4 * 8, RT1lo, RT1hi, RT2lo, RT2hi, RT3lo, RT3hi, RT4lo, RT4hi, RWlo);
+       stm RWhi!, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi}
+
+       read_be64_aligned_4(%r1, 8 * 8, RT1lo, RT1hi, RT2lo, RT2hi, RT3lo, RT3hi, RT4lo, RT4hi, RWlo);
+       stm RWhi!, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi}
+
+       read_be64_aligned_4(%r1, 12 * 8, RT1lo, RT1hi, RT2lo, RT2hi, RT3lo, RT3hi, RT4lo, RT4hi, RWlo);
+2:
+       add %r1, #(16 * 8);
+       stm RWhi, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi}
+       str %r1, [%sp, #(data)];
+
+       /* preload E & A */
+       ldr RElo, [%sp, #(_e)];
+       ldr REhi, [%sp, #(_e) + 4];
+       mov RWlo, #0;
+       ldr RT2lo, [%sp, #(_a)];
+       mov RRND, #(80-16);
+       ldr RT2hi, [%sp, #(_a) + 4];
+       mov RWhi, #0;
+
+.Loop_rounds:
+       R(_a, _b, _c, _d, _e, _f, _g, _h, W_0_63, 16);
+       R(_h, _a, _b, _c, _d, _e, _f, _g, W_0_63, 17);
+       R(_g, _h, _a, _b, _c, _d, _e, _f, W_0_63, 18);
+       R(_f, _g, _h, _a, _b, _c, _d, _e, W_0_63, 19);
+       R(_e, _f, _g, _h, _a, _b, _c, _d, W_0_63, 20);
+       R(_d, _e, _f, _g, _h, _a, _b, _c, W_0_63, 21);
+       R(_c, _d, _e, _f, _g, _h, _a, _b, W_0_63, 22);
+       R(_b, _c, _d, _e, _f, _g, _h, _a, W_0_63, 23);
+       R(_a, _b, _c, _d, _e, _f, _g, _h, W_0_63, 24);
+       R(_h, _a, _b, _c, _d, _e, _f, _g, W_0_63, 25);
+       R(_g, _h, _a, _b, _c, _d, _e, _f, W_0_63, 26);
+       R(_f, _g, _h, _a, _b, _c, _d, _e, W_0_63, 27);
+       R(_e, _f, _g, _h, _a, _b, _c, _d, W_0_63, 28);
+       R(_d, _e, _f, _g, _h, _a, _b, _c, W_0_63, 29);
+       R(_c, _d, _e, _f, _g, _h, _a, _b, W_0_63, 30);
+       R(_b, _c, _d, _e, _f, _g, _h, _a, W_0_63, 31);
+
+       subs RRND, #16;
+       bne .Loop_rounds;
+
+       R(_a, _b, _c, _d, _e, _f, _g, _h, W_64_79, 16);
+       R(_h, _a, _b, _c, _d, _e, _f, _g, W_64_79, 17);
+       R(_g, _h, _a, _b, _c, _d, _e, _f, W_64_79, 18);
+       R(_f, _g, _h, _a, _b, _c, _d, _e, W_64_79, 19);
+       R(_e, _f, _g, _h, _a, _b, _c, _d, W_64_79, 20);
+       R(_d, _e, _f, _g, _h, _a, _b, _c, W_64_79, 21);
+       R(_c, _d, _e, _f, _g, _h, _a, _b, W_64_79, 22);
+       R(_b, _c, _d, _e, _f, _g, _h, _a, W_64_79, 23);
+       R(_a, _b, _c, _d, _e, _f, _g, _h, W_64_79, 24);
+       R(_h, _a, _b, _c, _d, _e, _f, _g, W_64_79, 25);
+       R(_g, _h, _a, _b, _c, _d, _e, _f, W_64_79, 26);
+       R(_f, _g, _h, _a, _b, _c, _d, _e, W_64_79, 27);
+       R(_e, _f, _g, _h, _a, _b, _c, _d, W_64_79, 28);
+       R(_d, _e, _f, _g, _h, _a, _b, _c, W_64_79, 29);
+       R(_c, _d, _e, _f, _g, _h, _a, _b, W_64_79, 30);
+       R(_b, _c, _d, _e, _f, _g, _h, _a, W_64_79, 31);
+
+       ldr %r0, [%sp, #(ctx)];
+       adds RT2lo, RWlo; /* _h = t2 + Maj(_a,_b,_c) */
+       ldr %r1, [%sp, #(data)];
+       adc RT2hi, RWhi;
+
+       ldm %r0, {RT1lo,RT1hi,RWlo,RWhi,RT3lo,RT3hi,RT4lo,RT4hi}
+       adds RT1lo, RT2lo;
+       ldr RT2lo, [%sp, #(_b + 0)];
+       adc  RT1hi, RT2hi;
+       ldr RT2hi, [%sp, #(_b + 4)];
+       adds RWlo, RT2lo;
+       ldr RT2lo, [%sp, #(_c + 0)];
+       adc  RWhi, RT2hi;
+       ldr RT2hi, [%sp, #(_c + 4)];
+       adds RT3lo, RT2lo;
+       ldr RT2lo, [%sp, #(_d + 0)];
+       adc  RT3hi, RT2hi;
+       ldr RT2hi, [%sp, #(_d + 4)];
+       adds RT4lo, RT2lo;
+       ldr RT2lo, [%sp, #(_e + 0)];
+       adc  RT4hi, RT2hi;
+       stm %r0!, {RT1lo,RT1hi,RWlo,RWhi,RT3lo,RT3hi,RT4lo,RT4hi}
+
+       ldr RT2hi, [%sp, #(_e + 4)];
+       ldm %r0, {RT1lo,RT1hi,RWlo,RWhi,RT3lo,RT3hi,RT4lo,RT4hi}
+       adds RT1lo, RT2lo;
+       ldr RT2lo, [%sp, #(_f + 0)];
+       adc  RT1hi, RT2hi;
+       ldr RT2hi, [%sp, #(_f + 4)];
+       adds RWlo, RT2lo;
+       ldr RT2lo, [%sp, #(_g + 0)];
+       adc  RWhi, RT2hi;
+       ldr RT2hi, [%sp, #(_g + 4)];
+       adds RT3lo, RT2lo;
+       ldr RT2lo, [%sp, #(_h + 0)];
+       adc  RT3hi, RT2hi;
+       ldr RT2hi, [%sp, #(_h + 4)];
+       adds RT4lo, RT2lo;
+       adc  RT4hi, RT2hi;
+       stm %r0, {RT1lo,RT1hi,RWlo,RWhi,RT3lo,RT3hi,RT4lo,RT4hi}
+       sub %r0, %r0, #(4 * 8);
+       ldr RWlo, [%sp, #nblks];
+
+       sub RK, #(80 * 8);
+       subs RWlo, #1;
+       bne .Loop_blocks;
+
+.Ldone:
+       mov %r0, #STACK_MAX;
+__out:
+       add %sp, %sp, #STACK_MAX;
+       pop {%r4-%r11, %ip, %pc};
+.size _gcry_sha512_transform_arm,.-_gcry_sha512_transform_arm;
+
+#endif
+#endif
index 042b15a..a9d1272 100644 (file)
@@ -1,6 +1,6 @@
 /* sha512-armv7-neon.S  -  ARM/NEON assembly implementation of SHA-512 transform
  *
- * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
 #define RT6 d14
 #define RT7 d15
 
+#define RT01q q4
+#define RT23q q5
+#define RT45q q6
+#define RT67q q7
+
 #define RW0 d16
 #define RW1 d17
 #define RW2 d18
 /***********************************************************************
  * ARM assembly implementation of sha512 transform
  ***********************************************************************/
-#define round_0_63(ra, rb, rc, rd, re, rf, rg, rh, rw0, rw14, rw9, rw1) \
+#define rounds2_0_63(ra, rb, rc, rd, re, rf, rg, rh, rw0, rw1, rw01q, rw2, rw23q, rw1415q, rw9, rw10, interleave_op, arg1) \
        /* t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t]; */ \
-       vshr.u64 RT1, re, #14; \
+       vshr.u64 RT2, re, #14; \
        vshl.u64 RT3, re, #64 - 14; \
+       interleave_op(arg1); \
        vshr.u64 RT4, re, #18; \
        vshl.u64 RT5, re, #64 - 18; \
-       veor.64 RT1, RT1, RT3; \
        vld1.64 {RT0}, [RK]!; \
-       veor.64 RT1, RT1, RT4; \
-       vshr.u64 RT3, re, #41; \
-       vshl.u64 RT4, re, #64 - 41; \
-       veor.64 RT1, RT1, RT5; \
+       veor.64 RT23q, RT23q, RT45q; \
+       vshr.u64 RT4, re, #41; \
+       vshl.u64 RT5, re, #64 - 41; \
        vadd.u64 RT0, RT0, rw0; \
-       veor.64 RT1, RT1, RT3; \
-       vand.64 RT2, re, rf; \
-       veor.64 RT1, RT1, RT4; \
-       vbic.64 RT6, rg, re; \
+       veor.64 RT23q, RT23q, RT45q; \
+       vmov.64 RT7, re; \
+       veor.64 RT1, RT2, RT3; \
+       vbsl.64 RT7, rf, rg; \
        \
        vadd.u64 RT1, RT1, rh; \
-       veor.64 RT2, RT2, RT6; \
-       vshr.u64 rh, ra, #28; \
+       vshr.u64 RT2, ra, #28; \
        vshl.u64 RT3, ra, #64 - 28; \
        vadd.u64 RT1, RT1, RT0; \
        vshr.u64 RT4, ra, #34; \
-       veor.64 rh, rh, RT3; \
        vshl.u64 RT5, ra, #64 - 34; \
-       vadd.u64 RT1, RT1, RT2; \
+       vadd.u64 RT1, RT1, RT7; \
        \
        /* h = Sum0 (a) + Maj (a, b, c); */ \
-       veor.64 rh, rh, RT4; \
-       vshr.u64 RT3, ra, #39; \
-       vshl.u64 RT4, ra, #64 - 39; \
-       vorr.64 RT6, ra, rb; \
-       vand.64 RT0, ra, rb; \
-       veor.64 rh, rh, RT5; \
-       vand.64 RT6, RT6, rc; \
-       veor.64 rh, rh, RT3; \
-       vorr.64 RT0, RT0, RT6; \
-       veor.64 rh, rh, RT4; \
-       vshr.u64 RT4, rw14, #19; \
+       veor.64 RT23q, RT23q, RT45q; \
+       vshr.u64 RT4, ra, #39; \
+       vshl.u64 RT5, ra, #64 - 39; \
+       veor.64 RT0, ra, rb; \
+       veor.64 RT23q, RT23q, RT45q; \
+       vbsl.64 RT0, rc, rb; \
+       vadd.u64 rd, rd, RT1; /* d+=t1; */ \
+       veor.64 rh, RT2, RT3; \
+       \
+       /* t1 = g + Sum1 (d) + Ch (d, e, f) + k[t] + w[t]; */ \
+       vshr.u64 RT2, rd, #14; \
+       vshl.u64 RT3, rd, #64 - 14; \
        vadd.u64 rh, rh, RT0; \
-       vshl.u64 RT2, rw14, #64 - 19; \
+       vshr.u64 RT4, rd, #18; \
+       vshl.u64 RT5, rd, #64 - 18; \
+       vadd.u64 rh, rh, RT1; /* h+=t1; */ \
+       vld1.64 {RT0}, [RK]!; \
+       veor.64 RT23q, RT23q, RT45q; \
+       vshr.u64 RT4, rd, #41; \
+       vshl.u64 RT5, rd, #64 - 41; \
+       vadd.u64 RT0, RT0, rw1; \
+       veor.64 RT23q, RT23q, RT45q; \
+       vmov.64 RT7, rd; \
+       veor.64 RT1, RT2, RT3; \
+       vbsl.64 RT7, re, rf; \
+       \
+       vadd.u64 RT1, RT1, rg; \
+       vshr.u64 RT2, rh, #28; \
+       vshl.u64 RT3, rh, #64 - 28; \
+       vadd.u64 RT1, RT1, RT0; \
+       vshr.u64 RT4, rh, #34; \
+       vshl.u64 RT5, rh, #64 - 34; \
+       vadd.u64 RT1, RT1, RT7; \
+       \
+       /* g = Sum0 (h) + Maj (h, a, b); */ \
+       veor.64 RT23q, RT23q, RT45q; \
+       vshr.u64 RT4, rh, #39; \
+       vshl.u64 RT5, rh, #64 - 39; \
+       veor.64 RT0, rh, ra; \
+       veor.64 RT23q, RT23q, RT45q; \
+       vbsl.64 RT0, rb, ra; \
+       vadd.u64 rc, rc, RT1; /* c+=t1; */ \
+       veor.64 rg, RT2, RT3; \
        \
        /* w[0] += S1 (w[14]) + w[9] + S0 (w[1]); */ \
-       vshr.u64 RT3, rw14, #61; \
-       vshl.u64 RT6, rw14, #64 - 61; \
-       veor.64 RT0, RT4, RT2; \
-       vshr.u64 RT2, rw14, 6; \
-       veor.64 RT0, RT0, RT3; \
-       vshr.u64 RT7, rw1, #1; \
-       veor.64 RT0, RT0, RT6; \
-       vshl.u64 RT4, rw1, #64 - 1; \
-       veor.64 RT0, RT0, RT2; \
-       vshr.u64 RT5, rw1, #8; \
-       vadd.u64 rw0, rw0, RT0; \
-       vshl.u64 RT6, rw1, #64 - 8; \
-       veor.64 RT7, RT7, RT4; \
-       vshr.u64 RT4, rw1, 7; \
-       veor.64 RT7, RT7, RT5; \
-       vadd.u64 rw0, rw0, rw9; /* w[0]+=w[9]; */\
-       veor.64 RT7, RT7, RT6; \
-       vadd.u64 rd, rd, RT1; /* d+=t1; */ \
-       veor.64 RT7, RT7, RT4; \
-       vadd.u64 rh, rh, RT1; /* h+=t1; */ \
-       vadd.u64 rw0, rw0, RT7; \
+       /* w[1] += S1 (w[15]) + w[10] + S0 (w[2]); */ \
+       \
+       /**** S0(w[1:2]) */ \
+       \
+       /* w[0:1] += w[9:10] */ \
+       /* RT23q = rw1:rw2 */ \
+       vext.u64 RT23q, rw01q, rw23q, #1; \
+       vadd.u64 rw0, rw9; \
+       vadd.u64 rg, rg, RT0; \
+       vadd.u64 rw1, rw10;\
+       vadd.u64 rg, rg, RT1; /* g+=t1; */ \
+       \
+       vshr.u64 RT45q, RT23q, #1; \
+       vshl.u64 RT67q, RT23q, #64 - 1; \
+       vshr.u64 RT01q, RT23q, #8; \
+       veor.u64 RT45q, RT45q, RT67q; \
+       vshl.u64 RT67q, RT23q, #64 - 8; \
+       veor.u64 RT45q, RT45q, RT01q; \
+       vshr.u64 RT01q, RT23q, #7; \
+       veor.u64 RT45q, RT45q, RT67q; \
+       \
+       /**** S1(w[14:15]) */ \
+       vshr.u64 RT23q, rw1415q, #6; \
+       veor.u64 RT01q, RT01q, RT45q; \
+       vshr.u64 RT45q, rw1415q, #19; \
+       vshl.u64 RT67q, rw1415q, #64 - 19; \
+       veor.u64 RT23q, RT23q, RT45q; \
+       vshr.u64 RT45q, rw1415q, #61; \
+       veor.u64 RT23q, RT23q, RT67q; \
+       vshl.u64 RT67q, rw1415q, #64 - 61; \
+       veor.u64 RT23q, RT23q, RT45q; \
+       vadd.u64 rw01q, RT01q; /* w[0:1] += S(w[1:2]) */ \
+       veor.u64 RT01q, RT23q, RT67q;
+#define vadd_RT01q(rw01q) \
+       /* w[0:1] += S(w[14:15]) */ \
+       vadd.u64 rw01q, RT01q;
+
+#define dummy(_) /*_*/
 
-#define round_64_79(ra, rb, rc, rd, re, rf, rg, rh, rw0) \
+#define rounds2_64_79(ra, rb, rc, rd, re, rf, rg, rh, rw0, rw1, interleave_op1, arg1, interleave_op2, arg2) \
        /* t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t]; */ \
-       vld1.64 {RT0}, [RK]!; \
-       vshr.u64 RT1, re, #14; \
+       vshr.u64 RT2, re, #14; \
        vshl.u64 RT3, re, #64 - 14; \
+       interleave_op1(arg1); \
        vshr.u64 RT4, re, #18; \
        vshl.u64 RT5, re, #64 - 18; \
-       veor.64 RT1, RT1, RT3; \
-       vshr.u64 RT7, ra, #28; \
-       veor.64 RT1, RT1, RT4; \
-       vshr.u64 RT3, re, #41; \
-       vshl.u64 RT4, re, #64 - 41; \
-       veor.64 RT1, RT1, RT5; \
+       interleave_op2(arg2); \
+       vld1.64 {RT0}, [RK]!; \
+       veor.64 RT23q, RT23q, RT45q; \
+       vshr.u64 RT4, re, #41; \
+       vshl.u64 RT5, re, #64 - 41; \
        vadd.u64 RT0, RT0, rw0; \
-       veor.64 RT1, RT1, RT3; \
-       vand.64 RT2, re, rf; \
-       veor.64 RT1, RT1, RT4; \
-       vbic.64 RT6, rg, re; \
+       veor.64 RT23q, RT23q, RT45q; \
+       vmov.64 RT7, re; \
+       veor.64 RT1, RT2, RT3; \
+       vbsl.64 RT7, rf, rg; \
        \
        vadd.u64 RT1, RT1, rh; \
-       veor.64 RT2, RT2, RT6; \
+       vshr.u64 RT2, ra, #28; \
+       vshl.u64 RT3, ra, #64 - 28; \
        vadd.u64 RT1, RT1, RT0; \
        vshr.u64 RT4, ra, #34; \
        vshl.u64 RT5, ra, #64 - 34; \
+       vadd.u64 RT1, RT1, RT7; \
        \
-       /* t7 = Sum0 (a) + Maj (a, b, c); */ \
-       vshl.u64 RT6, ra, #64 - 28; \
-       veor.64 RT7, RT7, RT4; \
-       vshr.u64 RT3, ra, #39; \
-       veor.64 RT7, RT7, RT6; \
-       vshl.u64 RT4, ra, #64 - 39; \
-       vorr.64 RT6, ra, rb; \
-       vand.64 RT0, ra, rb; \
-       veor.64 RT7, RT7, RT5; \
-       vand.64 RT6, RT6, rc; \
-       veor.64 RT7, RT7, RT3; \
-       vorr.64 RT0, RT0, RT6; \
-       veor.64 RT7, RT7, RT4; \
-       vadd.u64 RT1, RT1, RT2; \
-       vadd.u64 RT7, RT7, RT0; \
+       /* h = Sum0 (a) + Maj (a, b, c); */ \
+       veor.64 RT23q, RT23q, RT45q; \
+       vshr.u64 RT4, ra, #39; \
+       vshl.u64 RT5, ra, #64 - 39; \
+       veor.64 RT0, ra, rb; \
+       veor.64 RT23q, RT23q, RT45q; \
+       vbsl.64 RT0, rc, rb; \
        vadd.u64 rd, rd, RT1; /* d+=t1; */ \
-       vadd.u64 rh, RT7, RT1; /* h=t7+t1; */
+       veor.64 rh, RT2, RT3; \
+       \
+       /* t1 = g + Sum1 (d) + Ch (d, e, f) + k[t] + w[t]; */ \
+       vshr.u64 RT2, rd, #14; \
+       vshl.u64 RT3, rd, #64 - 14; \
+       vadd.u64 rh, rh, RT0; \
+       vshr.u64 RT4, rd, #18; \
+       vshl.u64 RT5, rd, #64 - 18; \
+       vadd.u64 rh, rh, RT1; /* h+=t1; */ \
+       vld1.64 {RT0}, [RK]!; \
+       veor.64 RT23q, RT23q, RT45q; \
+       vshr.u64 RT4, rd, #41; \
+       vshl.u64 RT5, rd, #64 - 41; \
+       vadd.u64 RT0, RT0, rw1; \
+       veor.64 RT23q, RT23q, RT45q; \
+       vmov.64 RT7, rd; \
+       veor.64 RT1, RT2, RT3; \
+       vbsl.64 RT7, re, rf; \
+       \
+       vadd.u64 RT1, RT1, rg; \
+       vshr.u64 RT2, rh, #28; \
+       vshl.u64 RT3, rh, #64 - 28; \
+       vadd.u64 RT1, RT1, RT0; \
+       vshr.u64 RT4, rh, #34; \
+       vshl.u64 RT5, rh, #64 - 34; \
+       vadd.u64 RT1, RT1, RT7; \
+       \
+       /* g = Sum0 (h) + Maj (h, a, b); */ \
+       veor.64 RT23q, RT23q, RT45q; \
+       vshr.u64 RT4, rh, #39; \
+       vshl.u64 RT5, rh, #64 - 39; \
+       veor.64 RT0, rh, ra; \
+       veor.64 RT23q, RT23q, RT45q; \
+       vbsl.64 RT0, rb, ra; \
+       vadd.u64 rc, rc, RT1; /* c+=t1; */ \
+       veor.64 rg, RT2, RT3;
+#define vadd_rg_RT0(rg) \
+       vadd.u64 rg, rg, RT0;
+#define vadd_rg_RT1(rg) \
+       vadd.u64 rg, rg, RT1; /* g+=t1; */
 
 .align 3
 .globl _gcry_sha512_transform_armv7_neon
@@ -207,8 +288,11 @@ _gcry_sha512_transform_armv7_neon:
         *      %r0: SHA512_CONTEXT
         *      %r1: data
         *      %r2: u64 k[] constants
+        *      %r3: nblks
         */
-       mov %r3, #0;
+       push {%lr};
+
+       mov %lr, #0;
 
        /* Load context to d0-d7 */
        vld1.64 {RA-RD}, [%r0]!;
@@ -220,7 +304,7 @@ _gcry_sha512_transform_armv7_neon:
        vld1.64 {RW0-RW3}, [%r1]!;
        vld1.64 {RW4-RW7}, [%r1]!;
        vld1.64 {RW8-RW11}, [%r1]!;
-       vld1.64 {RW12-RW15}, [%r1];
+       vld1.64 {RW12-RW15}, [%r1]!;
 #ifdef __ARMEL__
        /* byteswap */
        vrev64.8 RW01q, RW01q;
@@ -237,46 +321,95 @@ _gcry_sha512_transform_armv7_neon:
        vpush {RT0-RT7};
 
 .Loop:
-       add %r3, #16;
-       round_0_63(RA, RB, RC, RD, RE, RF, RG, RH, RW0, RW14, RW9, RW1);
-       cmp %r3, #64;
-       round_0_63(RH, RA, RB, RC, RD, RE, RF, RG, RW1, RW15, RW10, RW2);
-       round_0_63(RG, RH, RA, RB, RC, RD, RE, RF, RW2, RW0, RW11, RW3);
-       round_0_63(RF, RG, RH, RA, RB, RC, RD, RE, RW3, RW1, RW12, RW4);
-       round_0_63(RE, RF, RG, RH, RA, RB, RC, RD, RW4, RW2, RW13, RW5);
-       round_0_63(RD, RE, RF, RG, RH, RA, RB, RC, RW5, RW3, RW14, RW6);
-       round_0_63(RC, RD, RE, RF, RG, RH, RA, RB, RW6, RW4, RW15, RW7);
-       round_0_63(RB, RC, RD, RE, RF, RG, RH, RA, RW7, RW5, RW0, RW8);
-       round_0_63(RA, RB, RC, RD, RE, RF, RG, RH, RW8, RW6, RW1, RW9);
-       round_0_63(RH, RA, RB, RC, RD, RE, RF, RG, RW9, RW7, RW2, RW10);
-       round_0_63(RG, RH, RA, RB, RC, RD, RE, RF, RW10, RW8, RW3, RW11);
-       round_0_63(RF, RG, RH, RA, RB, RC, RD, RE, RW11, RW9, RW4, RW12);
-       round_0_63(RE, RF, RG, RH, RA, RB, RC, RD, RW12, RW10, RW5, RW13);
-       round_0_63(RD, RE, RF, RG, RH, RA, RB, RC, RW13, RW11, RW6, RW14);
-       round_0_63(RC, RD, RE, RF, RG, RH, RA, RB, RW14, RW12, RW7, RW15);
-       round_0_63(RB, RC, RD, RE, RF, RG, RH, RA, RW15, RW13, RW8, RW0);
-       bne .Loop;
-
-       round_64_79(RA, RB, RC, RD, RE, RF, RG, RH, RW0);
-       round_64_79(RH, RA, RB, RC, RD, RE, RF, RG, RW1);
-       round_64_79(RG, RH, RA, RB, RC, RD, RE, RF, RW2);
-       round_64_79(RF, RG, RH, RA, RB, RC, RD, RE, RW3);
-       round_64_79(RE, RF, RG, RH, RA, RB, RC, RD, RW4);
-       round_64_79(RD, RE, RF, RG, RH, RA, RB, RC, RW5);
-       round_64_79(RC, RD, RE, RF, RG, RH, RA, RB, RW6);
-       round_64_79(RB, RC, RD, RE, RF, RG, RH, RA, RW7);
-       round_64_79(RA, RB, RC, RD, RE, RF, RG, RH, RW8);
-       round_64_79(RH, RA, RB, RC, RD, RE, RF, RG, RW9);
-       round_64_79(RG, RH, RA, RB, RC, RD, RE, RF, RW10);
-       round_64_79(RF, RG, RH, RA, RB, RC, RD, RE, RW11);
-       round_64_79(RE, RF, RG, RH, RA, RB, RC, RD, RW12);
-       round_64_79(RD, RE, RF, RG, RH, RA, RB, RC, RW13);
-       round_64_79(RC, RD, RE, RF, RG, RH, RA, RB, RW14);
-       round_64_79(RB, RC, RD, RE, RF, RG, RH, RA, RW15);
+       rounds2_0_63(RA, RB, RC, RD, RE, RF, RG, RH, RW0, RW1, RW01q, RW2, RW23q, RW1415q, RW9, RW10, dummy, _);
+       b .Lenter_rounds;
+
+.Loop_rounds:
+       rounds2_0_63(RA, RB, RC, RD, RE, RF, RG, RH, RW0, RW1, RW01q, RW2, RW23q, RW1415q, RW9, RW10, vadd_RT01q, RW1415q);
+.Lenter_rounds:
+       rounds2_0_63(RG, RH, RA, RB, RC, RD, RE, RF, RW2, RW3, RW23q, RW4, RW45q, RW01q, RW11, RW12, vadd_RT01q, RW01q);
+       rounds2_0_63(RE, RF, RG, RH, RA, RB, RC, RD, RW4, RW5, RW45q, RW6, RW67q, RW23q, RW13, RW14, vadd_RT01q, RW23q);
+       rounds2_0_63(RC, RD, RE, RF, RG, RH, RA, RB, RW6, RW7, RW67q, RW8, RW89q, RW45q, RW15, RW0, vadd_RT01q, RW45q);
+       rounds2_0_63(RA, RB, RC, RD, RE, RF, RG, RH, RW8, RW9, RW89q, RW10, RW1011q, RW67q, RW1, RW2, vadd_RT01q, RW67q);
+       rounds2_0_63(RG, RH, RA, RB, RC, RD, RE, RF, RW10, RW11, RW1011q, RW12, RW1213q, RW89q, RW3, RW4, vadd_RT01q, RW89q);
+       add %lr, #16;
+       rounds2_0_63(RE, RF, RG, RH, RA, RB, RC, RD, RW12, RW13, RW1213q, RW14, RW1415q, RW1011q, RW5, RW6, vadd_RT01q, RW1011q);
+       cmp %lr, #64;
+       rounds2_0_63(RC, RD, RE, RF, RG, RH, RA, RB, RW14, RW15, RW1415q, RW0, RW01q, RW1213q, RW7, RW8, vadd_RT01q, RW1213q);
+       bne .Loop_rounds;
+
+       subs %r3, #1;
+
+       rounds2_64_79(RA, RB, RC, RD, RE, RF, RG, RH, RW0, RW1, vadd_RT01q, RW1415q, dummy, _);
+       rounds2_64_79(RG, RH, RA, RB, RC, RD, RE, RF, RW2, RW3, vadd_rg_RT0, RG, vadd_rg_RT1, RG);
+       beq .Lhandle_tail;
+       vld1.64 {RW0-RW3}, [%r1]!;
+       rounds2_64_79(RE, RF, RG, RH, RA, RB, RC, RD, RW4, RW5, vadd_rg_RT0, RE, vadd_rg_RT1, RE);
+       rounds2_64_79(RC, RD, RE, RF, RG, RH, RA, RB, RW6, RW7, vadd_rg_RT0, RC, vadd_rg_RT1, RC);
+#ifdef __ARMEL__
+       vrev64.8 RW01q, RW01q;
+       vrev64.8 RW23q, RW23q;
+#endif
+       vld1.64 {RW4-RW7}, [%r1]!;
+       rounds2_64_79(RA, RB, RC, RD, RE, RF, RG, RH, RW8, RW9, vadd_rg_RT0, RA, vadd_rg_RT1, RA);
+       rounds2_64_79(RG, RH, RA, RB, RC, RD, RE, RF, RW10, RW11, vadd_rg_RT0, RG, vadd_rg_RT1, RG);
+#ifdef __ARMEL__
+       vrev64.8 RW45q, RW45q;
+       vrev64.8 RW67q, RW67q;
+#endif
+       vld1.64 {RW8-RW11}, [%r1]!;
+       rounds2_64_79(RE, RF, RG, RH, RA, RB, RC, RD, RW12, RW13, vadd_rg_RT0, RE, vadd_rg_RT1, RE);
+       rounds2_64_79(RC, RD, RE, RF, RG, RH, RA, RB, RW14, RW15, vadd_rg_RT0, RC, vadd_rg_RT1, RC);
+#ifdef __ARMEL__
+       vrev64.8 RW89q, RW89q;
+       vrev64.8 RW1011q, RW1011q;
+#endif
+       vld1.64 {RW12-RW15}, [%r1]!;
+       vadd_rg_RT0(RA);
+       vadd_rg_RT1(RA);
+
+       /* Load context */
+       vld1.64 {RT0-RT3}, [%r0]!;
+       vld1.64 {RT4-RT7}, [%r0];
+       sub %r0, #(4*8);
+
+#ifdef __ARMEL__
+       vrev64.8 RW1213q, RW1213q;
+       vrev64.8 RW1415q, RW1415q;
+#endif
+
+       vadd.u64 RA, RT0;
+       vadd.u64 RB, RT1;
+       vadd.u64 RC, RT2;
+       vadd.u64 RD, RT3;
+       vadd.u64 RE, RT4;
+       vadd.u64 RF, RT5;
+       vadd.u64 RG, RT6;
+       vadd.u64 RH, RT7;
+
+       /* Store the first half of context */
+       vst1.64 {RA-RD}, [%r0]!;
+       sub RK, $(8*80);
+       vst1.64 {RE-RH}, [%r0]; /* Store the last half of context */
+       mov %lr, #0;
+       sub %r0, #(4*8);
+
+       b .Loop;
+.ltorg
+
+.Lhandle_tail:
+       rounds2_64_79(RE, RF, RG, RH, RA, RB, RC, RD, RW4, RW5, vadd_rg_RT0, RE, vadd_rg_RT1, RE);
+       rounds2_64_79(RC, RD, RE, RF, RG, RH, RA, RB, RW6, RW7, vadd_rg_RT0, RC, vadd_rg_RT1, RC);
+       rounds2_64_79(RA, RB, RC, RD, RE, RF, RG, RH, RW8, RW9, vadd_rg_RT0, RA, vadd_rg_RT1, RA);
+       rounds2_64_79(RG, RH, RA, RB, RC, RD, RE, RF, RW10, RW11, vadd_rg_RT0, RG, vadd_rg_RT1, RG);
+       rounds2_64_79(RE, RF, RG, RH, RA, RB, RC, RD, RW12, RW13, vadd_rg_RT0, RE, vadd_rg_RT1, RE);
+       rounds2_64_79(RC, RD, RE, RF, RG, RH, RA, RB, RW14, RW15, vadd_rg_RT0, RC, vadd_rg_RT1, RC);
 
        /* Load context to d16-d23 */
        vld1.64 {RW0-RW3}, [%r0]!;
+       vadd_rg_RT0(RA);
        vld1.64 {RW4-RW7}, [%r0];
+       vadd_rg_RT1(RA);
        sub %r0, #(4*8);
 
        vadd.u64 RA, RW0;
@@ -310,7 +443,7 @@ _gcry_sha512_transform_armv7_neon:
        veor.u64 %q2, %q2;
        veor.u64 %q3, %q3;
 
-       bx %lr;
+       pop {%pc};
 .size _gcry_sha512_transform_armv7_neon,.-_gcry_sha512_transform_armv7_neon;
 
 #endif
index 3449b87..699c271 100644 (file)
@@ -41,7 +41,8 @@
 
 #ifdef __x86_64
 #include <config.h>
-#if defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && \
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
     defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
     defined(HAVE_GCC_INLINE_ASM_AVX) && defined(USE_SHA512)
 
 #  define ADD_RIP
 #endif
 
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
+
 .intel_syntax noprefix
 
 .text
@@ -259,7 +266,7 @@ frame_size = ((frame_GPRSAVE) + (frame_GPRSAVE_size))
 ; L is the message length in SHA512 blocks
 */
 .globl _gcry_sha512_transform_amd64_avx
-.type _gcry_sha512_transform_amd64_avx,@function;
+ELF(.type _gcry_sha512_transform_amd64_avx,@function;)
 .align 16
 _gcry_sha512_transform_amd64_avx:
        xor eax, eax
index d6301f3..02f95af 100644 (file)
@@ -43,7 +43,8 @@
 
 #ifdef __x86_64
 #include <config.h>
-#if defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && \
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
     defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
     defined(HAVE_GCC_INLINE_ASM_AVX2) && defined(HAVE_GCC_INLINE_ASM_BMI2) && \
     defined(USE_SHA512)
 #  define ADD_RIP
 #endif
 
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
+
 .intel_syntax noprefix
 
 .text
@@ -596,7 +603,7 @@ rotate_Ys
 ; L is the message length in SHA512 blocks
 */
 .globl _gcry_sha512_transform_amd64_avx2
-.type _gcry_sha512_transform_amd64_avx2,@function;
+ELF(.type _gcry_sha512_transform_amd64_avx2,@function;)
 .align 16
 _gcry_sha512_transform_amd64_avx2:
        xor eax, eax
index 4c80baa..c721bcf 100644 (file)
@@ -44,7 +44,8 @@
 
 #ifdef __x86_64
 #include <config.h>
-#if defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && \
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
     defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
     defined(HAVE_GCC_INLINE_ASM_SSSE3) && defined(USE_SHA512)
 
 #  define ADD_RIP
 #endif
 
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
+
 .intel_syntax noprefix
 
 .text
@@ -261,7 +268,7 @@ frame_size = ((frame_GPRSAVE) + (frame_GPRSAVE_size))
 ; L is the message length in SHA512 blocks.
 */
 .globl _gcry_sha512_transform_amd64_ssse3
-.type _gcry_sha512_transform_amd64_ssse3,@function;
+ELF(.type _gcry_sha512_transform_amd64_ssse3,@function;)
 .align 16
 _gcry_sha512_transform_amd64_ssse3:
        xor eax, eax
index 6f729cc..5b25965 100644 (file)
 #endif /*ENABLE_NEON_SUPPORT*/
 
 
+/* USE_ARM_ASM indicates whether to enable ARM assembly code. */
+#undef USE_ARM_ASM
+#if defined(__ARMEL__) && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS)
+# define USE_ARM_ASM 1
+#endif
+
+
 /* USE_SSSE3 indicates whether to compile with Intel SSSE3 code. */
 #undef USE_SSSE3
-#if defined(__x86_64__) && defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && \
-    defined(HAVE_GCC_INLINE_ASM_SSSE3) && \
-    defined(HAVE_INTEL_SYNTAX_PLATFORM_AS)
+#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_SSSE3) && \
+    defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
+    (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
 # define USE_SSSE3 1
 #endif
 
 
 /* USE_AVX indicates whether to compile with Intel AVX code. */
 #undef USE_AVX
-#if defined(__x86_64__) && defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && \
-    defined(HAVE_GCC_INLINE_ASM_AVX) && \
-    defined(HAVE_INTEL_SYNTAX_PLATFORM_AS)
+#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX) && \
+    defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
+    (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
 # define USE_AVX 1
 #endif
 
 
 /* USE_AVX2 indicates whether to compile with Intel AVX2/rorx code. */
 #undef USE_AVX2
-#if defined(__x86_64__) && defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && \
-    defined(HAVE_GCC_INLINE_ASM_AVX2) && defined(HAVE_GCC_INLINE_ASM_BMI2) && \
-    defined(HAVE_INTEL_SYNTAX_PLATFORM_AS)
+#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX2) && \
+    defined(HAVE_GCC_INLINE_ASM_BMI2) && \
+    defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
+    (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
 # define USE_AVX2 1
 #endif
 
@@ -117,7 +128,7 @@ typedef struct
 } SHA512_CONTEXT;
 
 static unsigned int
-transform (void *context, const unsigned char *data);
+transform (void *context, const unsigned char *data, size_t nblks);
 
 static void
 sha512_init (void *context, unsigned int flags)
@@ -150,7 +161,7 @@ sha512_init (void *context, unsigned int flags)
   ctx->use_ssse3 = (features & HWF_INTEL_SSSE3) != 0;
 #endif
 #ifdef USE_AVX
-  ctx->use_avx = (features & HWF_INTEL_AVX) && (features & HWF_INTEL_CPU);
+  ctx->use_avx = (features & HWF_INTEL_AVX) && (features & HWF_INTEL_FAST_SHLD);
 #endif
 #ifdef USE_AVX2
   ctx->use_avx2 = (features & HWF_INTEL_AVX2) && (features & HWF_INTEL_BMI2);
@@ -190,7 +201,7 @@ sha384_init (void *context, unsigned int flags)
   ctx->use_ssse3 = (features & HWF_INTEL_SSSE3) != 0;
 #endif
 #ifdef USE_AVX
-  ctx->use_avx = (features & HWF_INTEL_AVX) && (features & HWF_INTEL_CPU);
+  ctx->use_avx = (features & HWF_INTEL_AVX) && (features & HWF_INTEL_FAST_SHLD);
 #endif
 #ifdef USE_AVX2
   ctx->use_avx2 = (features & HWF_INTEL_AVX2) && (features & HWF_INTEL_BMI2);
@@ -200,36 +211,6 @@ sha384_init (void *context, unsigned int flags)
 }
 
 
-static inline u64
-ROTR (u64 x, u64 n)
-{
-  return ((x >> n) | (x << (64 - n)));
-}
-
-static inline u64
-Ch (u64 x, u64 y, u64 z)
-{
-  return ((x & y) ^ ( ~x & z));
-}
-
-static inline u64
-Maj (u64 x, u64 y, u64 z)
-{
-  return ((x & y) ^ (x & z) ^ (y & z));
-}
-
-static inline u64
-Sum0 (u64 x)
-{
-  return (ROTR (x, 28) ^ ROTR (x, 34) ^ ROTR (x, 39));
-}
-
-static inline u64
-Sum1 (u64 x)
-{
-  return (ROTR (x, 14) ^ ROTR (x, 18) ^ ROTR (x, 41));
-}
-
 static const u64 k[] =
   {
     U64_C(0x428a2f98d728ae22), U64_C(0x7137449123ef65cd),
@@ -274,11 +255,43 @@ static const u64 k[] =
     U64_C(0x5fcb6fab3ad6faec), U64_C(0x6c44198c4a475817)
   };
 
+#ifndef USE_ARM_ASM
+
+static inline u64
+ROTR (u64 x, u64 n)
+{
+  return ((x >> n) | (x << (64 - n)));
+}
+
+static inline u64
+Ch (u64 x, u64 y, u64 z)
+{
+  return ((x & y) ^ ( ~x & z));
+}
+
+static inline u64
+Maj (u64 x, u64 y, u64 z)
+{
+  return ((x & y) ^ (x & z) ^ (y & z));
+}
+
+static inline u64
+Sum0 (u64 x)
+{
+  return (ROTR (x, 28) ^ ROTR (x, 34) ^ ROTR (x, 39));
+}
+
+static inline u64
+Sum1 (u64 x)
+{
+  return (ROTR (x, 14) ^ ROTR (x, 18) ^ ROTR (x, 41));
+}
+
 /****************
  * Transform the message W which consists of 16 64-bit-words
  */
 static unsigned int
-__transform (SHA512_STATE *hd, const unsigned char *data)
+transform_blk (SHA512_STATE *hd, const unsigned char *data)
 {
   u64 a, b, c, d, e, f, g, h;
   u64 w[16];
@@ -300,7 +313,6 @@ __transform (SHA512_STATE *hd, const unsigned char *data)
 #define S0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7))
 #define S1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
 
-
   for (t = 0; t < 80 - 16; )
     {
       u64 t1, t2;
@@ -541,57 +553,82 @@ __transform (SHA512_STATE *hd, const unsigned char *data)
   return /* burn_stack */ (8 + 16) * sizeof(u64) + sizeof(u32) +
                           3 * sizeof(void*);
 }
+#endif /*!USE_ARM_ASM*/
+
+/* AMD64 assembly implementations use SystemV ABI, ABI conversion and additional
+ * stack to store XMM6-XMM15 needed on Win64. */
+#undef ASM_FUNC_ABI
+#undef ASM_EXTRA_STACK
+#if defined(USE_SSSE3) || defined(USE_AVX) || defined(USE_AVX2)
+# ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+#  define ASM_FUNC_ABI __attribute__((sysv_abi))
+#  define ASM_EXTRA_STACK (10 * 16)
+# else
+#  define ASM_FUNC_ABI
+#  define ASM_EXTRA_STACK 0
+# endif
+#endif
 
 
 #ifdef USE_ARM_NEON_ASM
 void _gcry_sha512_transform_armv7_neon (SHA512_STATE *hd,
                                        const unsigned char *data,
-                                       const u64 k[]);
+                                       const u64 k[], size_t num_blks);
+#endif
+
+#ifdef USE_ARM_ASM
+unsigned int _gcry_sha512_transform_arm (SHA512_STATE *hd,
+                                        const unsigned char *data,
+                                        const u64 k[], size_t num_blks);
 #endif
 
 #ifdef USE_SSSE3
 unsigned int _gcry_sha512_transform_amd64_ssse3(const void *input_data,
-                                               void *state, size_t num_blks);
+                                                void *state,
+                                                size_t num_blks) ASM_FUNC_ABI;
 #endif
 
 #ifdef USE_AVX
 unsigned int _gcry_sha512_transform_amd64_avx(const void *input_data,
-                                             void *state, size_t num_blks);
+                                              void *state,
+                                              size_t num_blks) ASM_FUNC_ABI;
 #endif
 
 #ifdef USE_AVX2
 unsigned int _gcry_sha512_transform_amd64_avx2(const void *input_data,
-                                              void *state, size_t num_blks);
+                                               void *state,
+                                               size_t num_blks) ASM_FUNC_ABI;
 #endif
 
 
 static unsigned int
-transform (void *context, const unsigned char *data)
+transform (void *context, const unsigned char *data, size_t nblks)
 {
   SHA512_CONTEXT *ctx = context;
+  unsigned int burn;
 
 #ifdef USE_AVX2
   if (ctx->use_avx2)
-    return _gcry_sha512_transform_amd64_avx2 (data, &ctx->state, 1)
-           + 4 * sizeof(void*);
+    return _gcry_sha512_transform_amd64_avx2 (data, &ctx->state, nblks)
+           + 4 * sizeof(void*) + ASM_EXTRA_STACK;
 #endif
 
 #ifdef USE_AVX
   if (ctx->use_avx)
-    return _gcry_sha512_transform_amd64_avx (data, &ctx->state, 1)
-           + 4 * sizeof(void*);
+    return _gcry_sha512_transform_amd64_avx (data, &ctx->state, nblks)
+           + 4 * sizeof(void*) + ASM_EXTRA_STACK;
 #endif
 
 #ifdef USE_SSSE3
   if (ctx->use_ssse3)
-    return _gcry_sha512_transform_amd64_ssse3 (data, &ctx->state, 1)
-           + 4 * sizeof(void*);
+    return _gcry_sha512_transform_amd64_ssse3 (data, &ctx->state, nblks)
+           + 4 * sizeof(void*) + ASM_EXTRA_STACK;
 #endif
 
 #ifdef USE_ARM_NEON_ASM
   if (ctx->use_neon)
     {
-      _gcry_sha512_transform_armv7_neon (&ctx->state, data, k);
+      _gcry_sha512_transform_armv7_neon (&ctx->state, data, k, nblks);
 
       /* _gcry_sha512_transform_armv7_neon does not store sensitive data
        * to stack.  */
@@ -599,7 +636,26 @@ transform (void *context, const unsigned char *data)
     }
 #endif
 
-  return __transform (&ctx->state, data) + 3 * sizeof(void*);
+#ifdef USE_ARM_ASM
+  burn = _gcry_sha512_transform_arm (&ctx->state, data, k, nblks);
+#else
+  do
+    {
+      burn = transform_blk (&ctx->state, data) + 3 * sizeof(void*);
+      data += 128;
+    }
+  while (--nblks);
+
+#ifdef ASM_EXTRA_STACK
+  /* 'transform_blk' is typically inlined and XMM6-XMM15 are stored at
+   *  the prologue of this function. Therefore need to add ASM_EXTRA_STACK to
+   *  here too.
+   */
+  burn += ASM_EXTRA_STACK;
+#endif
+#endif
+
+  return burn;
 }
 
 
@@ -657,11 +713,11 @@ sha512_final (void *context)
   /* append the 128 bit count */
   buf_put_be64(hd->bctx.buf + 112, msb);
   buf_put_be64(hd->bctx.buf + 120, lsb);
-  stack_burn_depth = transform (hd, hd->bctx.buf);
+  stack_burn_depth = transform (hd, hd->bctx.buf, 1);
   _gcry_burn_stack (stack_burn_depth);
 
   p = hd->bctx.buf;
-#define X(a) do { *(u64*)p = be_bswap64(hd->state.h##a) ; p += 8; } while (0)
+#define X(a) do { buf_put_be64(p, hd->state.h##a); p += 8; } while (0)
   X (0);
   X (1);
   X (2);
@@ -839,7 +895,7 @@ gcry_md_spec_t _gcry_digest_spec_sha512 =
   {
     GCRY_MD_SHA512, {0, 1},
     "SHA512", sha512_asn, DIM (sha512_asn), oid_spec_sha512, 64,
-    sha512_init, _gcry_md_block_write, sha512_final, sha512_read,
+    sha512_init, _gcry_md_block_write, sha512_final, sha512_read, NULL,
     sizeof (SHA512_CONTEXT),
     run_selftests
   };
@@ -865,7 +921,7 @@ gcry_md_spec_t _gcry_digest_spec_sha384 =
   {
     GCRY_MD_SHA384, {0, 1},
     "SHA384", sha384_asn, DIM (sha384_asn), oid_spec_sha384, 48,
-    sha384_init, _gcry_md_block_write, sha512_final, sha512_read,
+    sha384_init, _gcry_md_block_write, sha512_final, sha512_read, NULL,
     sizeof (SHA512_CONTEXT),
     run_selftests
   };
index 297b64a..7f38e6f 100644 (file)
@@ -1080,7 +1080,7 @@ static const u64 stribog_table[8][256] =
     U64_C(0x72d14d3493b2e388), U64_C(0xd6a30f258c153427) },
 };
 
-static const u64 C16[13][16] =
+static const u64 C16[12][8] =
 {
   { U64_C(0xdd806559f2a64507), U64_C(0x05767436cc744d23),
     U64_C(0xa2422a08a460d315), U64_C(0x4b7ce09192676901),
@@ -1194,7 +1194,7 @@ static inline void g (u64 *h, u64 *m, u64 *N)
 
 
 static unsigned int
-transform64 (void *context, const unsigned char *inbuf_arg);
+transform (void *context, const unsigned char *inbuf_arg, size_t datalen);
 
 
 static void
@@ -1207,7 +1207,7 @@ stribog_init_512 (void *context, unsigned int flags)
   memset (hd, 0, sizeof (*hd));
 
   hd->bctx.blocksize = 64;
-  hd->bctx.bwrite = transform64;
+  hd->bctx.bwrite = transform;
 }
 
 static void
@@ -1220,7 +1220,7 @@ stribog_init_256 (void *context, unsigned int flags)
 }
 
 static void
-transform (STRIBOG_CONTEXT *hd, const unsigned char *data, unsigned count)
+transform_bits (STRIBOG_CONTEXT *hd, const unsigned char *data, unsigned count)
 {
   u64 M[8];
   u64 l;
@@ -1251,15 +1251,30 @@ transform (STRIBOG_CONTEXT *hd, const unsigned char *data, unsigned count)
 }
 
 static unsigned int
-transform64 (void *context, const unsigned char *inbuf_arg)
+transform_blk (void *context, const unsigned char *inbuf_arg)
 {
   STRIBOG_CONTEXT *hd = context;
 
-  transform (hd, inbuf_arg, 64 * 8);
+  transform_bits (hd, inbuf_arg, 64 * 8);
 
   return /* burn_stack */ 768;
 }
 
+static unsigned int
+transform ( void *c, const unsigned char *data, size_t nblks )
+{
+  unsigned int burn;
+
+  do
+    {
+      burn = transform_blk (c, data);
+      data += 64;
+    }
+  while (--nblks);
+
+  return burn;
+}
+
 /*
    The routine finally terminates the computation and returns the
    digest.  The handle is prepared for a new cycle, but adding bytes
@@ -1279,7 +1294,7 @@ stribog_final (void *context)
   hd->bctx.buf[i++] = 1;
   while (i < 64)
     hd->bctx.buf[i++] = 0;
-  transform (hd, hd->bctx.buf, hd->bctx.count * 8);
+  transform_bits (hd, hd->bctx.buf, hd->bctx.count * 8);
 
   g (hd->h, hd->N, Z);
   g (hd->h, hd->Sigma, Z);
@@ -1311,6 +1326,7 @@ gcry_md_spec_t _gcry_digest_spec_stribog_256 =
     GCRY_MD_STRIBOG256, {0, 0},
     "STRIBOG256", NULL, 0, NULL, 32,
     stribog_init_256, _gcry_md_block_write, stribog_final, stribog_read_256,
+    NULL,
     sizeof (STRIBOG_CONTEXT)
   };
 
@@ -1319,5 +1335,6 @@ gcry_md_spec_t _gcry_digest_spec_stribog_512 =
     GCRY_MD_STRIBOG512, {0, 0},
     "STRIBOG512", NULL, 0, NULL, 64,
     stribog_init_512, _gcry_md_block_write, stribog_final, stribog_read_512,
+    NULL,
     sizeof (STRIBOG_CONTEXT)
   };
index 414dcc4..b60ec16 100644 (file)
@@ -31,9 +31,6 @@
 #include "bithelp.h"
 #include "bufhelp.h"
 
-/* We really need a 64 bit type for this code.  */
-#ifdef HAVE_U64_TYPEDEF
-
 typedef struct
 {
   gcry_md_block_ctx_t bctx;
@@ -590,7 +587,7 @@ static u64 sbox4[256] = {
 };
 
 static unsigned int
-transform ( void *ctx, const unsigned char *data );
+transform ( void *ctx, const unsigned char *data, size_t nblks );
 
 static void
 do_init (void *context, int variant)
@@ -633,75 +630,51 @@ tiger2_init (void *context, unsigned int flags)
   do_init (context, 2);
 }
 
-static void
-tiger_round( u64 *ra, u64 *rb, u64 *rc, u64 x, int mul )
-{
-  u64 a = *ra;
-  u64 b = *rb;
-  u64 c = *rc;
-
-  c ^= x;
-  a -= (  sbox1[  c        & 0xff ] ^ sbox2[ (c >> 16) & 0xff ]
-        ^ sbox3[ (c >> 32) & 0xff ] ^ sbox4[ (c >> 48) & 0xff ]);
-  b += (  sbox4[ (c >>  8) & 0xff ] ^ sbox3[ (c >> 24) & 0xff ]
-        ^ sbox2[ (c >> 40) & 0xff ] ^ sbox1[ (c >> 56) & 0xff ]);
-  b *= mul;
-
-  *ra = a;
-  *rb = b;
-  *rc = c;
-}
-
-
-static void
-pass( u64 *ra, u64 *rb, u64 *rc, u64 *x, int mul )
-{
-  u64 a = *ra;
-  u64 b = *rb;
-  u64 c = *rc;
-
-  tiger_round( &a, &b, &c, x[0], mul );
-  tiger_round( &b, &c, &a, x[1], mul );
-  tiger_round( &c, &a, &b, x[2], mul );
-  tiger_round( &a, &b, &c, x[3], mul );
-  tiger_round( &b, &c, &a, x[4], mul );
-  tiger_round( &c, &a, &b, x[5], mul );
-  tiger_round( &a, &b, &c, x[6], mul );
-  tiger_round( &b, &c, &a, x[7], mul );
-
-  *ra = a;
-  *rb = b;
-  *rc = c;
-}
-
 
-static void
-key_schedule( u64 *x )
-{
-  x[0] -= x[7] ^ 0xa5a5a5a5a5a5a5a5LL;
-  x[1] ^= x[0];
-  x[2] += x[1];
-  x[3] -= x[2] ^ ((~x[1]) << 19 );
-  x[4] ^= x[3];
-  x[5] += x[4];
-  x[6] -= x[5] ^ ((~x[4]) >> 23 );
-  x[7] ^= x[6];
-  x[0] += x[7];
-  x[1] -= x[0] ^ ((~x[7]) << 19 );
-  x[2] ^= x[1];
-  x[3] += x[2];
-  x[4] -= x[3] ^ ((~x[2]) >> 23 );
-  x[5] ^= x[4];
-  x[6] += x[5];
-  x[7] -= x[6] ^ 0x0123456789abcdefLL;
-}
+#define tiger_round(xa, xb, xc, xx, xmul) { \
+  xc ^= xx; \
+  xa -= (  sbox1[  (xc)        & 0xff ] ^ sbox2[ ((xc) >> 16) & 0xff ] \
+         ^ sbox3[ ((xc) >> 32) & 0xff ] ^ sbox4[ ((xc) >> 48) & 0xff ]); \
+  xb += (  sbox4[ ((xc) >>  8) & 0xff ] ^ sbox3[ ((xc) >> 24) & 0xff ] \
+         ^ sbox2[ ((xc) >> 40) & 0xff ] ^ sbox1[ ((xc) >> 56) & 0xff ]); \
+  xb *= xmul; }
+
+
+#define pass(ya, yb, yc, yx, ymul) { \
+  tiger_round( ya, yb, yc, yx[0], ymul ); \
+  tiger_round( yb, yc, ya, yx[1], ymul ); \
+  tiger_round( yc, ya, yb, yx[2], ymul ); \
+  tiger_round( ya, yb, yc, yx[3], ymul ); \
+  tiger_round( yb, yc, ya, yx[4], ymul ); \
+  tiger_round( yc, ya, yb, yx[5], ymul ); \
+  tiger_round( ya, yb, yc, yx[6], ymul ); \
+  tiger_round( yb, yc, ya, yx[7], ymul ); }
+
+
+#define key_schedule(x) { \
+  x[0] -= x[7] ^ 0xa5a5a5a5a5a5a5a5LL; \
+  x[1] ^= x[0]; \
+  x[2] += x[1]; \
+  x[3] -= x[2] ^ ((~x[1]) << 19 ); \
+  x[4] ^= x[3]; \
+  x[5] += x[4]; \
+  x[6] -= x[5] ^ ((~x[4]) >> 23 ); \
+  x[7] ^= x[6]; \
+  x[0] += x[7]; \
+  x[1] -= x[0] ^ ((~x[7]) << 19 ); \
+  x[2] ^= x[1]; \
+  x[3] += x[2]; \
+  x[4] -= x[3] ^ ((~x[2]) >> 23 ); \
+  x[5] ^= x[4]; \
+  x[6] += x[5]; \
+  x[7] -= x[6] ^ 0x0123456789abcdefLL; }
 
 
 /****************
  * Transform the message DATA which consists of 512 bytes (8 words)
  */
 static unsigned int
-transform ( void *ctx, const unsigned char *data )
+transform_blk ( void *ctx, const unsigned char *data )
 {
   TIGER_CONTEXT *hd = ctx;
   u64 a,b,c,aa,bb,cc;
@@ -716,11 +689,11 @@ transform ( void *ctx, const unsigned char *data )
   b = bb = hd->b;
   c = cc = hd->c;
 
-  pass( &a, &b, &c, x, 5);
+  pass( a, b, c, x, 5);
   key_schedule( x );
-  pass( &c, &a, &b, x, 7);
+  pass( c, a, b, x, 7);
   key_schedule( x );
-  pass( &b, &c, &a, x, 9);
+  pass( b, c, a, x, 9);
 
   /* feedforward */
   a ^= aa;
@@ -735,6 +708,22 @@ transform ( void *ctx, const unsigned char *data )
 }
 
 
+static unsigned int
+transform ( void *c, const unsigned char *data, size_t nblks )
+{
+  unsigned int burn;
+
+  do
+    {
+      burn = transform_blk (c, data);
+      data += 64;
+    }
+  while (--nblks);
+
+  return burn;
+}
+
+
 
 /* The routine terminates the computation
  */
@@ -785,12 +774,12 @@ tiger_final( void *context )
   /* append the 64 bit count */
   buf_put_le32(hd->bctx.buf + 56, lsb);
   buf_put_le32(hd->bctx.buf + 60, msb);
-  burn = transform( hd, hd->bctx.buf );
+  burn = transform( hd, hd->bctx.buf, 1 );
   _gcry_burn_stack (burn);
 
   p = hd->bctx.buf;
-#define X(a) do { *(u64*)p = be_bswap64(hd->a); p += 8; } while(0)
-#define Y(a) do { *(u64*)p = le_bswap64(hd->a); p += 8; } while(0)
+#define X(a) do { buf_put_be64(p, hd->a); p += 8; } while(0)
+#define Y(a) do { buf_put_le64(p, hd->a); p += 8; } while(0)
   if (hd->variant == 0)
     {
       X(a);
@@ -824,7 +813,7 @@ gcry_md_spec_t _gcry_digest_spec_tiger =
   {
     GCRY_MD_TIGER, {0, 0},
     "TIGER192", NULL, 0, NULL, 24,
-    tiger_init, _gcry_md_block_write, tiger_final, tiger_read,
+    tiger_init, _gcry_md_block_write, tiger_final, tiger_read, NULL,
     sizeof (TIGER_CONTEXT)
   };
 
@@ -847,7 +836,7 @@ gcry_md_spec_t _gcry_digest_spec_tiger1 =
   {
     GCRY_MD_TIGER1, {0, 0},
     "TIGER", asn1, DIM (asn1), oid_spec_tiger1, 24,
-    tiger1_init, _gcry_md_block_write, tiger_final, tiger_read,
+    tiger1_init, _gcry_md_block_write, tiger_final, tiger_read, NULL,
     sizeof (TIGER_CONTEXT)
   };
 
@@ -858,8 +847,6 @@ gcry_md_spec_t _gcry_digest_spec_tiger2 =
   {
     GCRY_MD_TIGER2, {0, 0},
     "TIGER2", NULL, 0, NULL, 24,
-    tiger2_init, _gcry_md_block_write, tiger_final, tiger_read,
+    tiger2_init, _gcry_md_block_write, tiger_final, tiger_read, NULL,
     sizeof (TIGER_CONTEXT)
   };
-
-#endif /* HAVE_U64_TYPEDEF */
index c923d22..aa964e0 100644 (file)
@@ -1,6 +1,6 @@
 /* twofish-amd64.S  -  AMD64 assembly implementation of Twofish cipher
  *
- * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013-2015 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
 
 #ifdef __x86_64
 #include <config.h>
-#if defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && defined(USE_TWOFISH)
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+    defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && defined(USE_TWOFISH)
+
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
 
 #ifdef __PIC__
 #  define RIP %rip
 
 .align 8
 .globl _gcry_twofish_amd64_encrypt_block
-.type   _gcry_twofish_amd64_encrypt_block,@function;
+ELF(.type   _gcry_twofish_amd64_encrypt_block,@function;)
 
 _gcry_twofish_amd64_encrypt_block:
        /* input:
@@ -205,11 +212,11 @@ _gcry_twofish_amd64_encrypt_block:
        addq $(3 * 8), %rsp;
 
        ret;
-.size _gcry_twofish_amd64_encrypt_block,.-_gcry_twofish_amd64_encrypt_block;
+ELF(.size _gcry_twofish_amd64_encrypt_block,.-_gcry_twofish_amd64_encrypt_block;)
 
 .align 8
 .globl _gcry_twofish_amd64_decrypt_block
-.type   _gcry_twofish_amd64_decrypt_block,@function;
+ELF(.type   _gcry_twofish_amd64_decrypt_block,@function;)
 
 _gcry_twofish_amd64_decrypt_block:
        /* input:
@@ -248,7 +255,7 @@ _gcry_twofish_amd64_decrypt_block:
        addq $(3 * 8), %rsp;
 
        ret;
-.size _gcry_twofish_amd64_encrypt_block,.-_gcry_twofish_amd64_encrypt_block;
+ELF(.size _gcry_twofish_amd64_encrypt_block,.-_gcry_twofish_amd64_encrypt_block;)
 
 #undef CTX
 
@@ -462,7 +469,7 @@ _gcry_twofish_amd64_decrypt_block:
        outunpack3(RAB, 2);
 
 .align 8
-.type __twofish_enc_blk3,@function;
+ELF(.type __twofish_enc_blk3,@function;)
 
 __twofish_enc_blk3:
        /* input:
@@ -485,10 +492,10 @@ __twofish_enc_blk3:
        outunpack_enc3();
 
        ret;
-.size __twofish_enc_blk3,.-__twofish_enc_blk3;
+ELF(.size __twofish_enc_blk3,.-__twofish_enc_blk3;)
 
 .align 8
-.type  __twofish_dec_blk3,@function;
+ELF(.type  __twofish_dec_blk3,@function;)
 
 __twofish_dec_blk3:
        /* input:
@@ -511,11 +518,11 @@ __twofish_dec_blk3:
        outunpack_dec3();
 
        ret;
-.size __twofish_dec_blk3,.-__twofish_dec_blk3;
+ELF(.size __twofish_dec_blk3,.-__twofish_dec_blk3;)
 
 .align 8
 .globl _gcry_twofish_amd64_ctr_enc
-.type   _gcry_twofish_amd64_ctr_enc,@function;
+ELF(.type   _gcry_twofish_amd64_ctr_enc,@function;)
 _gcry_twofish_amd64_ctr_enc:
        /* input:
         *      %rdi: ctx, CTX
@@ -593,11 +600,11 @@ _gcry_twofish_amd64_ctr_enc:
        addq $(8 * 8), %rsp;
 
        ret;
-.size _gcry_twofish_amd64_ctr_enc,.-_gcry_twofish_amd64_ctr_enc;
+ELF(.size _gcry_twofish_amd64_ctr_enc,.-_gcry_twofish_amd64_ctr_enc;)
 
 .align 8
 .globl _gcry_twofish_amd64_cbc_dec
-.type   _gcry_twofish_amd64_cbc_dec,@function;
+ELF(.type   _gcry_twofish_amd64_cbc_dec,@function;)
 _gcry_twofish_amd64_cbc_dec:
        /* input:
         *      %rdi: ctx, CTX
@@ -659,11 +666,11 @@ _gcry_twofish_amd64_cbc_dec:
        addq $(9 * 8), %rsp;
 
        ret;
-.size _gcry_twofish_amd64_cbc_dec,.-_gcry_twofish_amd64_cbc_dec;
+ELF(.size _gcry_twofish_amd64_cbc_dec,.-_gcry_twofish_amd64_cbc_dec;)
 
 .align 8
 .globl _gcry_twofish_amd64_cfb_dec
-.type   _gcry_twofish_amd64_cfb_dec,@function;
+ELF(.type   _gcry_twofish_amd64_cfb_dec,@function;)
 _gcry_twofish_amd64_cfb_dec:
        /* input:
         *      %rdi: ctx, CTX
@@ -725,7 +732,315 @@ _gcry_twofish_amd64_cfb_dec:
        addq $(8 * 8), %rsp;
 
        ret;
-.size _gcry_twofish_amd64_cfb_dec,.-_gcry_twofish_amd64_cfb_dec;
+ELF(.size _gcry_twofish_amd64_cfb_dec,.-_gcry_twofish_amd64_cfb_dec;)
+
+.align 8
+.globl _gcry_twofish_amd64_ocb_enc
+ELF(.type   _gcry_twofish_amd64_ocb_enc,@function;)
+_gcry_twofish_amd64_ocb_enc:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (3 blocks)
+        *      %rdx: src (3 blocks)
+        *      %rcx: offset
+        *      %r8 : checksum
+        *      %r9 : L pointers (void *L[3])
+        */
+       subq $(8 * 8), %rsp;
+       movq %rbp, (0 * 8)(%rsp);
+       movq %rbx, (1 * 8)(%rsp);
+       movq %r12, (2 * 8)(%rsp);
+       movq %r13, (3 * 8)(%rsp);
+       movq %r14, (4 * 8)(%rsp);
+       movq %r15, (5 * 8)(%rsp);
+
+       movq %rsi, (6 * 8)(%rsp);
+       movq %rdx, RX0;
+       movq %rcx, RX1;
+       movq %r8, RX2;
+       movq %r9, RY0;
+       movq %rsi, RY1;
+
+       /* Load offset */
+       movq (0 * 8)(RX1), RT0;
+       movq (1 * 8)(RX1), RT1;
+
+       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+       movq (RY0), RY2;
+       xorq (0 * 8)(RY2), RT0;
+       xorq (1 * 8)(RY2), RT1;
+       movq (0 * 8)(RX0), RAB0;
+       movq (1 * 8)(RX0), RCD0;
+       /* Store Offset_i */
+       movq RT0, (0 * 8)(RY1);
+       movq RT1, (1 * 8)(RY1);
+       /* Checksum_i = Checksum_{i-1} xor P_i  */
+       xor RAB0, (0 * 8)(RX2);
+       xor RCD0, (1 * 8)(RX2);
+       /* PX_i = P_i xor Offset_i */
+       xorq RT0, RAB0;
+       xorq RT1, RCD0;
+
+       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+       movq 8(RY0), RY2;
+       xorq (0 * 8)(RY2), RT0;
+       xorq (1 * 8)(RY2), RT1;
+       movq (2 * 8)(RX0), RAB1;
+       movq (3 * 8)(RX0), RCD1;
+       /* Store Offset_i */
+       movq RT0, (2 * 8)(RY1);
+       movq RT1, (3 * 8)(RY1);
+       /* Checksum_i = Checksum_{i-1} xor P_i  */
+       xor RAB1, (0 * 8)(RX2);
+       xor RCD1, (1 * 8)(RX2);
+       /* PX_i = P_i xor Offset_i */
+       xorq RT0, RAB1;
+       xorq RT1, RCD1;
+
+       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+       movq 16(RY0), RY2;
+       xorq (0 * 8)(RY2), RT0;
+       xorq (1 * 8)(RY2), RT1;
+       movq (4 * 8)(RX0), RAB2;
+       movq (5 * 8)(RX0), RCD2;
+       /* Store Offset_i */
+       movq RT0, (4 * 8)(RY1);
+       movq RT1, (5 * 8)(RY1);
+       /* Checksum_i = Checksum_{i-1} xor P_i  */
+       xor RAB2, (0 * 8)(RX2);
+       xor RCD2, (1 * 8)(RX2);
+       /* PX_i = P_i xor Offset_i */
+       xorq RT0, RAB2;
+       xorq RT1, RCD2;
+
+       /* Store offset */
+       movq RT0, (0 * 8)(RX1);
+       movq RT1, (1 * 8)(RX1);
+
+       /* CX_i = ENCIPHER(K, PX_i)  */
+       call __twofish_enc_blk3;
+
+       movq (6 * 8)(%rsp), RX1; /*dst*/
+
+       /* C_i = CX_i xor Offset_i  */
+       xorq RCD0, (0 * 8)(RX1);
+       xorq RAB0, (1 * 8)(RX1);
+       xorq RCD1, (2 * 8)(RX1);
+       xorq RAB1, (3 * 8)(RX1);
+       xorq RCD2, (4 * 8)(RX1);
+       xorq RAB2, (5 * 8)(RX1);
+
+       movq (0 * 8)(%rsp), %rbp;
+       movq (1 * 8)(%rsp), %rbx;
+       movq (2 * 8)(%rsp), %r12;
+       movq (3 * 8)(%rsp), %r13;
+       movq (4 * 8)(%rsp), %r14;
+       movq (5 * 8)(%rsp), %r15;
+       addq $(8 * 8), %rsp;
+
+       ret;
+ELF(.size _gcry_twofish_amd64_ocb_enc,.-_gcry_twofish_amd64_ocb_enc;)
+
+.align 8
+.globl _gcry_twofish_amd64_ocb_dec
+ELF(.type   _gcry_twofish_amd64_ocb_dec,@function;)
+_gcry_twofish_amd64_ocb_dec:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (3 blocks)
+        *      %rdx: src (3 blocks)
+        *      %rcx: offset
+        *      %r8 : checksum
+        *      %r9 : L pointers (void *L[3])
+        */
+       subq $(8 * 8), %rsp;
+       movq %rbp, (0 * 8)(%rsp);
+       movq %rbx, (1 * 8)(%rsp);
+       movq %r12, (2 * 8)(%rsp);
+       movq %r13, (3 * 8)(%rsp);
+       movq %r14, (4 * 8)(%rsp);
+       movq %r15, (5 * 8)(%rsp);
+
+       movq %rsi, (6 * 8)(%rsp);
+       movq %r8,  (7 * 8)(%rsp);
+       movq %rdx, RX0;
+       movq %rcx, RX1;
+       movq %r9, RY0;
+       movq %rsi, RY1;
+
+       /* Load offset */
+       movq (0 * 8)(RX1), RT0;
+       movq (1 * 8)(RX1), RT1;
+
+       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+       movq (RY0), RY2;
+       xorq (0 * 8)(RY2), RT0;
+       xorq (1 * 8)(RY2), RT1;
+       movq (0 * 8)(RX0), RAB0;
+       movq (1 * 8)(RX0), RCD0;
+       /* Store Offset_i */
+       movq RT0, (0 * 8)(RY1);
+       movq RT1, (1 * 8)(RY1);
+       /* CX_i = C_i xor Offset_i */
+       xorq RT0, RAB0;
+       xorq RT1, RCD0;
+
+       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+       movq 8(RY0), RY2;
+       xorq (0 * 8)(RY2), RT0;
+       xorq (1 * 8)(RY2), RT1;
+       movq (2 * 8)(RX0), RAB1;
+       movq (3 * 8)(RX0), RCD1;
+       /* Store Offset_i */
+       movq RT0, (2 * 8)(RY1);
+       movq RT1, (3 * 8)(RY1);
+       /* PX_i = P_i xor Offset_i */
+       xorq RT0, RAB1;
+       xorq RT1, RCD1;
+
+       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+       movq 16(RY0), RY2;
+       xorq (0 * 8)(RY2), RT0;
+       xorq (1 * 8)(RY2), RT1;
+       movq (4 * 8)(RX0), RAB2;
+       movq (5 * 8)(RX0), RCD2;
+       /* Store Offset_i */
+       movq RT0, (4 * 8)(RY1);
+       movq RT1, (5 * 8)(RY1);
+       /* PX_i = P_i xor Offset_i */
+       xorq RT0, RAB2;
+       xorq RT1, RCD2;
+
+       /* Store offset */
+       movq RT0, (0 * 8)(RX1);
+       movq RT1, (1 * 8)(RX1);
+
+       /* PX_i = DECIPHER(K, CX_i)  */
+       call __twofish_dec_blk3;
+
+       movq (7 * 8)(%rsp), RX2; /*checksum*/
+       movq (6 * 8)(%rsp), RX1; /*dst*/
+
+       /* Load checksum */
+       movq (0 * 8)(RX2), RT0;
+       movq (1 * 8)(RX2), RT1;
+
+       /* P_i = PX_i xor Offset_i  */
+       xorq RCD0, (0 * 8)(RX1);
+       xorq RAB0, (1 * 8)(RX1);
+       xorq RCD1, (2 * 8)(RX1);
+       xorq RAB1, (3 * 8)(RX1);
+       xorq RCD2, (4 * 8)(RX1);
+       xorq RAB2, (5 * 8)(RX1);
+
+       /* Checksum_i = Checksum_{i-1} xor P_i  */
+       xorq (0 * 8)(RX1), RT0;
+       xorq (1 * 8)(RX1), RT1;
+       xorq (2 * 8)(RX1), RT0;
+       xorq (3 * 8)(RX1), RT1;
+       xorq (4 * 8)(RX1), RT0;
+       xorq (5 * 8)(RX1), RT1;
+
+       /* Store checksum */
+       movq RT0, (0 * 8)(RX2);
+       movq RT1, (1 * 8)(RX2);
+
+       movq (0 * 8)(%rsp), %rbp;
+       movq (1 * 8)(%rsp), %rbx;
+       movq (2 * 8)(%rsp), %r12;
+       movq (3 * 8)(%rsp), %r13;
+       movq (4 * 8)(%rsp), %r14;
+       movq (5 * 8)(%rsp), %r15;
+       addq $(8 * 8), %rsp;
+
+       ret;
+ELF(.size _gcry_twofish_amd64_ocb_dec,.-_gcry_twofish_amd64_ocb_dec;)
+
+.align 8
+.globl _gcry_twofish_amd64_ocb_auth
+ELF(.type   _gcry_twofish_amd64_ocb_auth,@function;)
+_gcry_twofish_amd64_ocb_auth:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: abuf (3 blocks)
+        *      %rdx: offset
+        *      %rcx: checksum
+        *      %r8 : L pointers (void *L[3])
+        */
+       subq $(8 * 8), %rsp;
+       movq %rbp, (0 * 8)(%rsp);
+       movq %rbx, (1 * 8)(%rsp);
+       movq %r12, (2 * 8)(%rsp);
+       movq %r13, (3 * 8)(%rsp);
+       movq %r14, (4 * 8)(%rsp);
+       movq %r15, (5 * 8)(%rsp);
+
+       movq %rcx, (6 * 8)(%rsp);
+       movq %rsi, RX0;
+       movq %rdx, RX1;
+       movq %r8, RY0;
+
+       /* Load offset */
+       movq (0 * 8)(RX1), RT0;
+       movq (1 * 8)(RX1), RT1;
+
+       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+       movq (RY0), RY2;
+       xorq (0 * 8)(RY2), RT0;
+       xorq (1 * 8)(RY2), RT1;
+       movq (0 * 8)(RX0), RAB0;
+       movq (1 * 8)(RX0), RCD0;
+       /* PX_i = P_i xor Offset_i */
+       xorq RT0, RAB0;
+       xorq RT1, RCD0;
+
+       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+       movq 8(RY0), RY2;
+       xorq (0 * 8)(RY2), RT0;
+       xorq (1 * 8)(RY2), RT1;
+       movq (2 * 8)(RX0), RAB1;
+       movq (3 * 8)(RX0), RCD1;
+       /* PX_i = P_i xor Offset_i */
+       xorq RT0, RAB1;
+       xorq RT1, RCD1;
+
+       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+       movq 16(RY0), RY2;
+       xorq (0 * 8)(RY2), RT0;
+       xorq (1 * 8)(RY2), RT1;
+       movq (4 * 8)(RX0), RAB2;
+       movq (5 * 8)(RX0), RCD2;
+       /* PX_i = P_i xor Offset_i */
+       xorq RT0, RAB2;
+       xorq RT1, RCD2;
+
+       /* Store offset */
+       movq RT0, (0 * 8)(RX1);
+       movq RT1, (1 * 8)(RX1);
+
+       /* C_i = ENCIPHER(K, PX_i)  */
+       call __twofish_enc_blk3;
+
+       movq (6 * 8)(%rsp), RX1; /*checksum*/
+
+       /* Checksum_i = C_i xor Checksum_i  */
+       xorq RCD0, RCD1;
+       xorq RAB0, RAB1;
+       xorq RCD1, RCD2;
+       xorq RAB1, RAB2;
+       xorq RCD2, (0 * 8)(RX1);
+       xorq RAB2, (1 * 8)(RX1);
+
+       movq (0 * 8)(%rsp), %rbp;
+       movq (1 * 8)(%rsp), %rbx;
+       movq (2 * 8)(%rsp), %r12;
+       movq (3 * 8)(%rsp), %r13;
+       movq (4 * 8)(%rsp), %r14;
+       movq (5 * 8)(%rsp), %r15;
+       addq $(8 * 8), %rsp;
+
+       ret;
+ELF(.size _gcry_twofish_amd64_ocb_auth,.-_gcry_twofish_amd64_ocb_auth;)
 
 #endif /*USE_TWOFISH*/
 #endif /*__x86_64*/
index ead2240..2e1da6c 100644 (file)
@@ -1,6 +1,6 @@
 /* twofish-arm.S  -  ARM assembly implementation of Twofish cipher
  *
- * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
index ecd76e3..f6ecd67 100644 (file)
@@ -45,6 +45,7 @@
 #include "g10lib.h"
 #include "cipher.h"
 #include "bufhelp.h"
+#include "cipher-internal.h"
 #include "cipher-selftest.h"
 
 
@@ -53,7 +54,8 @@
 
 /* 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)
+#if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+    defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
 # define USE_AMD64_ASM 1
 #endif
 
@@ -354,7 +356,8 @@ static const u32 mds[4][256] = {
  * see a non-horrible way of avoiding them, and I did manage to group the
  * statements so that each if covers four group multiplications. */
 
-static const byte poly_to_exp[255] = {
+static const u16 poly_to_exp[256] = {
+   492,
    0x00, 0x01, 0x17, 0x02, 0x2E, 0x18, 0x53, 0x03, 0x6A, 0x2F, 0x93, 0x19,
    0x34, 0x54, 0x45, 0x04, 0x5C, 0x6B, 0xB6, 0x30, 0xA6, 0x94, 0x4B, 0x1A,
    0x8C, 0x35, 0x81, 0x55, 0xAA, 0x46, 0x0D, 0x05, 0x24, 0x5D, 0x87, 0x6C,
@@ -379,7 +382,7 @@ static const byte poly_to_exp[255] = {
    0x85, 0xC8, 0xA1
 };
 
-static const byte exp_to_poly[492] = {
+static const byte exp_to_poly[492 + 256] = {
    0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D, 0x9A, 0x79, 0xF2,
    0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC, 0xF5, 0xA7, 0x03,
    0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3, 0x8B, 0x5B, 0xB6,
@@ -420,7 +423,7 @@ static const byte exp_to_poly[492] = {
    0x3F, 0x7E, 0xFC, 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE,
    0xB1, 0x2F, 0x5E, 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41,
    0x82, 0x49, 0x92, 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E,
-   0x71, 0xE2, 0x89, 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB
+   0x71, 0xE2, 0x89, 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB,
 };
 \f
 
@@ -492,14 +495,15 @@ static byte calc_sb_tbl[512] = {
     0x6F, 0x16, 0x9D, 0x25, 0x36, 0x86, 0x42, 0x56,
     0x4A, 0x55, 0x5E, 0x09, 0xC1, 0xBE, 0xE0, 0x91
 };
+
 /* Macro to perform one column of the RS matrix multiplication.  The
  * parameters a, b, c, and d are the four bytes of output; i is the index
  * of the key bytes, and w, x, y, and z, are the column of constants from
  * the RS matrix, preprocessed through the poly_to_exp table. */
 
 #define CALC_S(a, b, c, d, i, w, x, y, z) \
-   if (key[i]) { \
-      tmp = poly_to_exp[key[i] - 1]; \
+   { \
+      tmp = poly_to_exp[key[i]]; \
       (a) ^= exp_to_poly[tmp + (w)]; \
       (b) ^= exp_to_poly[tmp + (x)]; \
       (c) ^= exp_to_poly[tmp + (y)]; \
@@ -598,7 +602,7 @@ do_twofish_setkey (TWOFISH_context *ctx, const byte *key, const unsigned keylen)
   byte si = 0, sj = 0, sk = 0, sl = 0, sm = 0, sn = 0, so = 0, sp = 0;
 
   /* Temporary for CALC_S. */
-  byte tmp;
+  unsigned int tmp;
 
   /* Flags for self-test. */
   static int initialized = 0;
@@ -666,28 +670,15 @@ do_twofish_setkey (TWOFISH_context *ctx, const byte *key, const unsigned keylen)
           CALC_SB256_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
        }
 
-      /* Calculate whitening and round subkeys.  The constants are
-       * indices of subkeys, preprocessed through q0 and q1. */
-      CALC_K256 (w, 0, 0xA9, 0x75, 0x67, 0xF3);
-      CALC_K256 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
-      CALC_K256 (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
-      CALC_K256 (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
-      CALC_K256 (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
-      CALC_K256 (k, 2, 0x80, 0xE6, 0x78, 0x6B);
-      CALC_K256 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
-      CALC_K256 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
-      CALC_K256 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
-      CALC_K256 (k, 10, 0x35, 0xD8, 0x98, 0xFD);
-      CALC_K256 (k, 12, 0x18, 0x37, 0xF7, 0x71);
-      CALC_K256 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
-      CALC_K256 (k, 16, 0x43, 0x30, 0x75, 0x0F);
-      CALC_K256 (k, 18, 0x37, 0xF8, 0x26, 0x1B);
-      CALC_K256 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
-      CALC_K256 (k, 22, 0x94, 0x06, 0x48, 0x3F);
-      CALC_K256 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
-      CALC_K256 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
-      CALC_K256 (k, 28, 0x84, 0x8A, 0x54, 0x00);
-      CALC_K256 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+      /* Calculate whitening and round subkeys. */
+      for (i = 0; i < 8; i += 2)
+       {
+         CALC_K256 ( w, i, q0[i], q1[i], q0[i + 1], q1[i + 1] );
+       }
+      for (j = 0; j < 32; j += 2, i += 2)
+       {
+         CALC_K256 ( k, j, q0[i], q1[i], q0[i + 1], q1[i + 1] );
+       }
     }
   else
     {
@@ -697,28 +688,15 @@ do_twofish_setkey (TWOFISH_context *ctx, const byte *key, const unsigned keylen)
           CALC_SB_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
         }
 
-      /* Calculate whitening and round subkeys.  The constants are
-       * indices of subkeys, preprocessed through q0 and q1. */
-      CALC_K (w, 0, 0xA9, 0x75, 0x67, 0xF3);
-      CALC_K (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
-      CALC_K (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
-      CALC_K (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
-      CALC_K (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
-      CALC_K (k, 2, 0x80, 0xE6, 0x78, 0x6B);
-      CALC_K (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
-      CALC_K (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
-      CALC_K (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
-      CALC_K (k, 10, 0x35, 0xD8, 0x98, 0xFD);
-      CALC_K (k, 12, 0x18, 0x37, 0xF7, 0x71);
-      CALC_K (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
-      CALC_K (k, 16, 0x43, 0x30, 0x75, 0x0F);
-      CALC_K (k, 18, 0x37, 0xF8, 0x26, 0x1B);
-      CALC_K (k, 20, 0xFA, 0x87, 0x13, 0xFA);
-      CALC_K (k, 22, 0x94, 0x06, 0x48, 0x3F);
-      CALC_K (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
-      CALC_K (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
-      CALC_K (k, 28, 0x84, 0x8A, 0x54, 0x00);
-      CALC_K (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+      /* Calculate whitening and round subkeys. */
+      for (i = 0; i < 8; i += 2)
+       {
+         CALC_K ( w, i, q0[i], q1[i], q0[i + 1], q1[i + 1] );
+       }
+      for (j = 0; j < 32; j += 2, i += 2)
+       {
+         CALC_K ( k, j, q0[i], q1[i], q0[i + 1], q1[i + 1] );
+       }
     }
 
   return 0;
@@ -754,6 +732,159 @@ extern void _gcry_twofish_amd64_cbc_dec(const TWOFISH_context *c, byte *out,
 extern void _gcry_twofish_amd64_cfb_dec(const TWOFISH_context *c, byte *out,
                                        const byte *in, byte *iv);
 
+extern void _gcry_twofish_amd64_ocb_enc(const TWOFISH_context *ctx, byte *out,
+                                       const byte *in, byte *offset,
+                                       byte *checksum, const u64 Ls[3]);
+
+extern void _gcry_twofish_amd64_ocb_dec(const TWOFISH_context *ctx, byte *out,
+                                       const byte *in, byte *offset,
+                                       byte *checksum, const u64 Ls[3]);
+
+extern void _gcry_twofish_amd64_ocb_auth(const TWOFISH_context *ctx,
+                                        const byte *abuf, byte *offset,
+                                        byte *checksum, const u64 Ls[3]);
+
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+static inline void
+call_sysv_fn (const void *fn, const void *arg1, const void *arg2,
+              const void *arg3, const void *arg4)
+{
+  /* Call SystemV ABI function without storing non-volatile XMM registers,
+   * as target function does not use vector instruction sets. */
+  asm volatile ("callq *%0\n\t"
+                : "+a" (fn),
+                  "+D" (arg1),
+                  "+S" (arg2),
+                  "+d" (arg3),
+                  "+c" (arg4)
+                :
+                : "cc", "memory", "r8", "r9", "r10", "r11");
+}
+
+static inline void
+call_sysv_fn5 (const void *fn, const void *arg1, const void *arg2,
+               const void *arg3, const void *arg4, const void *arg5)
+{
+  /* Call SystemV ABI function without storing non-volatile XMM registers,
+   * as target function does not use vector instruction sets. */
+  asm volatile ("movq %[arg5], %%r8\n\t"
+               "callq *%0\n\t"
+               : "+a" (fn),
+                 "+D" (arg1),
+                 "+S" (arg2),
+                 "+d" (arg3),
+                 "+c" (arg4)
+               : [arg5] "g" (arg5)
+               : "cc", "memory", "r8", "r9", "r10", "r11");
+}
+
+static inline void
+call_sysv_fn6 (const void *fn, const void *arg1, const void *arg2,
+               const void *arg3, const void *arg4, const void *arg5,
+              const void *arg6)
+{
+  /* Call SystemV ABI function without storing non-volatile XMM registers,
+   * as target function does not use vector instruction sets. */
+  asm volatile ("movq %[arg5], %%r8\n\t"
+               "movq %[arg6], %%r9\n\t"
+               "callq *%0\n\t"
+               : "+a" (fn),
+                 "+D" (arg1),
+                 "+S" (arg2),
+                 "+d" (arg3),
+                 "+c" (arg4)
+               : [arg5] "g" (arg5),
+                 [arg6] "g" (arg6)
+               : "cc", "memory", "r8", "r9", "r10", "r11");
+}
+#endif
+
+static inline void
+twofish_amd64_encrypt_block(const TWOFISH_context *c, byte *out, const byte *in)
+{
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+  call_sysv_fn(_gcry_twofish_amd64_encrypt_block, c, out, in, NULL);
+#else
+  _gcry_twofish_amd64_encrypt_block(c, out, in);
+#endif
+}
+
+static inline void
+twofish_amd64_decrypt_block(const TWOFISH_context *c, byte *out, const byte *in)
+{
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+  call_sysv_fn(_gcry_twofish_amd64_decrypt_block, c, out, in, NULL);
+#else
+  _gcry_twofish_amd64_decrypt_block(c, out, in);
+#endif
+}
+
+static inline void
+twofish_amd64_ctr_enc(const TWOFISH_context *c, byte *out, const byte *in,
+                      byte *ctr)
+{
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+  call_sysv_fn(_gcry_twofish_amd64_ctr_enc, c, out, in, ctr);
+#else
+  _gcry_twofish_amd64_ctr_enc(c, out, in, ctr);
+#endif
+}
+
+static inline void
+twofish_amd64_cbc_dec(const TWOFISH_context *c, byte *out, const byte *in,
+                      byte *iv)
+{
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+  call_sysv_fn(_gcry_twofish_amd64_cbc_dec, c, out, in, iv);
+#else
+  _gcry_twofish_amd64_cbc_dec(c, out, in, iv);
+#endif
+}
+
+static inline void
+twofish_amd64_cfb_dec(const TWOFISH_context *c, byte *out, const byte *in,
+                      byte *iv)
+{
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+  call_sysv_fn(_gcry_twofish_amd64_cfb_dec, c, out, in, iv);
+#else
+  _gcry_twofish_amd64_cfb_dec(c, out, in, iv);
+#endif
+}
+
+static inline void
+twofish_amd64_ocb_enc(const TWOFISH_context *ctx, byte *out, const byte *in,
+                     byte *offset, byte *checksum, const u64 Ls[3])
+{
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+  call_sysv_fn6(_gcry_twofish_amd64_ocb_enc, ctx, out, in, offset, checksum, Ls);
+#else
+  _gcry_twofish_amd64_ocb_enc(ctx, out, in, offset, checksum, Ls);
+#endif
+}
+
+static inline void
+twofish_amd64_ocb_dec(const TWOFISH_context *ctx, byte *out, const byte *in,
+                     byte *offset, byte *checksum, const u64 Ls[3])
+{
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+  call_sysv_fn6(_gcry_twofish_amd64_ocb_dec, ctx, out, in, offset, checksum, Ls);
+#else
+  _gcry_twofish_amd64_ocb_dec(ctx, out, in, offset, checksum, Ls);
+#endif
+}
+
+static inline void
+twofish_amd64_ocb_auth(const TWOFISH_context *ctx, const byte *abuf,
+                      byte *offset, byte *checksum, const u64 Ls[3])
+{
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+  call_sysv_fn5(_gcry_twofish_amd64_ocb_auth, ctx, abuf, offset, checksum, Ls);
+#else
+  _gcry_twofish_amd64_ocb_auth(ctx, abuf, offset, checksum, Ls);
+#endif
+}
+
 #elif defined(USE_ARM_ASM)
 
 /* Assembly implementations of Twofish. */
@@ -833,7 +964,7 @@ static unsigned int
 twofish_encrypt (void *context, byte *out, const byte *in)
 {
   TWOFISH_context *ctx = context;
-  _gcry_twofish_amd64_encrypt_block(ctx, out, in);
+  twofish_amd64_encrypt_block(ctx, out, in);
   return /*burn_stack*/ (4*sizeof (void*));
 }
 
@@ -900,7 +1031,7 @@ static unsigned int
 twofish_decrypt (void *context, byte *out, const byte *in)
 {
   TWOFISH_context *ctx = context;
-  _gcry_twofish_amd64_decrypt_block(ctx, out, in);
+  twofish_amd64_decrypt_block(ctx, out, in);
   return /*burn_stack*/ (4*sizeof (void*));
 }
 
@@ -980,7 +1111,7 @@ _gcry_twofish_ctr_enc(void *context, unsigned char *ctr, void *outbuf_arg,
     /* Process data in 3 block chunks. */
     while (nblocks >= 3)
       {
-        _gcry_twofish_amd64_ctr_enc(ctx, outbuf, inbuf, ctr);
+        twofish_amd64_ctr_enc(ctx, outbuf, inbuf, ctr);
 
         nblocks -= 3;
         outbuf += 3 * TWOFISH_BLOCKSIZE;
@@ -1038,7 +1169,7 @@ _gcry_twofish_cbc_dec(void *context, unsigned char *iv, void *outbuf_arg,
     /* Process data in 3 block chunks. */
     while (nblocks >= 3)
       {
-        _gcry_twofish_amd64_cbc_dec(ctx, outbuf, inbuf, iv);
+        twofish_amd64_cbc_dec(ctx, outbuf, inbuf, iv);
 
         nblocks -= 3;
         outbuf += 3 * TWOFISH_BLOCKSIZE;
@@ -1087,7 +1218,7 @@ _gcry_twofish_cfb_dec(void *context, unsigned char *iv, void *outbuf_arg,
     /* Process data in 3 block chunks. */
     while (nblocks >= 3)
       {
-        _gcry_twofish_amd64_cfb_dec(ctx, outbuf, inbuf, iv);
+        twofish_amd64_cfb_dec(ctx, outbuf, inbuf, iv);
 
         nblocks -= 3;
         outbuf += 3 * TWOFISH_BLOCKSIZE;
@@ -1116,6 +1247,122 @@ _gcry_twofish_cfb_dec(void *context, unsigned char *iv, void *outbuf_arg,
   _gcry_burn_stack(burn_stack_depth);
 }
 
+/* Bulk encryption/decryption of complete blocks in OCB mode. */
+size_t
+_gcry_twofish_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
+                       const void *inbuf_arg, size_t nblocks, int encrypt)
+{
+#ifdef USE_AMD64_ASM
+  TWOFISH_context *ctx = (void *)&c->context.c;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  unsigned char l_tmp[TWOFISH_BLOCKSIZE];
+  unsigned int burn, burn_stack_depth = 0;
+  u64 blkn = c->u_mode.ocb.data_nblocks;
+
+  {
+    /* Use u64 to store pointers for x32 support (assembly function
+      * assumes 64-bit pointers). */
+    u64 Ls[3];
+
+    /* Process data in 3 block chunks. */
+    while (nblocks >= 3)
+      {
+       /* l_tmp will be used only every 65536-th block. */
+       Ls[0] = (uintptr_t)(const void *)ocb_get_l(c, l_tmp, blkn + 1);
+       Ls[1] = (uintptr_t)(const void *)ocb_get_l(c, l_tmp, blkn + 2);
+       Ls[2] = (uintptr_t)(const void *)ocb_get_l(c, l_tmp, blkn + 3);
+       blkn += 3;
+
+       if (encrypt)
+         twofish_amd64_ocb_enc(ctx, outbuf, inbuf, c->u_iv.iv, c->u_ctr.ctr,
+                               Ls);
+       else
+         twofish_amd64_ocb_dec(ctx, outbuf, inbuf, c->u_iv.iv, c->u_ctr.ctr,
+                               Ls);
+
+       nblocks -= 3;
+       outbuf += 3 * TWOFISH_BLOCKSIZE;
+       inbuf  += 3 * TWOFISH_BLOCKSIZE;
+
+       burn = 8 * sizeof(void*);
+       if (burn > burn_stack_depth)
+         burn_stack_depth = burn;
+      }
+
+    /* Use generic code to handle smaller chunks... */
+  }
+
+  c->u_mode.ocb.data_nblocks = blkn;
+
+  wipememory(&l_tmp, sizeof(l_tmp));
+
+  if (burn_stack_depth)
+    _gcry_burn_stack (burn_stack_depth + 4 * sizeof(void *));
+#else
+  (void)c;
+  (void)outbuf_arg;
+  (void)inbuf_arg;
+  (void)encrypt;
+#endif
+
+  return nblocks;
+}
+
+/* Bulk authentication of complete blocks in OCB mode. */
+size_t
+_gcry_twofish_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
+                       size_t nblocks)
+{
+#ifdef USE_AMD64_ASM
+  TWOFISH_context *ctx = (void *)&c->context.c;
+  const unsigned char *abuf = abuf_arg;
+  unsigned char l_tmp[TWOFISH_BLOCKSIZE];
+  unsigned int burn, burn_stack_depth = 0;
+  u64 blkn = c->u_mode.ocb.aad_nblocks;
+
+  {
+    /* Use u64 to store pointers for x32 support (assembly function
+      * assumes 64-bit pointers). */
+    u64 Ls[3];
+
+    /* Process data in 3 block chunks. */
+    while (nblocks >= 3)
+      {
+       /* l_tmp will be used only every 65536-th block. */
+       Ls[0] = (uintptr_t)(const void *)ocb_get_l(c, l_tmp, blkn + 1);
+       Ls[1] = (uintptr_t)(const void *)ocb_get_l(c, l_tmp, blkn + 2);
+       Ls[2] = (uintptr_t)(const void *)ocb_get_l(c, l_tmp, blkn + 3);
+       blkn += 3;
+
+       twofish_amd64_ocb_auth(ctx, abuf, c->u_mode.ocb.aad_offset,
+                             c->u_mode.ocb.aad_sum, Ls);
+
+       nblocks -= 3;
+       abuf += 3 * TWOFISH_BLOCKSIZE;
+
+       burn = 8 * sizeof(void*);
+       if (burn > burn_stack_depth)
+         burn_stack_depth = burn;
+      }
+
+    /* Use generic code to handle smaller chunks... */
+  }
+
+  c->u_mode.ocb.aad_nblocks = blkn;
+
+  wipememory(&l_tmp, sizeof(l_tmp));
+
+  if (burn_stack_depth)
+    _gcry_burn_stack (burn_stack_depth + 4 * sizeof(void *));
+#else
+  (void)c;
+  (void)abuf_arg;
+#endif
+
+  return nblocks;
+}
+
 \f
 
 /* Run the self-tests for TWOFISH-CTR, tests IV increment of bulk CTR
diff --git a/cipher/whirlpool-sse2-amd64.S b/cipher/whirlpool-sse2-amd64.S
new file mode 100644 (file)
index 0000000..e98b831
--- /dev/null
@@ -0,0 +1,342 @@
+/* whirlpool-sse2-amd64.S  -  AMD64 assembly implementation of Whirlpool
+ *
+ * Copyright (C) 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef __x86_64
+#include <config.h>
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && defined(USE_WHIRLPOOL)
+
+#ifdef __PIC__
+#  define RIP %rip
+#else
+#  define RIP
+#endif
+
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
+
+.text
+
+/* look-up table offsets on RTAB */
+#define RC (0)
+#define C0 (RC + (8 * 10))
+#define C1 (C0 + (8 * 256))
+#define C2 (C1 + (8 * 256))
+#define C3 (C2 + (8 * 256))
+#define C4 (C3 + (8 * 256))
+#define C5 (C4 + (8 * 256))
+#define C6 (C5 + (8 * 256))
+#define C7 (C6 + (8 * 256))
+
+/* stack variables */
+#define STACK_DATAP  (0)
+#define STACK_STATEP (STACK_DATAP + 8)
+#define STACK_ROUNDS (STACK_STATEP + 8)
+#define STACK_NBLKS  (STACK_ROUNDS + 8)
+#define STACK_RBP    (STACK_NBLKS + 8)
+#define STACK_RBX    (STACK_RBP + 8)
+#define STACK_R12    (STACK_RBX + 8)
+#define STACK_R13    (STACK_R12 + 8)
+#define STACK_R14    (STACK_R13 + 8)
+#define STACK_R15    (STACK_R14 + 8)
+#define STACK_MAX    (STACK_R15 + 8)
+
+/* register macros */
+#define RTAB   %rbp
+
+#define RI1    %rax
+#define RI2    %rbx
+#define RI3    %rcx
+#define RI4    %rdx
+
+#define RI1d   %eax
+#define RI2d   %ebx
+#define RI3d   %ecx
+#define RI4d   %edx
+
+#define RI1bl  %al
+#define RI2bl  %bl
+#define RI3bl  %cl
+#define RI4bl  %dl
+
+#define RI1bh  %ah
+#define RI2bh  %bh
+#define RI3bh  %ch
+#define RI4bh  %dh
+
+#define RB0    %r8
+#define RB1    %r9
+#define RB2    %r10
+#define RB3    %r11
+#define RB4    %r12
+#define RB5    %r13
+#define RB6    %r14
+#define RB7    %r15
+
+#define RT0    %rsi
+#define RT1    %rdi
+
+#define RT0d   %esi
+#define RT1d   %edi
+
+#define XKEY0  %xmm0
+#define XKEY1  %xmm1
+#define XKEY2  %xmm2
+#define XKEY3  %xmm3
+#define XKEY4  %xmm4
+#define XKEY5  %xmm5
+#define XKEY6  %xmm6
+#define XKEY7  %xmm7
+
+#define XSTATE0        %xmm8
+#define XSTATE1        %xmm9
+#define XSTATE2        %xmm10
+#define XSTATE3        %xmm11
+#define XSTATE4        %xmm12
+#define XSTATE5        %xmm13
+#define XSTATE6        %xmm14
+#define XSTATE7        %xmm15
+
+/***********************************************************************
+ * AMD64 assembly implementation of Whirlpool.
+ *  - Using table-lookups
+ *  - Store state in XMM registers
+ ***********************************************************************/
+#define __do_whirl(op, ri, \
+                  b0, b1, b2, b3, b4, b5, b6, b7, \
+                  load_ri, load_arg) \
+       movzbl          ri ## bl,       RT0d; \
+       movzbl          ri ## bh,       RT1d; \
+       shrq            $16,            ri; \
+       op ## q         C7(RTAB,RT0,8), b7; \
+       op ## q         C6(RTAB,RT1,8), b6; \
+       movzbl          ri ## bl,       RT0d; \
+       movzbl          ri ## bh,       RT1d; \
+       shrq            $16,            ri; \
+       op ## q         C5(RTAB,RT0,8), b5; \
+       op ## q         C4(RTAB,RT1,8), b4; \
+       movzbl          ri ## bl,       RT0d; \
+       movzbl          ri ## bh,       RT1d; \
+       shrl            $16,            ri ## d; \
+       op ## q         C3(RTAB,RT0,8), b3; \
+       op ## q         C2(RTAB,RT1,8), b2; \
+       movzbl          ri ## bl,       RT0d; \
+       movzbl          ri ## bh,       RT1d; \
+       load_ri(        load_arg,       ri); \
+       op ## q         C1(RTAB,RT0,8), b1; \
+       op ## q         C0(RTAB,RT1,8), b0;
+
+#define do_whirl(op, ri, rb_add, load_ri, load_arg) \
+       __do_whirl(op, ##ri, rb_add, load_ri, load_arg)
+
+#define dummy(...) /*_*/
+
+#define do_movq(src, dst) movq src, dst;
+
+#define RB_ADD0 RB0, RB1, RB2, RB3, RB4, RB5, RB6, RB7
+#define RB_ADD1 RB1, RB2, RB3, RB4, RB5, RB6, RB7, RB0
+#define RB_ADD2 RB2, RB3, RB4, RB5, RB6, RB7, RB0, RB1
+#define RB_ADD3 RB3, RB4, RB5, RB6, RB7, RB0, RB1, RB2
+#define RB_ADD4 RB4, RB5, RB6, RB7, RB0, RB1, RB2, RB3
+#define RB_ADD5 RB5, RB6, RB7, RB0, RB1, RB2, RB3, RB4
+#define RB_ADD6 RB6, RB7, RB0, RB1, RB2, RB3, RB4, RB5
+#define RB_ADD7 RB7, RB0, RB1, RB2, RB3, RB4, RB5, RB6
+
+.align 8
+.globl _gcry_whirlpool_transform_amd64
+ELF(.type  _gcry_whirlpool_transform_amd64,@function;)
+
+_gcry_whirlpool_transform_amd64:
+       /* input:
+        *      %rdi: state
+        *      %rsi: inblk
+        *      %rdx: nblks
+        *      %rcx: look-up tables
+        */
+       cmp $0, %rdx;
+       je .Lskip;
+
+       subq $STACK_MAX, %rsp;
+       movq %rbp, STACK_RBP(%rsp);
+       movq %rbx, STACK_RBX(%rsp);
+       movq %r12, STACK_R12(%rsp);
+       movq %r13, STACK_R13(%rsp);
+       movq %r14, STACK_R14(%rsp);
+       movq %r15, STACK_R15(%rsp);
+
+       movq %rdx, STACK_NBLKS(%rsp);
+       movq %rdi, STACK_STATEP(%rsp);
+       movq %rsi, STACK_DATAP(%rsp);
+
+       movq %rcx, RTAB;
+
+       jmp .Lfirst_block;
+
+.align 8
+.Lblock_loop:
+       movq STACK_DATAP(%rsp), %rsi;
+       movq RI1, %rdi;
+
+.Lfirst_block:
+       /* load data_block */
+       movq 0*8(%rsi), RB0;
+       movq 1*8(%rsi), RB1;
+       bswapq RB0;
+       movq 2*8(%rsi), RB2;
+       bswapq RB1;
+       movq 3*8(%rsi), RB3;
+       bswapq RB2;
+       movq 4*8(%rsi), RB4;
+       bswapq RB3;
+       movq 5*8(%rsi), RB5;
+       bswapq RB4;
+       movq RB0, XSTATE0;
+       movq 6*8(%rsi), RB6;
+       bswapq RB5;
+       movq RB1, XSTATE1;
+       movq 7*8(%rsi), RB7;
+       bswapq RB6;
+       movq RB2, XSTATE2;
+       bswapq RB7;
+       movq RB3, XSTATE3;
+       movq RB4, XSTATE4;
+       movq RB5, XSTATE5;
+       movq RB6, XSTATE6;
+       movq RB7, XSTATE7;
+
+       /* load key */
+       movq 0*8(%rdi), XKEY0;
+       movq 1*8(%rdi), XKEY1;
+       movq 2*8(%rdi), XKEY2;
+       movq 3*8(%rdi), XKEY3;
+       movq 4*8(%rdi), XKEY4;
+       movq 5*8(%rdi), XKEY5;
+       movq 6*8(%rdi), XKEY6;
+       movq 7*8(%rdi), XKEY7;
+
+       movq XKEY0, RI1;
+       movq XKEY1, RI2;
+       movq XKEY2, RI3;
+       movq XKEY3, RI4;
+
+       /* prepare and store state */
+       pxor XKEY0, XSTATE0;
+       pxor XKEY1, XSTATE1;
+       pxor XKEY2, XSTATE2;
+       pxor XKEY3, XSTATE3;
+       pxor XKEY4, XSTATE4;
+       pxor XKEY5, XSTATE5;
+       pxor XKEY6, XSTATE6;
+       pxor XKEY7, XSTATE7;
+
+       movq XSTATE0, 0*8(%rdi);
+       movq XSTATE1, 1*8(%rdi);
+       movq XSTATE2, 2*8(%rdi);
+       movq XSTATE3, 3*8(%rdi);
+       movq XSTATE4, 4*8(%rdi);
+       movq XSTATE5, 5*8(%rdi);
+       movq XSTATE6, 6*8(%rdi);
+       movq XSTATE7, 7*8(%rdi);
+
+       addq $64, STACK_DATAP(%rsp);
+       movl $(0), STACK_ROUNDS(%rsp);
+.align 8
+.Lround_loop:
+       do_whirl(mov, RI1 /*XKEY0*/, RB_ADD0, do_movq, XKEY4);
+       do_whirl(xor, RI2 /*XKEY1*/, RB_ADD1, do_movq, XKEY5);
+       do_whirl(xor, RI3 /*XKEY2*/, RB_ADD2, do_movq, XKEY6);
+       do_whirl(xor, RI4 /*XKEY3*/, RB_ADD3, do_movq, XKEY7);
+       do_whirl(xor, RI1 /*XKEY0*/, RB_ADD4, do_movq, XSTATE0);
+       do_whirl(xor, RI2 /*XKEY1*/, RB_ADD5, do_movq, XSTATE1);
+       do_whirl(xor, RI3 /*XKEY2*/, RB_ADD6, do_movq, XSTATE2);
+       do_whirl(xor, RI4 /*XKEY3*/, RB_ADD7, do_movq, XSTATE3);
+
+       movl STACK_ROUNDS(%rsp), RT0d;
+       movq RB1, XKEY1;
+       addl $1, STACK_ROUNDS(%rsp);
+       movq RB2, XKEY2;
+       movq RB3, XKEY3;
+       xorq RC(RTAB,RT0,8), RB0; /* Add round constant */
+       movq RB4, XKEY4;
+       movq RB5, XKEY5;
+       movq RB0, XKEY0;
+       movq RB6, XKEY6;
+       movq RB7, XKEY7;
+
+       do_whirl(xor, RI1 /*XSTATE0*/, RB_ADD0, do_movq, XSTATE4);
+       do_whirl(xor, RI2 /*XSTATE1*/, RB_ADD1, do_movq, XSTATE5);
+       do_whirl(xor, RI3 /*XSTATE2*/, RB_ADD2, do_movq, XSTATE6);
+       do_whirl(xor, RI4 /*XSTATE3*/, RB_ADD3, do_movq, XSTATE7);
+
+       cmpl $10, STACK_ROUNDS(%rsp);
+       je .Lis_last_round;
+
+       do_whirl(xor, RI1 /*XSTATE4*/, RB_ADD4, do_movq, XKEY0);
+       do_whirl(xor, RI2 /*XSTATE5*/, RB_ADD5, do_movq, XKEY1);
+       do_whirl(xor, RI3 /*XSTATE6*/, RB_ADD6, do_movq, XKEY2);
+       do_whirl(xor, RI4 /*XSTATE7*/, RB_ADD7, do_movq, XKEY3);
+       movq RB0, XSTATE0;
+       movq RB1, XSTATE1;
+       movq RB2, XSTATE2;
+       movq RB3, XSTATE3;
+       movq RB4, XSTATE4;
+       movq RB5, XSTATE5;
+       movq RB6, XSTATE6;
+       movq RB7, XSTATE7;
+
+       jmp .Lround_loop;
+.align 8
+.Lis_last_round:
+       do_whirl(xor, RI1 /*XSTATE4*/, RB_ADD4, dummy, _);
+       movq STACK_STATEP(%rsp), RI1;
+       do_whirl(xor, RI2 /*XSTATE5*/, RB_ADD5, dummy, _);
+       do_whirl(xor, RI3 /*XSTATE6*/, RB_ADD6, dummy, _);
+       do_whirl(xor, RI4 /*XSTATE7*/, RB_ADD7, dummy, _);
+
+       /* store state */
+       xorq RB0, 0*8(RI1);
+       xorq RB1, 1*8(RI1);
+       xorq RB2, 2*8(RI1);
+       xorq RB3, 3*8(RI1);
+       xorq RB4, 4*8(RI1);
+       xorq RB5, 5*8(RI1);
+       xorq RB6, 6*8(RI1);
+       xorq RB7, 7*8(RI1);
+
+       subq $1, STACK_NBLKS(%rsp);
+       jnz .Lblock_loop;
+
+       movq STACK_RBP(%rsp), %rbp;
+       movq STACK_RBX(%rsp), %rbx;
+       movq STACK_R12(%rsp), %r12;
+       movq STACK_R13(%rsp), %r13;
+       movq STACK_R14(%rsp), %r14;
+       movq STACK_R15(%rsp), %r15;
+       addq $STACK_MAX, %rsp;
+.Lskip:
+       movl $(STACK_MAX + 8), %eax;
+       ret;
+ELF(.size _gcry_whirlpool_transform_amd64,.-_gcry_whirlpool_transform_amd64;)
+
+#endif
+#endif
index 338d44e..8a06939 100644 (file)
 #include "bufhelp.h"
 #include "hash-common.h"
 
+/* 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) || \
+    defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define USE_AMD64_ASM 1
+#endif
+
+\f
+
 /* Size of a whirlpool block (in bytes).  */
 #define BLOCK_SIZE 64
 
 /* Number of rounds.  */
 #define R 10
 
-
+\f
 
 /* Types.  */
 typedef u64 whirlpool_block_t[BLOCK_SIZE / 8];
@@ -89,8 +98,15 @@ typedef struct {
 
 \f
 
+
+struct whirlpool_tables_s {
+  u64 RC[R];
+  u64 C[8][256];
+};
+
+static const struct whirlpool_tables_s tab =
+{
 /* Round constants.  */
-static const u64 rc[R] =
   {
     U64_C (0x1823c6e887b8014f),
     U64_C (0x36a6d2f5796f9152),
@@ -102,13 +118,9 @@ static const u64 rc[R] =
     U64_C (0xe427418ba77d95d8),
     U64_C (0xfbee7c66dd17479e),
     U64_C (0xca2dbf07ad5a8333),
-  };
-
-\f
-
+  },
 /* Main lookup boxes.  */
-static const u64 C0[256] =
-  {
+  { {
     U64_C (0x18186018c07830d8), U64_C (0x23238c2305af4626),
     U64_C (0xc6c63fc67ef991b8), U64_C (0xe8e887e8136fcdfb),
     U64_C (0x878726874ca113cb), U64_C (0xb8b8dab8a9626d11),
@@ -237,10 +249,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 +378,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 +507,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 +636,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 +765,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 +894,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 +1023,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),
@@ -1161,15 +1152,75 @@ static const u64 C7[256] =
     U64_C (0x985a98b4c22d2c98), U64_C (0xa4aaa4490e55eda4),
     U64_C (0x28a0285d88507528), U64_C (0x5c6d5cda31b8865c),
     U64_C (0xf8c7f8933fed6bf8), U64_C (0x86228644a411c286),
-  };
+  } }
+};
+#define C tab.C
+#define C0 C[0]
+#define C1 C[1]
+#define C2 C[2]
+#define C3 C[3]
+#define C4 C[4]
+#define C5 C[5]
+#define C6 C[6]
+#define C7 C[7]
+#define rc tab.RC
+
+\f
 
+static unsigned int
+whirlpool_transform (void *ctx, const unsigned char *data, size_t nblks);
 
 \f
+
+static void
+whirlpool_init (void *ctx, unsigned int flags)
+{
+  whirlpool_context_t *context = ctx;
+
+  memset (context, 0, sizeof (*context));
+
+  context->bctx.blocksize = BLOCK_SIZE;
+  context->bctx.bwrite = whirlpool_transform;
+  if ((flags & GCRY_MD_FLAG_BUGEMU1))
+    {
+      memset (&context->bugemu, 0, sizeof context->bugemu);
+      context->use_bugemu = 1;
+    }
+  else
+    context->use_bugemu = 0;
+}
+
+
+#ifdef USE_AMD64_ASM
+
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+# define ASM_FUNC_ABI __attribute__((sysv_abi))
+# define ASM_EXTRA_STACK (10 * 16)
+#else
+# define ASM_FUNC_ABI
+# define ASM_EXTRA_STACK 0
+#endif
+
+extern unsigned int
+_gcry_whirlpool_transform_amd64(u64 *state, const unsigned char *data,
+    size_t nblks, const struct whirlpool_tables_s *tables) ASM_FUNC_ABI;
+
+static unsigned int
+whirlpool_transform (void *ctx, const unsigned char *data, size_t nblks)
+{
+  whirlpool_context_t *context = ctx;
+
+  return _gcry_whirlpool_transform_amd64(
+               context->hash_state, data, nblks, &tab) + ASM_EXTRA_STACK;
+}
+
+#else /* USE_AMD64_ASM */
+
 /*
  * Transform block.
  */
 static unsigned int
-whirlpool_transform (void *ctx, const unsigned char *data)
+whirlpool_transform_blk (void *ctx, const unsigned char *data)
 {
   whirlpool_context_t *context = ctx;
   whirlpool_block_t data_block;
@@ -1268,25 +1319,23 @@ whirlpool_transform (void *ctx, const unsigned char *data)
                         4 * sizeof(void*);
 }
 
-
-static void
-whirlpool_init (void *ctx, unsigned int flags)
+static unsigned int
+whirlpool_transform ( void *c, const unsigned char *data, size_t nblks )
 {
-  whirlpool_context_t *context = ctx;
+  unsigned int burn;
 
-  memset (context, 0, sizeof (*context));
-
-  context->bctx.blocksize = BLOCK_SIZE;
-  context->bctx.bwrite = whirlpool_transform;
-  if ((flags & GCRY_MD_FLAG_BUGEMU1))
+  do
     {
-      memset (&context->bugemu, 0, sizeof context->bugemu);
-      context->use_bugemu = 1;
+      burn = whirlpool_transform_blk (c, data);
+      data += BLOCK_SIZE;
     }
-  else
-    context->use_bugemu = 0;
+  while (--nblks);
+
+  return burn;
 }
 
+#endif /* !USE_AMD64_ASM */
+
 
 /* Bug compatibility Whirlpool version.  */
 static void
@@ -1303,7 +1352,7 @@ whirlpool_add_bugemu (whirlpool_context_t *context,
   if (context->bugemu.count == BLOCK_SIZE)
     {
       /* Flush the buffer.  */
-      whirlpool_transform (context, context->bctx.buf);
+      whirlpool_transform (context, context->bctx.buf, 1);
       context->bugemu.count = 0;
     }
   if (! buffer)
@@ -1323,7 +1372,7 @@ whirlpool_add_bugemu (whirlpool_context_t *context,
 
   while (buffer_n >= BLOCK_SIZE)
     {
-      whirlpool_transform (context, buffer);
+      whirlpool_transform (context, buffer, 1);
       context->bugemu.count = 0;
       buffer_n -= BLOCK_SIZE;
       buffer += BLOCK_SIZE;
@@ -1476,6 +1525,6 @@ gcry_md_spec_t _gcry_digest_spec_whirlpool =
   {
     GCRY_MD_WHIRLPOOL, {0, 0},
     "WHIRLPOOL", NULL, 0, NULL, 64,
-    whirlpool_init, whirlpool_write, whirlpool_final, whirlpool_read,
+    whirlpool_init, whirlpool_write, whirlpool_final, whirlpool_read, NULL,
     sizeof (whirlpool_context_t)
   };
index bb2d26b..3a2d403 100644 (file)
@@ -1,9 +1,8 @@
-# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
-# Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 # if -- disable-static was used.
 
 VPATH = @srcdir@
-am__make_dryrun = \
-  { \
-    am__dry=no; \
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
     case $$MAKEFLAGS in \
       *\\[\ \  ]*) \
-        echo 'am--echo: ; @echo "AM"  OK' | $(MAKE) -f - 2>/dev/null \
-          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
-      *) \
-        for am__flg in $$MAKEFLAGS; do \
-          case $$am__flg in \
-            *=*|--*) ;; \
-            *n*) am__dry=yes; break;; \
-          esac; \
-        done;; \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs  ]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
     esac; \
-    test $$am__dry = yes; \
-  }
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -84,17 +111,16 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = compat
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in clock.c \
-       getpid.c
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am clock.c \
+       getpid.c $(top_srcdir)/build-aux/depcomp
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/gpg-error.m4 \
-       $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/lock.m4 \
-       $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
-       $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+       $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+       $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+       $(top_srcdir)/m4/lt~obsolete.m4 \
        $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \
        $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
-       $(top_srcdir)/m4/threadlib.m4 $(top_srcdir)/acinclude.m4 \
-       $(top_srcdir)/configure.ac
+       $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -107,6 +133,19 @@ libcompat_la_OBJECTS = $(am_libcompat_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
 am__v_lt_0 = --silent
+am__v_lt_1 = 
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
 depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
 am__depfiles_maybe = depfiles
@@ -119,20 +158,16 @@ LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(AM_CFLAGS) $(CFLAGS)
 AM_V_CC = $(am__v_CC_@AM_V@)
 am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
-am__v_CC_0 = @echo "  CC    " $@;
-AM_V_at = $(am__v_at_@AM_V@)
-am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
-am__v_at_0 = @
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
 CCLD = $(CC)
 LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
        $(AM_LDFLAGS) $(LDFLAGS) -o $@
 AM_V_CCLD = $(am__v_CCLD_@AM_V@)
 am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
-am__v_CCLD_0 = @echo "  CCLD  " $@;
-AM_V_GEN = $(am__v_GEN_@AM_V@)
-am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
-am__v_GEN_0 = @echo "  GEN   " $@;
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
 SOURCES = $(libcompat_la_SOURCES)
 DIST_SOURCES = $(libcompat_la_SOURCES)
 am__can_run_installinfo = \
@@ -140,6 +175,23 @@ am__can_run_installinfo = \
     n|no|NO) false;; \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -187,6 +239,8 @@ GCRYPT_RANDOM = @GCRYPT_RANDOM@
 GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
 GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
 GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GPG_ERROR_MT_CFLAGS = @GPG_ERROR_MT_CFLAGS@
+GPG_ERROR_MT_LIBS = @GPG_ERROR_MT_LIBS@
 GREP = @GREP@
 INSERT_SYS_SELECT_H = @INSERT_SYS_SELECT_H@
 INSTALL = @INSTALL@
@@ -207,16 +261,12 @@ LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@
 LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@
 LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@
 LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@
-LIBMULTITHREAD = @LIBMULTITHREAD@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
-LIBTHREAD = @LIBTHREAD@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
-LTLIBMULTITHREAD = @LTLIBMULTITHREAD@
 LTLIBOBJS = @LTLIBOBJS@
-LTLIBTHREAD = @LTLIBTHREAD@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
@@ -247,6 +297,7 @@ SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
+SYSROOT = @SYSROOT@
 SYS_SOCKET_H = @SYS_SOCKET_H@
 VERSION = @VERSION@
 VERSION_NUMBER = @VERSION_NUMBER@
@@ -353,12 +404,15 @@ $(am__aclocal_m4_deps):
 
 clean-noinstLTLIBRARIES:
        -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
-       @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
-         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
-         test "$$dir" != "$$p" || dir=.; \
-         echo "rm -f \"$${dir}/so_locations\""; \
-         rm -f "$${dir}/so_locations"; \
-       done
+       @list='$(noinst_LTLIBRARIES)'; \
+       locs=`for p in $$list; do echo $$p; done | \
+             sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+             sort -u`; \
+       test -z "$$locs" || { \
+         echo rm -f $${locs}; \
+         rm -f $${locs}; \
+       }
+
 libcompat.la: $(libcompat_la_OBJECTS) $(libcompat_la_DEPENDENCIES) $(EXTRA_libcompat_la_DEPENDENCIES) 
        $(AM_V_CCLD)$(LINK)  $(libcompat_la_OBJECTS) $(libcompat_la_LIBADD) $(LIBS)
 
@@ -377,14 +431,14 @@ distclean-compile:
 @am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
 
 .c.obj:
 @am__fastdepCC_TRUE@   $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
 @am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
 
 .c.lo:
 @am__fastdepCC_TRUE@   $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -399,26 +453,15 @@ mostlyclean-libtool:
 clean-libtool:
        -rm -rf .libs _libs
 
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
-       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
-       unique=`for i in $$list; do \
-           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-         done | \
-         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-             END { if (nonempty) { for (i in files) print i; }; }'`; \
-       mkid -fID $$unique
-tags: TAGS
-
-TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-               $(TAGS_FILES) $(LISP)
+ID: $(am__tagged_files)
+       $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
        set x; \
        here=`pwd`; \
-       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-       unique=`for i in $$list; do \
-           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-         done | \
-         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-             END { if (nonempty) { for (i in files) print i; }; }'`; \
+       $(am__define_uniq_tagged_files); \
        shift; \
        if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
@@ -430,15 +473,11 @@ TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
              $$unique; \
          fi; \
        fi
-ctags: CTAGS
-CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-               $(TAGS_FILES) $(LISP)
-       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-       unique=`for i in $$list; do \
-           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-         done | \
-         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-             END { if (nonempty) { for (i in files) print i; }; }'`; \
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+       $(am__define_uniq_tagged_files); \
        test -z "$(CTAGS_ARGS)$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$unique
@@ -447,6 +486,21 @@ GTAGS:
        here=`$(am__cd) $(top_builddir) && pwd` \
          && $(am__cd) $(top_srcdir) \
          && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+       list='$(am__tagged_files)'; \
+       case "$(srcdir)" in \
+         [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+         *) sdir=$(subdir)/$(srcdir) ;; \
+       esac; \
+       for i in $$list; do \
+         if test -f "$$i"; then \
+           echo "$(subdir)/$$i"; \
+         else \
+           echo "$$sdir/$$i"; \
+         fi; \
+       done >> $(top_builddir)/cscope.files
 
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
@@ -588,18 +642,19 @@ uninstall-am:
 
 .MAKE: install-am install-strip
 
-.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
-       clean-libtool clean-noinstLTLIBRARIES ctags distclean \
-       distclean-compile distclean-generic distclean-libtool \
-       distclean-tags distdir dvi dvi-am html html-am info info-am \
-       install install-am install-data install-data-am install-dvi \
-       install-dvi-am install-exec install-exec-am install-html \
-       install-html-am install-info install-info-am install-man \
-       install-pdf install-pdf-am install-ps install-ps-am \
-       install-strip installcheck installcheck-am installdirs \
-       maintainer-clean maintainer-clean-generic mostlyclean \
-       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
-       pdf pdf-am ps ps-am tags uninstall uninstall-am
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+       clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \
+       ctags-am distclean distclean-compile distclean-generic \
+       distclean-libtool distclean-tags distdir dvi dvi-am html \
+       html-am info info-am install install-am install-data \
+       install-data-am install-dvi install-dvi-am install-exec \
+       install-exec-am install-html install-html-am install-info \
+       install-info-am install-man install-pdf install-pdf-am \
+       install-ps install-ps-am install-strip installcheck \
+       installcheck-am installdirs maintainer-clean \
+       maintainer-clean-generic mostlyclean mostlyclean-compile \
+       mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+       tags tags-am uninstall uninstall-am
 
 
 # AC_LIBOBJ files are:
index f59a41c..96b3e2e 100644 (file)
@@ -30,10 +30,9 @@ _gcry_compat_identification (void)
   static const char blurb[] =
     "\n\n"
     "This is Libgcrypt " PACKAGE_VERSION " - The GNU Crypto Library\n"
-    "Copyright (C) 2000-2012 Free Software Foundation, Inc.\n"
-    "Copyright (C) 2012-2014 g10 Code GmbH\n"
-    "Copyright (C) 2013-2014 Jussi Kivilinna\n"
-    "(See the source code for a complete list)\n"
+    "Copyright (C) 2000-2016 Free Software Foundation, Inc.\n"
+    "Copyright (C) 2012-2016 g10 Code GmbH\n"
+    "Copyright (C) 2013-2016 Jussi Kivilinna\n"
     "\n"
     "(" BUILD_REVISION " " BUILD_TIMESTAMP ")\n"
     "\n\n";
index d4202db..609b789 100644 (file)
@@ -48,6 +48,9 @@
 /* Enable support for Intel PCLMUL instructions. */
 #undef ENABLE_PCLMUL_SUPPORT
 
+/* Enable support for Intel SSE4.1 instructions. */
+#undef ENABLE_SSE41_SUPPORT
+
 /* Define to use the GNU C visibility attribute. */
 #undef GCRY_USE_VISIBILITY
 
@@ -69,6 +72,9 @@
 /* Defined if compiler has '__builtin_bswap64' intrinsic */
 #undef HAVE_BUILTIN_BSWAP64
 
+/* Defined if compiler has '__builtin_ctz' intrinsic */
+#undef HAVE_BUILTIN_CTZ
+
 /* Defined if a `byte' is typedef'd */
 #undef HAVE_BYTE_TYPEDEF
 
    implementations */
 #undef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS
 
+/* Defined if underlying assembler is compatible with WIN64 assembly
+   implementations */
+#undef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+
 /* Defined for Alpha platforms */
 #undef HAVE_CPU_ARCH_ALPHA
 
 /* Defined if a GCC style "__attribute__ ((aligned (n))" is supported */
 #undef HAVE_GCC_ATTRIBUTE_ALIGNED
 
+/* Defined if compiler supports "__attribute__ ((ms_abi))" function attribute
+   */
+#undef HAVE_GCC_ATTRIBUTE_MS_ABI
+
+/* Defined if a GCC style "__attribute__ ((packed))" is supported */
+#undef HAVE_GCC_ATTRIBUTE_PACKED
+
+/* Defined if compiler supports "__attribute__ ((sysv_abi))" function
+   attribute */
+#undef HAVE_GCC_ATTRIBUTE_SYSV_ABI
+
+/* Defined if default calling convention is 'ms_abi' */
+#undef HAVE_GCC_DEFAULT_ABI_IS_MS_ABI
+
+/* Defined if default calling convention is 'sysv_abi' */
+#undef HAVE_GCC_DEFAULT_ABI_IS_SYSV_ABI
+
 /* Defined if inline assembler supports AVX instructions */
 #undef HAVE_GCC_INLINE_ASM_AVX
 
 /* Defined if inline assembler supports PCLMUL instructions */
 #undef HAVE_GCC_INLINE_ASM_PCLMUL
 
+/* Defined if inline assembler supports SSE4.1 instructions */
+#undef HAVE_GCC_INLINE_ASM_SSE41
+
 /* Defined if inline assembler supports SSSE3 instructions */
 #undef HAVE_GCC_INLINE_ASM_SSSE3
 
 /* Defined if the GNU Pth is available */
 #undef HAVE_PTH
 
-/* Define if the <pthread.h> defines PTHREAD_MUTEX_RECURSIVE. */
-#undef HAVE_PTHREAD_MUTEX_RECURSIVE
-
-/* Define if the POSIX multithreading library has read/write locks. */
-#undef HAVE_PTHREAD_RWLOCK
+/* Define if we have pthread. */
+#undef HAVE_PTHREAD
 
 /* Define to 1 if you have the `raise' function. */
 #undef HAVE_RAISE
 /* Define to 1 if you have the `strtoul' function. */
 #undef HAVE_STRTOUL
 
+/* Define to 1 if you have the `syscall' function. */
+#undef HAVE_SYSCALL
+
 /* Define to 1 if you have the `sysconf' function. */
 #undef HAVE_SYSCONF
 
 /* defined to the name of the weaker random device */
 #undef NAME_OF_DEV_URANDOM
 
-/* Define to 1 if your C compiler doesn't accept -c and -o together. */
-#undef NO_MINUS_C_MINUS_O
-
 /* Name of this package */
 #undef PACKAGE
 
 /* A human readable text with the name of the OS */
 #undef PRINTABLE_OS_NAME
 
-/* Define if the pthread_in_use() detection is hard. */
-#undef PTHREAD_IN_USE_DETECTION_HARD
-
 /* Define as the return type of signal handlers (`int' or `void'). */
 #undef RETSIGTYPE
 
+/* The size of `uint64_t', as computed by sizeof. */
+#undef SIZEOF_UINT64_T
+
 /* The size of `unsigned int', as computed by sizeof. */
 #undef SIZEOF_UNSIGNED_INT
 
 /* The size of `unsigned short', as computed by sizeof. */
 #undef SIZEOF_UNSIGNED_SHORT
 
+/* The size of `void *', as computed by sizeof. */
+#undef SIZEOF_VOID_P
+
 /* Define to 1 if you have the ANSI C header files. */
 #undef STDC_HEADERS
 
 #undef USE_CAST5
 
 /* Defined if this module should be included */
+#undef USE_CHACHA20
+
+/* Defined if this module should be included */
 #undef USE_CRC
 
 /* Defined if this module should be included */
 #undef USE_IDEA
 
 /* Defined if this module should be included */
+#undef USE_MD2
+
+/* Defined if this module should be included */
 #undef USE_MD4
 
 /* Defined if this module should be included */
 /* set this to limit filenames to the 8.3 format */
 #undef USE_ONLY_8DOT3
 
-/* Define if the POSIX multithreading library can be used. */
-#undef USE_POSIX_THREADS
-
-/* Define if references to the POSIX multithreading library should be made
-   weak. */
-#undef USE_POSIX_THREADS_WEAK
-
 /* Define to support the experimental random daemon */
 #undef USE_RANDOM_DAEMON
 
 #undef USE_SHA256
 
 /* Defined if this module should be included */
-#undef USE_SHA512
-
-/* Define if the old Solaris multithreading library can be used. */
-#undef USE_SOLARIS_THREADS
+#undef USE_SHA3
 
-/* Define if references to the old Solaris multithreading library should be
-   made weak. */
-#undef USE_SOLARIS_THREADS_WEAK
+/* Defined if this module should be included */
+#undef USE_SHA512
 
 /* Enable extensions on AIX 3, Interix.  */
 #ifndef _ALL_SOURCE
 /* Defined if this module should be included */
 #undef USE_WHIRLPOOL
 
-/* Define if the native Windows multithreading API can be used. */
-#undef USE_WINDOWS_THREADS
-
 /* Version of this package */
 #undef VERSION
 
index a3d1e23..b2dbee1 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,7 +1,7 @@
 #! /bin/sh
 # From configure.ac Revision.
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for libgcrypt 1.6.2.
+# Generated by GNU Autoconf 2.69 for libgcrypt 1.7.1.
 #
 # Report bugs to <http://bugs.gnupg.org>.
 #
@@ -591,8 +591,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='libgcrypt'
 PACKAGE_TARNAME='libgcrypt'
-PACKAGE_VERSION='1.6.2'
-PACKAGE_STRING='libgcrypt 1.6.2'
+PACKAGE_VERSION='1.7.1'
+PACKAGE_STRING='libgcrypt 1.7.1'
 PACKAGE_BUGREPORT='http://bugs.gnupg.org'
 PACKAGE_URL=''
 
@@ -634,13 +634,14 @@ ac_includes_default="\
 # include <unistd.h>
 #endif"
 
-gl_use_threads_default=
 ac_subst_vars='am__EXEEXT_FALSE
 am__EXEEXT_TRUE
 LTLIBOBJS
 BUILD_TIMESTAMP
 BUILD_FILEVERSION
 BUILD_REVISION
+BUILD_DOC_FALSE
+BUILD_DOC_TRUE
 GCRYPT_HWF_MODULES
 LIBGCRYPT_DIGESTS
 LIBGCRYPT_PUBKEY_CIPHERS
@@ -700,13 +701,11 @@ MPI_SFLAGS
 FALLBACK_SOCKLEN_T
 SYS_SOCKET_H
 INSERT_SYS_SELECT_H
-LTLIBMULTITHREAD
-LIBMULTITHREAD
-LTLIBTHREAD
-LIBTHREAD
 PTH_LIBS
 PTH_CFLAGS
 PTH_CONFIG
+GPG_ERROR_MT_LIBS
+GPG_ERROR_MT_CFLAGS
 GPG_ERROR_LIBS
 GPG_ERROR_CFLAGS
 GPG_ERROR_CONFIG
@@ -775,10 +774,7 @@ VERSION_NUMBER
 LIBGCRYPT_LT_REVISION
 LIBGCRYPT_LT_AGE
 LIBGCRYPT_LT_CURRENT
-AM_BACKSLASH
-AM_DEFAULT_VERBOSITY
-AM_DEFAULT_V
-AM_V
+SYSROOT
 MAINT
 MAINTAINER_MODE_FALSE
 MAINTAINER_MODE_TRUE
@@ -790,6 +786,10 @@ build_os
 build_vendor
 build_cpu
 build
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+AM_DEFAULT_V
+AM_V
 am__untar
 am__tar
 AMTAR
@@ -854,8 +854,8 @@ SHELL'
 ac_subst_files=''
 ac_user_opts='
 enable_option_checking
-enable_maintainer_mode
 enable_silent_rules
+enable_maintainer_mode
 enable_dependency_tracking
 enable_static
 enable_shared
@@ -881,6 +881,7 @@ enable_hmac_binary_check
 enable_padlock_support
 enable_aesni_support
 enable_pclmul_support
+enable_sse41_support
 enable_drng_support
 enable_avx_support
 enable_avx2_support
@@ -891,14 +892,16 @@ enable_ld_version_script
 with_libgpg_error_prefix
 with_gpg_error_prefix
 with_pth_prefix
-enable_threads
 enable_mpi_path
 enable_optimization
 enable_noexecstack
+enable_doc
+enable_build_timestamp
 '
       ac_precious_vars='build_alias
 host_alias
 target_alias
+SYSROOT
 CC
 CFLAGS
 LDFLAGS
@@ -1448,7 +1451,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures libgcrypt 1.6.2 to adapt to many kinds of systems.
+\`configure' configures libgcrypt 1.7.1 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1518,7 +1521,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of libgcrypt 1.6.2:";;
+     short | recursive ) echo "Configuration of libgcrypt 1.7.1:";;
    esac
   cat <<\_ACEOF
 
@@ -1526,12 +1529,15 @@ Optional Features:
   --disable-option-checking  ignore unrecognized --enable/--with options
   --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
-  --enable-maintainer-mode  enable make rules and dependencies not useful
-                         (and sometimes confusing) to the casual installer
-  --enable-silent-rules          less verbose build output (undo: `make V=1')
-  --disable-silent-rules         verbose build output (undo: `make V=0')
-  --disable-dependency-tracking  speeds up one-time build
-  --enable-dependency-tracking   do not reject slow dependency extractors
+  --enable-silent-rules   less verbose build output (undo: "make V=1")
+  --disable-silent-rules  verbose build output (undo: "make V=0")
+  --enable-maintainer-mode
+                          enable make rules and dependencies not useful (and
+                          sometimes confusing) to the casual installer
+  --enable-dependency-tracking
+                          do not reject slow dependency extractors
+  --disable-dependency-tracking
+                          speeds up one-time build
   --enable-static[=PKGS]  build static libraries [default=no]
   --enable-shared[=PKGS]  build shared libraries [default=yes]
   --enable-fast-install[=PKGS]
@@ -1545,7 +1551,7 @@ Optional Features:
                           select the public-key ciphers to include
   --enable-digests=digests
                           select the message digests to include
-  --enable-kdfs=kdfs      select the KDFs to include
+  --enable-kfds=kdfs      select the KDFs to include
   --enable-random=name    select which random number generator to use
   --disable-dev-random    disable the use of dev random
   --enable-random-daemon  Build and support the experimental gcryptrnd
@@ -1561,6 +1567,7 @@ Optional Features:
   --disable-aesni-support Disable support for the Intel AES-NI instructions
   --disable-pclmul-support
                           Disable support for the Intel PCLMUL instructions
+  --disable-sse41-support Disable support for the Intel SSE4.1 instructions
   --disable-drng-support  Disable support for the Intel DRNG (RDRAND
                           instruction)
   --disable-avx-support   Disable support for the Intel AVX instructions
@@ -1573,14 +1580,15 @@ Optional Features:
   --enable-ld-version-script
                           enable/disable use of linker version script.
                           (default is system dependent)
-  --enable-threads={posix|solaris|windows}
-                          specify multithreading API
-  --disable-threads       build without multithread safety
   --enable-mpi-path=EXTRA_PATH
                           prepend EXTRA_PATH to list of CPU specific
                           optimizations
   --disable-optimization  disable compiler optimization
   --disable-noexecstack   disable non executable stack support
+  --disable-doc           do not build the documentation
+  --enable-build-timestamp
+                          set an explicit build timestamp for reproducibility.
+                          (default is the current time in ISO-8601 format)
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -1598,6 +1606,7 @@ Optional Packages:
   --with-pth-prefix=PFX   prefix where GNU Pth is installed (optional)
 
 Some influential environment variables:
+  SYSROOT     locate config scripts also below that directory
   CC          C compiler command
   CFLAGS      C compiler flags
   LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
@@ -1677,7 +1686,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-libgcrypt configure 1.6.2
+libgcrypt configure 1.7.1
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2329,7 +2338,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by libgcrypt $as_me 1.6.2, which was
+It was created by libgcrypt $as_me 1.7.1, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2682,9 +2691,9 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 #   (Interfaces removed:    CURRENT++, AGE=0, REVISION=0)
 #   (Interfaces added:      CURRENT++, AGE++, REVISION=0)
 #   (No interfaces changed:                   REVISION++)
-LIBGCRYPT_LT_CURRENT=20
-LIBGCRYPT_LT_AGE=0
-LIBGCRYPT_LT_REVISION=2
+LIBGCRYPT_LT_CURRENT=21
+LIBGCRYPT_LT_AGE=1
+LIBGCRYPT_LT_REVISION=1
 
 
 # If the API is changed in an incompatible way: increment the next counter.
@@ -2695,7 +2704,7 @@ LIBGCRYPT_CONFIG_API_VERSION=1
 
 # If you change the required gpg-error version, please remove
 # unnecessary error code defines in src/gcrypt-int.h.
-NEED_GPG_ERROR_VERSION=1.11
+NEED_GPG_ERROR_VERSION=1.13
 
 PACKAGE=$PACKAGE_NAME
 VERSION=$PACKAGE_VERSION
@@ -2730,7 +2739,7 @@ ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
 
 
 
-am__api_version='1.11'
+am__api_version='1.14'
 
 # Find a good install program.  We prefer a C program (faster),
 # so one script is as good as another.  But avoid the broken or
@@ -2827,9 +2836,6 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
 $as_echo_n "checking whether build environment is sane... " >&6; }
-# Just in case
-sleep 1
-echo timestamp > conftest.file
 # Reject unsafe characters in $srcdir or the absolute working directory
 # name.  Accept space and tab only in the latter.
 am_lf='
@@ -2840,32 +2846,40 @@ case `pwd` in
 esac
 case $srcdir in
   *[\\\"\#\$\&\'\`$am_lf\ \    ]*)
-    as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;;
+    as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;;
 esac
 
-# Do `set' in a subshell so we don't clobber the current shell's
+# Do 'set' in a subshell so we don't clobber the current shell's
 # arguments.  Must try -L first in case configure is actually a
 # symlink; some systems play weird games with the mod time of symlinks
 # (eg FreeBSD returns the mod time of the symlink's containing
 # directory).
 if (
-   set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
-   if test "$*" = "X"; then
-      # -L didn't work.
-      set X `ls -t "$srcdir/configure" conftest.file`
-   fi
-   rm -f conftest.file
-   if test "$*" != "X $srcdir/configure conftest.file" \
-      && test "$*" != "X conftest.file $srcdir/configure"; then
-
-      # If neither matched, then we have a broken ls.  This can happen
-      # if, for instance, CONFIG_SHELL is bash and it inherits a
-      # broken ls alias from the environment.  This has actually
-      # happened.  Such a system could not be considered "sane".
-      as_fn_error $? "ls -t appears to fail.  Make sure there is not a broken
-alias in your environment" "$LINENO" 5
-   fi
-
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+     if test "$*" = "X"; then
+       # -L didn't work.
+       set X `ls -t "$srcdir/configure" conftest.file`
+     fi
+     if test "$*" != "X $srcdir/configure conftest.file" \
+       && test "$*" != "X conftest.file $srcdir/configure"; then
+
+       # If neither matched, then we have a broken ls.  This can happen
+       # if, for instance, CONFIG_SHELL is bash and it inherits a
+       # broken ls alias from the environment.  This has actually
+       # happened.  Such a system could not be considered "sane".
+       as_fn_error $? "ls -t appears to fail.  Make sure there is not a broken
+  alias in your environment" "$LINENO" 5
+     fi
+     if test "$2" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
    test "$2" = conftest.file
    )
 then
@@ -2877,6 +2891,16 @@ Check your system clock" "$LINENO" 5
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
 test "$program_prefix" != NONE &&
   program_transform_name="s&^&$program_prefix&;$program_transform_name"
 # Use a double $ so make ignores it.
@@ -2887,8 +2911,8 @@ test "$program_suffix" != NONE &&
 ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
 program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
 
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
 
 if test x"${MISSING+set}" != xset; then
   case $am_aux_dir in
@@ -2899,12 +2923,12 @@ if test x"${MISSING+set}" != xset; then
   esac
 fi
 # Use eval to expand $SHELL
-if eval "$MISSING --run true"; then
-  am_missing_run="$MISSING --run "
+if eval "$MISSING --is-lightweight"; then
+  am_missing_run="$MISSING "
 else
   am_missing_run=
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5
-$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
 fi
 
 if test x"${install_sh}" != xset; then
@@ -2916,10 +2940,10 @@ if test x"${install_sh}" != xset; then
   esac
 fi
 
-# Installed binaries are usually stripped using `strip' when the user
-# run `make install-strip'.  However `strip' might not be the right
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip".  However 'strip' might not be the right
 # tool to use in cross-compilation environments, therefore Automake
-# will honor the `STRIP' environment variable to overrule this program.
+# will honor the 'STRIP' environment variable to overrule this program.
 if test "$cross_compiling" != no; then
   if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
@@ -3058,12 +3082,6 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
 $as_echo "$MKDIR_P" >&6; }
 
-mkdir_p="$MKDIR_P"
-case $mkdir_p in
-  [\\/$]* | ?:[\\/]*) ;;
-  */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
-esac
-
 for ac_prog in gawk mawk nawk awk
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
@@ -3146,6 +3164,45 @@ else
 fi
 rmdir .tst 2>/dev/null
 
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+  enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=1;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+       @$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+    AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
 if test "`cd $srcdir && pwd`" != "`pwd`"; then
   # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
   # is not polluted with repeated "-I."
@@ -3168,7 +3225,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='libgcrypt'
- VERSION='1.6.2'
+ VERSION='1.7.1'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -3196,18 +3253,71 @@ AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
 
 MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
 
+# For better backward compatibility.  To be removed once Automake 1.9.x
+# dies out for good.  For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+mkdir_p='$(MKDIR_P)'
+
 # We need awk for the "check" target.  The system "awk" is bad on
 # some platforms.
 # Always define AMTAR for backward compatibility.  Yes, it's still used
 # in the wild :-(  We should find a proper way to deprecate it ...
 AMTAR='$${TAR-tar}'
 
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar  pax cpio none'
+
 am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
 
 
 
 
 
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes.  So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+  cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present.  This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message.  This
+can help us improve future automake versions.
+
+END
+  if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+    echo 'Configuration will proceed anyway, since you have set the' >&2
+    echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+    echo >&2
+  else
+    cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+    as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
+  fi
+fi
+
 ac_config_headers="$ac_config_headers config.h"
 
 
@@ -3311,10 +3421,10 @@ if test "${enable_silent_rules+set}" = set; then :
   enableval=$enable_silent_rules;
 fi
 
-case $enable_silent_rules in
-yes) AM_DEFAULT_VERBOSITY=0;;
-no)  AM_DEFAULT_VERBOSITY=1;;
-*)   AM_DEFAULT_VERBOSITY=1;;
+case $enable_silent_rules in # (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=1;;
 esac
 am_make=${MAKE-make}
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
@@ -3359,6 +3469,8 @@ AM_BACKSLASH='\'
 
 
 
+
+
 cat >>confdefs.h <<_ACEOF
 #define PACKAGE "$PACKAGE"
 _ACEOF
@@ -3368,7 +3480,7 @@ cat >>confdefs.h <<_ACEOF
 #define VERSION "$VERSION"
 _ACEOF
 
-VERSION_NUMBER=0x010602
+VERSION_NUMBER=0x010701
 
 
 
@@ -4209,6 +4321,65 @@ ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+  # Make sure it works both with $CC and with simple cc.
+  # Following AC_PROG_CC_C_O, we do the test twice because some
+  # compilers refuse to overwrite an existing .o file with -o,
+  # though they will create one.
+  am_cv_prog_cc_c_o=yes
+  for am_i in 1 2; do
+    if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+   ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } \
+         && test -f conftest2.$ac_objext; then
+      : OK
+    else
+      am_cv_prog_cc_c_o=no
+      break
+    fi
+  done
+  rm -f core conftest*
+  unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
 DEPDIR="${am__leading_dot}deps"
 
 ac_config_commands="$ac_config_commands depfiles"
@@ -4228,7 +4399,7 @@ am__quote=
 _am_result=none
 # First try GNU make style include.
 echo "include confinc" > confmf
-# Ignore all kinds of additional output from `make'.
+# Ignore all kinds of additional output from 'make'.
 case `$am_make -s -f confmf 2> /dev/null` in #(
 *the\ am__doit\ target*)
   am__include=include
@@ -4284,8 +4455,8 @@ else
   # We make a subdir and do the tests there.  Otherwise we can end up
   # making bogus files that we don't know about and never remove.  For
   # instance it was reported that on HP-UX the gcc test will end up
-  # making a dummy file named `D' -- because `-MD' means `put the output
-  # in D'.
+  # making a dummy file named 'D' -- because '-MD' means "put the output
+  # in D".
   rm -rf conftest.dir
   mkdir conftest.dir
   # Copy depcomp to subdir because otherwise we won't find it if we're
@@ -4320,16 +4491,16 @@ else
     : > sub/conftest.c
     for i in 1 2 3 4 5 6; do
       echo '#include "conftst'$i'.h"' >> sub/conftest.c
-      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
-      # Solaris 8's {/usr,}/bin/sh.
-      touch sub/conftst$i.h
+      # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+      # Solaris 10 /bin/sh.
+      echo '/* dummy */' > sub/conftst$i.h
     done
     echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
 
-    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # We check with '-c' and '-o' for the sake of the "dashmstdout"
     # mode.  It turns out that the SunPro C++ compiler does not properly
-    # handle `-M -o', and we need to detect this.  Also, some Intel
-    # versions had trouble with output in subdirs
+    # handle '-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs.
     am__obj=sub/conftest.${OBJEXT-o}
     am__minus_obj="-o $am__obj"
     case $depmode in
@@ -4338,8 +4509,8 @@ else
       test "$am__universal" = false || continue
       ;;
     nosideeffect)
-      # after this tag, mechanisms are not by side-effect, so they'll
-      # only be used when explicitly requested
+      # After this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested.
       if test "x$enable_dependency_tracking" = xyes; then
        continue
       else
@@ -4347,7 +4518,7 @@ else
       fi
       ;;
     msvc7 | msvc7msys | msvisualcpp | msvcmsys)
-      # This compiler won't grok `-c -o', but also, the minuso test has
+      # This compiler won't grok '-c -o', but also, the minuso test has
       # not run yet.  These depmodes are late enough in the game, and
       # so weak that their functioning should not be impacted.
       am__obj=conftest.${OBJEXT-o}
@@ -4538,131 +4709,6 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
-if test "x$CC" != xcc; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5
-$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5
-$as_echo_n "checking whether cc understands -c and -o together... " >&6; }
-fi
-set dummy $CC; ac_cc=`$as_echo "$2" |
-                     sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
-if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-# Make sure it works both with $CC and with simple cc.
-# We do the test twice because some compilers refuse to overwrite an
-# existing .o file with -o, though they will create one.
-ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
-rm -f conftest2.*
-if { { case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } &&
-   test -f conftest2.$ac_objext && { { case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; };
-then
-  eval ac_cv_prog_cc_${ac_cc}_c_o=yes
-  if test "x$CC" != xcc; then
-    # Test first that cc exists at all.
-    if { ac_try='cc -c conftest.$ac_ext >&5'
-  { { case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; }; then
-      ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
-      rm -f conftest2.*
-      if { { case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } &&
-        test -f conftest2.$ac_objext && { { case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; };
-      then
-       # cc works too.
-       :
-      else
-       # cc exists but doesn't like -o.
-       eval ac_cv_prog_cc_${ac_cc}_c_o=no
-      fi
-    fi
-  fi
-else
-  eval ac_cv_prog_cc_${ac_cc}_c_o=no
-fi
-rm -f core conftest*
-
-fi
-if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-
-$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h
-
-fi
-
-# FIXME: we rely on the cache variable name because
-# there is no other way.
-set dummy $CC
-am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
-eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
-if test "$am_t" != yes; then
-   # Losing compiler, so override with the script.
-   # FIXME: It is wrong to rewrite CC.
-   # But if we don't then we get into trouble of one sort or another.
-   # A longer-term fix would be to have automake use am__CC in this case,
-   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
-   CC="$am_aux_dir/compile $CC"
-fi
-
 
 # By default we simply use the C compiler to build assembly code.
 
@@ -4682,8 +4728,8 @@ else
   # We make a subdir and do the tests there.  Otherwise we can end up
   # making bogus files that we don't know about and never remove.  For
   # instance it was reported that on HP-UX the gcc test will end up
-  # making a dummy file named `D' -- because `-MD' means `put the output
-  # in D'.
+  # making a dummy file named 'D' -- because '-MD' means "put the output
+  # in D".
   rm -rf conftest.dir
   mkdir conftest.dir
   # Copy depcomp to subdir because otherwise we won't find it if we're
@@ -4716,16 +4762,16 @@ else
     : > sub/conftest.c
     for i in 1 2 3 4 5 6; do
       echo '#include "conftst'$i'.h"' >> sub/conftest.c
-      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
-      # Solaris 8's {/usr,}/bin/sh.
-      touch sub/conftst$i.h
+      # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+      # Solaris 10 /bin/sh.
+      echo '/* dummy */' > sub/conftst$i.h
     done
     echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
 
-    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # We check with '-c' and '-o' for the sake of the "dashmstdout"
     # mode.  It turns out that the SunPro C++ compiler does not properly
-    # handle `-M -o', and we need to detect this.  Also, some Intel
-    # versions had trouble with output in subdirs
+    # handle '-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs.
     am__obj=sub/conftest.${OBJEXT-o}
     am__minus_obj="-o $am__obj"
     case $depmode in
@@ -4734,8 +4780,8 @@ else
       test "$am__universal" = false || continue
       ;;
     nosideeffect)
-      # after this tag, mechanisms are not by side-effect, so they'll
-      # only be used when explicitly requested
+      # After this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested.
       if test "x$enable_dependency_tracking" = xyes; then
        continue
       else
@@ -4743,7 +4789,7 @@ else
       fi
       ;;
     msvc7 | msvc7msys | msvisualcpp | msvcmsys)
-      # This compiler won't grok `-c -o', but also, the minuso test has
+      # This compiler won't grok '-c -o', but also, the minuso test has
       # not run yet.  These depmodes are late enough in the game, and
       # so weak that their functioning should not be impacted.
       am__obj=conftest.${OBJEXT-o}
@@ -12876,7 +12922,7 @@ LIBGCRYPT_CONFIG_HOST="$host"
 
 # Definitions for symmetric ciphers.
 available_ciphers="arcfour blowfish cast5 des aes twofish serpent rfc2268 seed"
-available_ciphers="$available_ciphers camellia idea salsa20 gost28147"
+available_ciphers="$available_ciphers camellia idea salsa20 gost28147 chacha20"
 enabled_ciphers=""
 
 # Definitions for public-key ciphers.
@@ -12884,13 +12930,12 @@ available_pubkey_ciphers="dsa elgamal rsa ecc"
 enabled_pubkey_ciphers=""
 
 # Definitions for message digests.
-available_digests="crc gostr3411-94 md4 md5 rmd160 sha1 sha256"
-available_digests_64="sha512 tiger whirlpool stribog"
+available_digests="crc gostr3411-94 md2 md4 md5 rmd160 sha1 sha256"
+available_digests="$available_digests sha512 sha3 tiger whirlpool stribog"
 enabled_digests=""
 
 # Definitions for kdfs (optional ones)
-available_kdfs="s2k pkdf2"
-available_kdfs_64="scrypt"
+available_kdfs="s2k pkdf2 scrypt"
 enabled_kdfs=""
 
 # Definitions for random modules.
@@ -13410,6 +13455,39 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5
+$as_echo_n "checking size of void *... " >&6; }
+if ${ac_cv_sizeof_void_p+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_void_p" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (void *)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_void_p=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5
+$as_echo "$ac_cv_sizeof_void_p" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_VOID_P $ac_cv_sizeof_void_p
+_ACEOF
+
+
 
 
   ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default"
@@ -13456,31 +13534,94 @@ if test "$ac_cv_sizeof_unsigned_short" = "0" \
 $as_echo "$as_me: WARNING: Hmmm, something is wrong with the sizes - using defaults" >&2;};
 fi
 
-# Do we have any 64-bit data types?
-if test "$ac_cv_sizeof_unsigned_int" != "8" \
-   && test "$ac_cv_sizeof_unsigned_long" != "8" \
-   && test "$ac_cv_sizeof_unsigned_long_long" != "8" \
-   && test "$ac_cv_sizeof_uint64_t" != "8"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No 64-bit types.  Disabling TIGER/192, SCRYPT, SHA-384, \
- SHA-512 and GOST R 34.11-12" >&5
-$as_echo "$as_me: WARNING: No 64-bit types.  Disabling TIGER/192, SCRYPT, SHA-384, \
- SHA-512 and GOST R 34.11-12" >&2;}
+# Ensure that we have UINT64_C before we bother to check for uint64_t
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for UINT64_C" >&5
+$as_echo_n "checking for UINT64_C... " >&6; }
+if ${gnupg_cv_uint64_c_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <inttypes.h>
+int
+main ()
+{
+uint64_t foo=UINT64_C(42);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gnupg_cv_uint64_c_works=yes
 else
-  available_digests="$available_digests $available_digests_64"
-  available_kdfs="$available_kdfs $available_kdfs_64"
+  gnupg_cv_uint64_c_works=no
 fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnupg_cv_uint64_c_works" >&5
+$as_echo "$gnupg_cv_uint64_c_works" >&6; }
+if test "$gnupg_cv_uint64_c_works" = "yes" ; then
+   # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of uint64_t" >&5
+$as_echo_n "checking size of uint64_t... " >&6; }
+if ${ac_cv_sizeof_uint64_t+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (uint64_t))" "ac_cv_sizeof_uint64_t"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_uint64_t" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (uint64_t)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_uint64_t=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_uint64_t" >&5
+$as_echo "$ac_cv_sizeof_uint64_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UINT64_T $ac_cv_sizeof_uint64_t
+_ACEOF
 
-# If not specified otherwise, all available algorithms will be
-# included.
-default_ciphers="$available_ciphers"
-default_pubkey_ciphers="$available_pubkey_ciphers"
-default_digests="$available_digests"
-default_kdfs="$available_kdfs"
-
-# Substitutions to set generated files in a Emacs buffer to read-only.
-emacs_local_vars_begin='Local Variables:'
-
-emacs_local_vars_read_only='buffer-read-only: t'
+
+fi
+
+# Do we have any 64-bit data types?
+if test "$ac_cv_sizeof_unsigned_int" != "8" \
+   && test "$ac_cv_sizeof_unsigned_long" != "8" \
+   && test "$ac_cv_sizeof_unsigned_long_long" != "8" \
+   && test "$ac_cv_sizeof_uint64_t" != "8"; then
+    as_fn_error $? "
+***
+*** No 64-bit integer type available.
+*** It is not possible to build Libgcrypt on this platform.
+***" "$LINENO" 5
+fi
+
+
+# If not specified otherwise, all available algorithms will be
+# included.
+default_ciphers="$available_ciphers"
+default_pubkey_ciphers="$available_pubkey_ciphers"
+default_digests="$available_digests"
+default_kdfs="$available_kdfs"
+# Blacklist MD2 by default
+default_digests=`echo $default_digests | sed -e 's/md2//g'`
+
+# Substitutions to set generated files in a Emacs buffer to read-only.
+emacs_local_vars_begin='Local Variables:'
+
+emacs_local_vars_read_only='buffer-read-only: t'
 
 emacs_local_vars_end='End:'
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pclmulsupport" >&5
 $as_echo "$pclmulsupport" >&6; }
 
+# Implementation of the --disable-sse41-support switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether SSE4.1 support is requested" >&5
+$as_echo_n "checking whether SSE4.1 support is requested... " >&6; }
+# Check whether --enable-sse41-support was given.
+if test "${enable_sse41_support+set}" = set; then :
+  enableval=$enable_sse41_support; sse41support=$enableval
+else
+  sse41support=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sse41support" >&5
+$as_echo "$sse41support" >&6; }
+
 # Implementation of the --disable-drng-support switch.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether DRNG support is requested" >&5
 $as_echo_n "checking whether DRNG support is requested... " >&6; }
@@ -13970,12 +14124,11 @@ _ACEOF
 # gpg-error is required.
 #
 
+  gpg_error_config_prefix=""
 
 # Check whether --with-libgpg-error-prefix was given.
 if test "${with_libgpg_error_prefix+set}" = set; then :
   withval=$with_libgpg_error_prefix; gpg_error_config_prefix="$withval"
-else
-  gpg_error_config_prefix=""
 fi
 
 
 # Check whether --with-gpg-error-prefix was given.
 if test "${with_gpg_error_prefix+set}" = set; then :
   withval=$with_gpg_error_prefix; gpg_error_config_prefix="$withval"
-else
-  gpg_error_config_prefix=""
 fi
 
 
-  if test x$gpg_error_config_prefix != x ; then
-     if test x${GPG_ERROR_CONFIG+set} != xset ; then
-        GPG_ERROR_CONFIG=$gpg_error_config_prefix/bin/gpg-error-config
+  if test x"${GPG_ERROR_CONFIG}" = x ; then
+     if test x"${gpg_error_config_prefix}" != x ; then
+        GPG_ERROR_CONFIG="${gpg_error_config_prefix}/bin/gpg-error-config"
+     else
+       case "${SYSROOT}" in
+         /*)
+           if test -x "${SYSROOT}/bin/gpg-error-config" ; then
+             GPG_ERROR_CONFIG="${SYSROOT}/bin/gpg-error-config"
+           fi
+           ;;
+         '')
+           ;;
+          *)
+           { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring \$SYSROOT as it is not an absolute path." >&5
+$as_echo "$as_me: WARNING: Ignoring \$SYSROOT as it is not an absolute path." >&2;}
+           ;;
+       esac
      fi
   fi
 
-  if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}gpg-error-config", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gpg-error-config; ac_word=$2
+  # Extract the first word of "gpg-error-config", so it can be a program name with args.
+set dummy gpg-error-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
 if ${ac_cv_path_GPG_ERROR_CONFIG+:} false; then :
@@ -14022,6 +14186,7 @@ done
   done
 IFS=$as_save_IFS
 
+  test -z "$ac_cv_path_GPG_ERROR_CONFIG" && ac_cv_path_GPG_ERROR_CONFIG="no"
   ;;
 esac
 fi
@@ -14035,68 +14200,12 @@ $as_echo "no" >&6; }
 fi
 
 
-fi
-if test -z "$ac_cv_path_GPG_ERROR_CONFIG"; then
-  ac_pt_GPG_ERROR_CONFIG=$GPG_ERROR_CONFIG
-  # Extract the first word of "gpg-error-config", so it can be a program name with args.
-set dummy gpg-error-config; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_ac_pt_GPG_ERROR_CONFIG+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  case $ac_pt_GPG_ERROR_CONFIG in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_ac_pt_GPG_ERROR_CONFIG="$ac_pt_GPG_ERROR_CONFIG" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_ac_pt_GPG_ERROR_CONFIG="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-  ;;
-esac
-fi
-ac_pt_GPG_ERROR_CONFIG=$ac_cv_path_ac_pt_GPG_ERROR_CONFIG
-if test -n "$ac_pt_GPG_ERROR_CONFIG"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_GPG_ERROR_CONFIG" >&5
-$as_echo "$ac_pt_GPG_ERROR_CONFIG" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-  if test "x$ac_pt_GPG_ERROR_CONFIG" = x; then
-    GPG_ERROR_CONFIG="no"
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
-    GPG_ERROR_CONFIG=$ac_pt_GPG_ERROR_CONFIG
-  fi
-else
-  GPG_ERROR_CONFIG="$ac_cv_path_GPG_ERROR_CONFIG"
-fi
-
   min_gpg_error_version="$NEED_GPG_ERROR_VERSION"
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GPG Error - version >= $min_gpg_error_version" >&5
 $as_echo_n "checking for GPG Error - version >= $min_gpg_error_version... " >&6; }
   ok=no
-  if test "$GPG_ERROR_CONFIG" != "no" ; then
+  if test "$GPG_ERROR_CONFIG" != "no" \
+     && test -f "$GPG_ERROR_CONFIG" ; then
     req_major=`echo $min_gpg_error_version | \
                sed 's/\([0-9]*\)\.\([0-9]*\)/\1/'`
     req_minor=`echo $min_gpg_error_version | \
@@ -14119,20 +14228,21 @@ $as_echo_n "checking for GPG Error - version >= $min_gpg_error_version... " >&6;
   if test $ok = yes; then
     GPG_ERROR_CFLAGS=`$GPG_ERROR_CONFIG $gpg_error_config_args --cflags`
     GPG_ERROR_LIBS=`$GPG_ERROR_CONFIG $gpg_error_config_args --libs`
+    GPG_ERROR_MT_CFLAGS=`$GPG_ERROR_CONFIG $gpg_error_config_args --mt --cflags 2>/dev/null`
+    GPG_ERROR_MT_LIBS=`$GPG_ERROR_CONFIG $gpg_error_config_args --mt --libs 2>/dev/null`
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes ($gpg_error_config_version)" >&5
 $as_echo "yes ($gpg_error_config_version)" >&6; }
     :
-    if test x"$host" != x ; then
-      gpg_error_config_host=`$GPG_ERROR_CONFIG $gpg_error_config_args --host 2>/dev/null || echo none`
-      if test x"$gpg_error_config_host" != xnone ; then
-        if test x"$gpg_error_config_host" != x"$host" ; then
+    gpg_error_config_host=`$GPG_ERROR_CONFIG $gpg_error_config_args --host 2>/dev/null || echo none`
+    if test x"$gpg_error_config_host" != xnone ; then
+      if test x"$gpg_error_config_host" != x"$host" ; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
 ***
 *** The config script $GPG_ERROR_CONFIG was
 *** built for $gpg_error_config_host and thus may not match the
 *** used host $host.
 *** You may want to use the configure option --with-gpg-error-prefix
-*** to specify a matching config script.
+*** to specify a matching config script or use \$SYSROOT.
 ***" >&5
 $as_echo "$as_me: WARNING:
 ***
@@ -14140,14 +14250,16 @@ $as_echo "$as_me: WARNING:
 *** built for $gpg_error_config_host and thus may not match the
 *** used host $host.
 *** You may want to use the configure option --with-gpg-error-prefix
-*** to specify a matching config script.
+*** to specify a matching config script or use \$SYSROOT.
 ***" >&2;}
-        fi
+        gpg_config_script_warn="$gpg_config_script_warn libgpg-error"
       fi
     fi
   else
     GPG_ERROR_CFLAGS=""
     GPG_ERROR_LIBS=""
+    GPG_ERROR_MT_CFLAGS=""
+    GPG_ERROR_MT_LIBS=""
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
     :
@@ -14155,6 +14267,8 @@ $as_echo "no" >&6; }
 
 
 
+
+
 if test "x$GPG_ERROR_LIBS" = "x"; then
   as_fn_error $? "libgpg-error is needed.
                 See ftp://ftp.gnupg.org/gcrypt/libgpg-error/ ." "$LINENO" 5
 
 
 
-
 #
-# See which thread system we have
+# Check whether pthreads is available
 #
-# Windows has always thread support; thus we don't bother to test for
-# it as it may lead to false results when cross building.
-if test "$have_w32_system" = yes; then
-  $as_echo "#define USE_WINDOWS_THREADS 1" >>confdefs.h
-
-  LIBTHREAD=
-  LTLIBTHREAD=
-  LIBMULTITHREAD=
-  LTLIBMULTITHREAD=
-  THREADLIB_CPPFLAGS=""
-
-
-
-
-else
-
-
-
-
-    THREADLIB_CPPFLAGS=""
-
-  # Check whether --enable-threads was given.
-if test "${enable_threads+set}" = set; then :
-  enableval=$enable_threads; gl_use_threads=$enableval
-else
-  if test -n "$gl_use_threads_default"; then
-       gl_use_threads="$gl_use_threads_default"
-     else
-       case "$host_os" in
-                                                               osf*) gl_use_threads=no ;;
-         cygwin*)
-               case `uname -r` in
-                 1.[0-5].*) gl_use_threads=no ;;
-                 *)         gl_use_threads=yes ;;
-               esac
-               ;;
-         *)    gl_use_threads=yes ;;
-       esac
-     fi
-
-fi
-
-  if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then
-    # For using <pthread.h>:
-    case "$host_os" in
-      osf*)
-        # On OSF/1, the compiler needs the flag -D_REENTRANT so that it
-        # groks <pthread.h>. cc also understands the flag -pthread, but
-        # we don't use it because 1. gcc-2.95 doesn't understand -pthread,
-        # 2. putting a flag into CPPFLAGS that has an effect on the linker
-        # causes the AC_LINK_IFELSE test below to succeed unexpectedly,
-        # leading to wrong values of LIBTHREAD and LTLIBTHREAD.
-        THREADLIB_CPPFLAGS="$THREADLIB_CPPFLAGS -D_REENTRANT"
-        ;;
-    esac
-    # Some systems optimize for single-threaded programs by default, and
-    # need special flags to disable these optimizations. For example, the
-    # definition of 'errno' in <errno.h>.
-    case "$host_os" in
-      aix* | freebsd*)
-           THREADLIB_CPPFLAGS="$THREADLIB_CPPFLAGS -D_THREAD_SAFE"
-           ;;
-      solaris*)
-           THREADLIB_CPPFLAGS="$THREADLIB_CPPFLAGS -D_REENTRANT"
-           ;;
-    esac
-  fi
-  if test x"$THREADLIB_CPPFLAGS" != x ; then
-      CPPFLAGS="$CPPFLAGS $THREADLIB_CPPFLAGS"
-  fi
-
-
-
-
-
-
-  gl_threads_api=none
-  LIBTHREAD=
-  LTLIBTHREAD=
-  LIBMULTITHREAD=
-  LTLIBMULTITHREAD=
-  if test "$gl_use_threads" != no; then
-        { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether imported symbols can be declared weak" >&5
-$as_echo_n "checking whether imported symbols can be declared weak... " >&6; }
-if ${gl_cv_have_weak+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  gl_cv_have_weak=no
-              cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-extern void xyzzy ();
-#pragma weak xyzzy
-int
-main ()
-{
-xyzzy();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  gl_cv_have_weak=maybe
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-       if test $gl_cv_have_weak = maybe; then
-                           if test "$cross_compiling" = yes; then :
-                          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#ifdef __ELF__
-               Extensible Linking Format
-               #endif
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "Extensible Linking Format" >/dev/null 2>&1; then :
-  gl_cv_have_weak="guessing yes"
-else
-  gl_cv_have_weak="guessing no"
-fi
-rm -f conftest*
-
-
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-#include <stdio.h>
-#pragma weak fputs
-int main ()
-{
-  return (fputs == NULL);
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-  gl_cv_have_weak=yes
-else
-  gl_cv_have_weak=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-  conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-       fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_have_weak" >&5
-$as_echo "$gl_cv_have_weak" >&6; }
-    if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then
-      # On OSF/1, the compiler needs the flag -pthread or -D_REENTRANT so that
-      # it groks <pthread.h>. It's added above, in gl_THREADLIB_EARLY_BODY.
-      ac_fn_c_check_header_mongrel "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default"
-if test "x$ac_cv_header_pthread_h" = xyes; then :
-  gl_have_pthread_h=yes
-else
-  gl_have_pthread_h=no
-fi
-
-
-      if test "$gl_have_pthread_h" = yes; then
-        # Other possible tests:
-        #   -lpthreads (FSU threads, PCthreads)
-        #   -lgthreads
-        gl_have_pthread=
-        # Test whether both pthread_mutex_lock and pthread_mutexattr_init exist
-        # in libc. IRIX 6.5 has the first one in both libc and libpthread, but
-        # the second one only in libpthread, and lock.c needs it.
-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <pthread.h>
-int
-main ()
-{
-pthread_mutex_lock((pthread_mutex_t*)0);
-               pthread_mutexattr_init((pthread_mutexattr_t*)0);
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  gl_have_pthread=yes
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-        # Test for libpthread by looking for pthread_kill. (Not pthread_self,
-        # since it is defined as a macro on OSF/1.)
-        if test -n "$gl_have_pthread"; then
-          # The program links fine without libpthread. But it may actually
-          # need to link with libpthread in order to create multiple threads.
-          { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_kill in -lpthread" >&5
-$as_echo_n "checking for pthread_kill in -lpthread... " >&6; }
-if ${ac_cv_lib_pthread_pthread_kill+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpthread  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char pthread_kill ();
-int
-main ()
-{
-return pthread_kill ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_pthread_pthread_kill=yes
-else
-  ac_cv_lib_pthread_pthread_kill=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_kill" >&5
-$as_echo "$ac_cv_lib_pthread_pthread_kill" >&6; }
-if test "x$ac_cv_lib_pthread_pthread_kill" = xyes; then :
-  LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread
-             # On Solaris and HP-UX, most pthread functions exist also in libc.
-             # Therefore pthread_in_use() needs to actually try to create a
-             # thread: pthread_create from libc will fail, whereas
-             # pthread_create will actually create a thread.
-             case "$host_os" in
-               solaris* | hpux*)
-
-$as_echo "#define PTHREAD_IN_USE_DETECTION_HARD 1" >>confdefs.h
-
-             esac
-
-fi
-
-        else
-          # Some library is needed. Try libpthread and libc_r.
-          { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_kill in -lpthread" >&5
-$as_echo_n "checking for pthread_kill in -lpthread... " >&6; }
-if ${ac_cv_lib_pthread_pthread_kill+:} false; then :
+if test "$have_w32_system" != yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5
+$as_echo_n "checking for pthread_create in -lpthread... " >&6; }
+if ${ac_cv_lib_pthread_pthread_create+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -14596,214 +14468,35 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 #ifdef __cplusplus
 extern "C"
 #endif
-char pthread_kill ();
+char pthread_create ();
 int
 main ()
 {
-return pthread_kill ();
+return pthread_create ();
   ;
   return 0;
 }
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_pthread_pthread_kill=yes
+  ac_cv_lib_pthread_pthread_create=yes
 else
-  ac_cv_lib_pthread_pthread_kill=no
+  ac_cv_lib_pthread_pthread_create=no
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_kill" >&5
-$as_echo "$ac_cv_lib_pthread_pthread_kill" >&6; }
-if test "x$ac_cv_lib_pthread_pthread_kill" = xyes; then :
-  gl_have_pthread=yes
-             LIBTHREAD=-lpthread LTLIBTHREAD=-lpthread
-             LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread
-fi
-
-          if test -z "$gl_have_pthread"; then
-            # For FreeBSD 4.
-            { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_kill in -lc_r" >&5
-$as_echo_n "checking for pthread_kill in -lc_r... " >&6; }
-if ${ac_cv_lib_c_r_pthread_kill+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lc_r  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char pthread_kill ();
-int
-main ()
-{
-return pthread_kill ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_c_r_pthread_kill=yes
-else
-  ac_cv_lib_c_r_pthread_kill=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_create" >&5
+$as_echo "$ac_cv_lib_pthread_pthread_create" >&6; }
+if test "x$ac_cv_lib_pthread_pthread_create" = xyes; then :
+  have_pthread=yes
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_r_pthread_kill" >&5
-$as_echo "$ac_cv_lib_c_r_pthread_kill" >&6; }
-if test "x$ac_cv_lib_c_r_pthread_kill" = xyes; then :
-  gl_have_pthread=yes
-               LIBTHREAD=-lc_r LTLIBTHREAD=-lc_r
-               LIBMULTITHREAD=-lc_r LTLIBMULTITHREAD=-lc_r
-fi
-
-          fi
-        fi
-        if test -n "$gl_have_pthread"; then
-          gl_threads_api=posix
-
-$as_echo "#define USE_POSIX_THREADS 1" >>confdefs.h
-
-          if test -n "$LIBMULTITHREAD" || test -n "$LTLIBMULTITHREAD"; then
-            if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then
-
-$as_echo "#define USE_POSIX_THREADS_WEAK 1" >>confdefs.h
-
-              LIBTHREAD=
-              LTLIBTHREAD=
-            fi
-          fi
-        fi
-      fi
-    fi
-    if test -z "$gl_have_pthread"; then
-      if test "$gl_use_threads" = yes || test "$gl_use_threads" = solaris; then
-        gl_have_solaristhread=
-        gl_save_LIBS="$LIBS"
-        LIBS="$LIBS -lthread"
-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-#include <thread.h>
-#include <synch.h>
-
-int
-main ()
-{
-thr_self();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  gl_have_solaristhread=yes
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-        LIBS="$gl_save_LIBS"
-        if test -n "$gl_have_solaristhread"; then
-          gl_threads_api=solaris
-          LIBTHREAD=-lthread
-          LTLIBTHREAD=-lthread
-          LIBMULTITHREAD="$LIBTHREAD"
-          LTLIBMULTITHREAD="$LTLIBTHREAD"
 
-$as_echo "#define USE_SOLARIS_THREADS 1" >>confdefs.h
+  if test "$have_pthread" = yes; then
 
-          if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then
+$as_echo "#define HAVE_PTHREAD 1 " >>confdefs.h
 
-$as_echo "#define USE_SOLARIS_THREADS_WEAK 1" >>confdefs.h
-
-            LIBTHREAD=
-            LTLIBTHREAD=
-          fi
-        fi
-      fi
-    fi
-    if test -z "$gl_have_pthread"; then
-      case "$gl_use_threads" in
-        yes | windows | win32) # The 'win32' is for backward compatibility.
-          if { case "$host_os" in
-                 mingw*) true;;
-                 *) false;;
-               esac
-             }; then
-            gl_threads_api=windows
-
-$as_echo "#define USE_WINDOWS_THREADS 1" >>confdefs.h
-
-          fi
-          ;;
-      esac
-    fi
-  fi
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for multithread API to use" >&5
-$as_echo_n "checking for multithread API to use... " >&6; }
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_threads_api" >&5
-$as_echo "$gl_threads_api" >&6; }
-
-
-
-
-
-
-
-
-
-
-
-  if test "$gl_threads_api" = posix; then
-    # OSF/1 4.0 and Mac OS X 10.1 lack the pthread_rwlock_t type and the
-    # pthread_rwlock_* functions.
-    ac_fn_c_check_type "$LINENO" "pthread_rwlock_t" "ac_cv_type_pthread_rwlock_t" "#include <pthread.h>
-"
-if test "x$ac_cv_type_pthread_rwlock_t" = xyes; then :
-
-$as_echo "#define HAVE_PTHREAD_RWLOCK 1" >>confdefs.h
-
-fi
-
-    # glibc defines PTHREAD_MUTEX_RECURSIVE as enum, not as a macro.
-    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-      #include <pthread.h>
-int
-main ()
-{
-
-#if __FreeBSD__ == 4
-error "No, in FreeBSD 4.0 recursive mutexes actually don't work."
-#elif (defined __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ \
-       && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070)
-error "No, in Mac OS X < 10.7 recursive mutexes actually don't work."
-#else
-int x = (int)PTHREAD_MUTEX_RECURSIVE;
-return !x;
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-$as_echo "#define HAVE_PTHREAD_MUTEX_RECURSIVE 1" >>confdefs.h
-
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
   fi
-  :
-
 fi
 
 
 
 
 #
+# Check for __builtin_ctz intrinsic.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_ctz" >&5
+$as_echo_n "checking for __builtin_ctz... " >&6; }
+if ${gcry_cv_have_builtin_ctz+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcry_cv_have_builtin_ctz=no
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+unsigned int x = 0; int y = __builtin_ctz(x); return y;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  gcry_cv_have_builtin_ctz=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_have_builtin_ctz" >&5
+$as_echo "$gcry_cv_have_builtin_ctz" >&6; }
+if test "$gcry_cv_have_builtin_ctz" = "yes" ; then
+
+$as_echo "#define HAVE_BUILTIN_CTZ 1" >>confdefs.h
+
+fi
+
+
+#
 # Check for VLA support (variable length arrays).
 #
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the variable length arrays are supported" >&5
 
 
 #
+# Check whether the compiler supports the GCC style packed attribute
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the GCC style packed attribute is supported" >&5
+$as_echo_n "checking whether the GCC style packed attribute is supported... " >&6; }
+if ${gcry_cv_gcc_attribute_packed+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcry_cv_gcc_attribute_packed=no
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+struct foolong_s { long b; } __attribute__ ((packed));
+            struct foo_s { char a; struct foolong_s b; }
+              __attribute__ ((packed));
+            enum bar {
+              FOO = 1 / (sizeof(struct foo_s) == (sizeof(char) + sizeof(long))),
+            };
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gcry_cv_gcc_attribute_packed=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_attribute_packed" >&5
+$as_echo "$gcry_cv_gcc_attribute_packed" >&6; }
+if test "$gcry_cv_gcc_attribute_packed" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_ATTRIBUTE_PACKED 1" >>confdefs.h
+
+fi
+
+
+#
 # Check whether the compiler supports 'asm' or '__asm__' keyword for
 # assembler blocks.
 #
 
 tmp_do_check="no"
 case "${host}" in
-    *-mingw32*)
+    i?86-mingw32* | i?86-*-mingw32*)
         ac_cv_sys_symbol_underscore=yes
         ;;
+    x86_64-*-mingw32*)
+        ac_cv_sys_symbol_underscore=no
+        ;;
     i386-emx-os2 | i345686-pc-os2*emx | i386-pc-msdosdjgpp)
         ac_cv_sys_symbol_underscore=yes
         ;;
@@ -16258,35 +16021,171 @@ else
   MPI_MOD_C_UDIV_FALSE=
 fi
 
- if test "$mpi_mod_c_udiv_qrnnd" = yes; then
-  MPI_MOD_C_UDIV_QRNND_TRUE=
-  MPI_MOD_C_UDIV_QRNND_FALSE='#'
+ if test "$mpi_mod_c_udiv_qrnnd" = yes; then
+  MPI_MOD_C_UDIV_QRNND_TRUE=
+  MPI_MOD_C_UDIV_QRNND_FALSE='#'
+else
+  MPI_MOD_C_UDIV_QRNND_TRUE='#'
+  MPI_MOD_C_UDIV_QRNND_FALSE=
+fi
+
+
+# Reset non applicable feature flags.
+if test "$mpi_cpu_arch" != "x86" ; then
+   aesnisupport="n/a"
+   pclmulsupport="n/a"
+   sse41support="n/a"
+   avxsupport="n/a"
+   avx2support="n/a"
+   padlocksupport="n/a"
+   drngsupport="n/a"
+fi
+
+if test "$mpi_cpu_arch" != "arm" ; then
+   neonsupport="n/a"
+fi
+
+
+#############################################
+####                                     ####
+#### Platform specific compiler checks.  ####
+####                                     ####
+#############################################
+
+
+# Following tests depend on warnings to cause compile to fail, so set -Werror
+# temporarily.
+_gcc_cflags_save=$CFLAGS
+CFLAGS="$CFLAGS -Werror"
+
+
+#
+# Check whether compiler supports 'ms_abi' function attribute.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiler supports 'ms_abi' function attribute" >&5
+$as_echo_n "checking whether compiler supports 'ms_abi' function attribute... " >&6; }
+if ${gcry_cv_gcc_attribute_ms_abi+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcry_cv_gcc_attribute_ms_abi=no
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int __attribute__ ((ms_abi)) proto(int);
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gcry_cv_gcc_attribute_ms_abi=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_attribute_ms_abi" >&5
+$as_echo "$gcry_cv_gcc_attribute_ms_abi" >&6; }
+if test "$gcry_cv_gcc_attribute_ms_abi" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_ATTRIBUTE_MS_ABI 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether compiler supports 'sysv_abi' function attribute.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiler supports 'sysv_abi' function attribute" >&5
+$as_echo_n "checking whether compiler supports 'sysv_abi' function attribute... " >&6; }
+if ${gcry_cv_gcc_attribute_sysv_abi+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcry_cv_gcc_attribute_sysv_abi=no
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int __attribute__ ((sysv_abi)) proto(int);
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gcry_cv_gcc_attribute_sysv_abi=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_attribute_sysv_abi" >&5
+$as_echo "$gcry_cv_gcc_attribute_sysv_abi" >&6; }
+if test "$gcry_cv_gcc_attribute_sysv_abi" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_ATTRIBUTE_SYSV_ABI 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether default calling convention is 'ms_abi'.
+#
+if test "$gcry_cv_gcc_attribute_ms_abi" = "yes" ; then
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether default calling convention is 'ms_abi'" >&5
+$as_echo_n "checking whether default calling convention is 'ms_abi'... " >&6; }
+if ${gcry_cv_gcc_default_abi_is_ms_abi+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcry_cv_gcc_default_abi_is_ms_abi=no
+           cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+void *test(void) {
+                 void *(*def_func)(void) = test;
+                 void *__attribute__((ms_abi))(*msabi_func)(void);
+                 /* warning on SysV abi targets, passes on Windows based targets */
+                 msabi_func = def_func;
+                 return msabi_func;
+             }
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gcry_cv_gcc_default_abi_is_ms_abi=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_default_abi_is_ms_abi" >&5
+$as_echo "$gcry_cv_gcc_default_abi_is_ms_abi" >&6; }
+   if test "$gcry_cv_gcc_default_abi_is_ms_abi" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_DEFAULT_ABI_IS_MS_ABI 1" >>confdefs.h
+
+   fi
+fi
+
+
+#
+# Check whether default calling convention is 'sysv_abi'.
+#
+if test "$gcry_cv_gcc_attribute_sysv_abi" = "yes" ; then
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether default calling convention is 'sysv_abi'" >&5
+$as_echo_n "checking whether default calling convention is 'sysv_abi'... " >&6; }
+if ${gcry_cv_gcc_default_abi_is_sysv_abi+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  MPI_MOD_C_UDIV_QRNND_TRUE='#'
-  MPI_MOD_C_UDIV_QRNND_FALSE=
+  gcry_cv_gcc_default_abi_is_sysv_abi=no
+           cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+void *test(void) {
+                 void *(*def_func)(void) = test;
+                 void *__attribute__((sysv_abi))(*sysvabi_func)(void);
+                 /* warning on MS ABI targets, passes on SysV ABI targets */
+                 sysvabi_func = def_func;
+                 return sysvabi_func;
+             }
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gcry_cv_gcc_default_abi_is_sysv_abi=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_default_abi_is_sysv_abi" >&5
+$as_echo "$gcry_cv_gcc_default_abi_is_sysv_abi" >&6; }
+   if test "$gcry_cv_gcc_default_abi_is_sysv_abi" = "yes" ; then
 
+$as_echo "#define HAVE_GCC_DEFAULT_ABI_IS_SYSV_ABI 1" >>confdefs.h
 
-# Reset non applicable feature flags.
-if test "$mpi_cpu_arch" != "x86" ; then
-   aesnisupport="n/a"
-   pclmulsupport="n/a"
-   avxsupport="n/a"
-   avx2support="n/a"
-   padlocksupport="n/a"
-   drngsupport="n/a"
+   fi
 fi
 
-if test "$mpi_cpu_arch" != "arm" ; then
-   neonsupport="n/a"
-fi
 
+# Restore flags.
+CFLAGS=$_gcc_cflags_save;
 
-#############################################
-####                                     ####
-#### Platform specific compiler checks.  ####
-####                                     ####
-#############################################
 
 #
 # Check whether GCC inline assembler supports SSSE3 instructions
@@ -16356,6 +16255,39 @@ $as_echo "#define HAVE_GCC_INLINE_ASM_PCLMUL 1" >>confdefs.h
 
 fi
 
+#
+# Check whether GCC inline assembler supports SSE4.1 instructions.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC inline assembler supports SSE4.1 instructions" >&5
+$as_echo_n "checking whether GCC inline assembler supports SSE4.1 instructions... " >&6; }
+if ${gcry_cv_gcc_inline_asm_sse41+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$mpi_cpu_arch" != "x86" ; then
+          gcry_cv_gcc_inline_asm_sse41="n/a"
+        else
+          gcry_cv_gcc_inline_asm_sse41=no
+          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+void a(void) {
+              int i;
+              __asm__("pextrd \$2, %%xmm0, %[out]\n\t" : [out] "=m" (i));
+            }
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gcry_cv_gcc_inline_asm_sse41=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+        fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_inline_asm_sse41" >&5
+$as_echo "$gcry_cv_gcc_inline_asm_sse41" >&6; }
+if test "$gcry_cv_gcc_inline_asm_sse41" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_INLINE_ASM_SSE41 1" >>confdefs.h
+
+fi
+
 
 #
 # Check whether GCC inline assembler supports AVX instructions
 
 
 #
+# Check whether GCC assembler needs "-Wa,--divide" to correctly handle
+# constant division
+#
+if test $amd64_as_feature_detection = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC assembler handles division correctly" >&5
+$as_echo_n "checking whether GCC assembler handles division correctly... " >&6; }
+if ${gcry_cv_gcc_as_const_division_ok+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcry_cv_gcc_as_const_division_ok=no
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+__asm__("xorl \$(123456789/12345678), %ebp;\n\t");
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gcry_cv_gcc_as_const_division_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_as_const_division_ok" >&5
+$as_echo "$gcry_cv_gcc_as_const_division_ok" >&6; }
+  if test "$gcry_cv_gcc_as_const_division_ok" = "no" ; then
+    #
+    # Add '-Wa,--divide' to CPPFLAGS and try check again.
+    #
+    _gcc_cppflags_save="$CPPFLAGS"
+    CPPFLAGS="$CPPFLAGS -Wa,--divide"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC assembler handles division correctly with \"-Wa,--divide\"" >&5
+$as_echo_n "checking whether GCC assembler handles division correctly with \"-Wa,--divide\"... " >&6; }
+if ${gcry_cv_gcc_as_const_division_with_wadivide_ok+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcry_cv_gcc_as_const_division_with_wadivide_ok=no
+          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+__asm__("xorl \$(123456789/12345678), %ebp;\n\t");
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gcry_cv_gcc_as_const_division_with_wadivide_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_as_const_division_with_wadivide_ok" >&5
+$as_echo "$gcry_cv_gcc_as_const_division_with_wadivide_ok" >&6; }
+    if test "$gcry_cv_gcc_as_const_division_with_wadivide_ok" = "no" ; then
+      # '-Wa,--divide' did not work, restore old flags.
+      CPPFLAGS="$_gcc_cppflags_save"
+    fi
+  fi
+fi
+
+
+#
 # Check whether GCC assembler supports features needed for our amd64
 # implementations
 #
 if test $amd64_as_feature_detection = yes; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC assembler is compatible for amd64 assembly implementations" >&5
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC assembler is compatible for amd64 assembly implementations" >&5
 $as_echo_n "checking whether GCC assembler is compatible for amd64 assembly implementations... " >&6; }
 if ${gcry_cv_gcc_amd64_platform_as_ok+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -16475,12 +16460,14 @@ else
 __asm__(
                 /* Test if '.type' and '.size' are supported.  */
                 /* These work only on ELF targets. */
-               /* TODO: add COFF (mingw64, cygwin64) support to assembly
-                 * implementations.  Mingw64/cygwin64 also require additional
-                 * work because they use different calling convention. */
                "asmfunc:\n\t"
                 ".size asmfunc,.-asmfunc;\n\t"
                 ".type asmfunc,@function;\n\t"
+               /* Test if assembler allows use of '/' for constant division
+                * (Solaris/x86 issue). If previous constant division check
+                * and "-Wa,--divide" workaround failed, this causes assembly
+                * to be disable on this machine. */
+               "xorl \$(123456789/12345678), %ebp;\n\t"
             );
 _ACEOF
 if ac_fn_c_try_compile "$LINENO"; then :
@@ -16496,6 +16483,36 @@ $as_echo "$gcry_cv_gcc_amd64_platform_as_ok" >&6; }
 $as_echo "#define HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS 1" >>confdefs.h
 
   fi
+  if test "$gcry_cv_gcc_amd64_platform_as_ok" = "no" &&
+     test "$gcry_cv_gcc_attribute_sysv_abi" = "yes" &&
+     test "$gcry_cv_gcc_default_abi_is_ms_abi" = "yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC assembler is compatible for WIN64 assembly implementations" >&5
+$as_echo_n "checking whether GCC assembler is compatible for WIN64 assembly implementations... " >&6; }
+if ${gcry_cv_gcc_win64_platform_as_ok+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcry_cv_gcc_win64_platform_as_ok=no
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+__asm__(
+              ".globl asmfunc\n\t"
+              "asmfunc:\n\t"
+              "xorq \$(1234), %rbp;\n\t"
+          );
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gcry_cv_gcc_win64_platform_as_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_win64_platform_as_ok" >&5
+$as_echo "$gcry_cv_gcc_win64_platform_as_ok" >&6; }
+    if test "$gcry_cv_gcc_win64_platform_as_ok" = "yes" ; then
+
+$as_echo "#define HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS 1" >>confdefs.h
+
+    fi
+  fi
 fi
 
 
@@ -16610,7 +16627,7 @@ else
 /* end confdefs.h.  */
 __asm__(
                 ".syntax unified\n\t"
-                ".thumb\n\t"
+                ".arm\n\t"
                 ".fpu neon\n\t"
                 "vld1.64 {%q0-%q1}, [%r0]!;\n\t"
                 "vrev64.8 %q0, %q3;\n\t"
@@ -16708,7 +16725,7 @@ _ACEOF
 fi
 done
 
-for ac_func in fcntl ftruncate flockfile
+for ac_func in syscall fcntl ftruncate flockfile
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
 fi
 
 
-#
-# Check whether we need to link with a pthreads library.
-#
-if test "x$LIBTHREAD" != x; then
-  LIBGCRYPT_CONFIG_LIBS="${LIBGCRYPT_CONFIG_LIBS} ${LIBTHREAD}"
-fi
-
 
 #
 # Check whether we can use Linux capabilities as requested.
@@ -17380,6 +17390,11 @@ if test x"$pclmulsupport" = xyes ; then
     pclmulsupport="no (unsupported by compiler)"
   fi
 fi
+if test x"$sse41support" = xyes ; then
+  if test "$gcry_cv_gcc_inline_asm_sse41" != "yes" ; then
+    sse41support="no (unsupported by compiler)"
+  fi
+fi
 if test x"$avxsupport" = xyes ; then
   if test "$gcry_cv_gcc_inline_asm_avx" != "yes" ; then
     avxsupport="no (unsupported by compiler)"
@@ -17406,6 +17421,11 @@ if test x"$pclmulsupport" = xyes ; then
 $as_echo "#define ENABLE_PCLMUL_SUPPORT 1" >>confdefs.h
 
 fi
+if test x"$sse41support" = xyes ; then
+
+$as_echo "#define ENABLE_SSE41_SUPPORT 1" >>confdefs.h
+
+fi
 if test x"$avxsupport" = xyes ; then
 
 $as_echo "#define ENABLE_AVX_SUPPORT 1" >>confdefs.h
@@ -17452,6 +17472,13 @@ if test "$found" = "1"; then
 
 $as_echo "#define USE_ARCFOUR 1" >>confdefs.h
 
+
+   case "${host}" in
+      x86_64-*-*)
+         # Build with the assembly implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS arcfour-amd64.lo"
+      ;;
+   esac
 fi
 
 
@@ -17528,6 +17555,13 @@ if test "$found" = "1" ; then
 
 $as_echo "#define USE_DES 1" >>confdefs.h
 
+
+   case "${host}" in
+      x86_64-*-*)
+         # Build with the assembly implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS des-amd64.lo"
+      ;;
+   esac
 fi
 
 
@@ -17551,12 +17585,25 @@ $as_echo "#define USE_AES 1" >>confdefs.h
       x86_64-*-*)
          # Build with the assembly implementation
          GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-amd64.lo"
+
+         # Build with the SSSE3 implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-ssse3-amd64.lo"
       ;;
       arm*-*-*)
          # Build with the assembly implementation
          GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-arm.lo"
       ;;
    esac
+
+   case "$mpi_cpu_arch" in
+     x86)
+         # Build with the AES-NI implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-aesni.lo"
+
+         # Build with the Padlock implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-padlock.lo"
+      ;;
+   esac
 fi
 
 
@@ -17765,6 +17812,51 @@ $as_echo "#define USE_GOST28147 1" >>confdefs.h
 fi
 
 
+name=chacha20
+list=$enabled_ciphers
+found=0
+
+for n in $list; do
+  if test "x$name" = "x$n"; then
+    found=1
+  fi
+done
+
+if test "$found" = "1" ; then
+   GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20.lo"
+
+$as_echo "#define USE_CHACHA20 1" >>confdefs.h
+
+
+   case "${host}" in
+      x86_64-*-*)
+         # Build with the assembly implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20-sse2-amd64.lo"
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20-ssse3-amd64.lo"
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20-avx2-amd64.lo"
+      ;;
+   esac
+
+   if test x"$neonsupport" = xyes ; then
+     # Build with the NEON implementation
+     GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20-armv7-neon.lo"
+   fi
+fi
+
+case "${host}" in
+   x86_64-*-*)
+      # Build with the assembly implementation
+      GCRYPT_CIPHERS="$GCRYPT_CIPHERS poly1305-sse2-amd64.lo"
+      GCRYPT_CIPHERS="$GCRYPT_CIPHERS poly1305-avx2-amd64.lo"
+   ;;
+esac
+
+if test x"$neonsupport" = xyes ; then
+   # Build with the NEON implementation
+   GCRYPT_CIPHERS="$GCRYPT_CIPHERS poly1305-armv7-neon.lo"
+fi
+
+
 name=dsa
 list=$enabled_pubkey_ciphers
 found=0
@@ -17854,6 +17946,13 @@ if test "$found" = "1" ; then
 
 $as_echo "#define USE_CRC 1" >>confdefs.h
 
+
+   case "${host}" in
+      i?86-*-* | x86_64-*-*)
+         # Build with the assembly implementation
+         GCRYPT_DIGESTS="$GCRYPT_DIGESTS crc-intel-pclmul.lo"
+      ;;
+   esac
 fi
 
 
@@ -17907,6 +18006,24 @@ $as_echo "#define USE_GOST_R_3411_12 1" >>confdefs.h
 fi
 
 
+name=md2
+list=$enabled_digests
+found=0
+
+for n in $list; do
+  if test "x$name" = "x$n"; then
+    found=1
+  fi
+done
+
+if test "$found" = "1" ; then
+   GCRYPT_DIGESTS="$GCRYPT_DIGESTS md2.lo"
+
+$as_echo "#define USE_MD2 1" >>confdefs.h
+
+fi
+
+
 name=md4
 list=$enabled_digests
 found=0
@@ -17943,6 +18060,24 @@ $as_echo "#define USE_MD5 1" >>confdefs.h
 fi
 
 
+name=rmd160
+list=$enabled_digests
+found=0
+
+for n in $list; do
+  if test "x$name" = "x$n"; then
+    found=1
+  fi
+done
+
+if test "$found" = "1" ; then
+   GCRYPT_DIGESTS="$GCRYPT_DIGESTS rmd160.lo"
+
+$as_echo "#define USE_RMD160 1" >>confdefs.h
+
+fi
+
+
 name=sha256
 list=$enabled_digests
 found=0
@@ -17963,6 +18098,8 @@ $as_echo "#define USE_SHA256 1" >>confdefs.h
       x86_64-*-*)
          # Build with the assembly implementation
          GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256-ssse3-amd64.lo"
+         GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256-avx-amd64.lo"
+         GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256-avx2-bmi2-amd64.lo"
       ;;
    esac
 fi
@@ -17991,6 +18128,10 @@ $as_echo "#define USE_SHA512 1" >>confdefs.h
          GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-avx-amd64.lo"
          GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-avx2-bmi2-amd64.lo"
       ;;
+      arm*-*-*)
+         # Build with the assembly implementation
+         GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-arm.lo"
+      ;;
    esac
 
    if test x"$neonsupport" = xyes ; then
@@ -18000,6 +18141,36 @@ $as_echo "#define USE_SHA512 1" >>confdefs.h
 fi
 
 
+name=sha3
+list=$enabled_digests
+found=0
+
+for n in $list; do
+  if test "x$name" = "x$n"; then
+    found=1
+  fi
+done
+
+if test "$found" = "1" ; then
+   GCRYPT_DIGESTS="$GCRYPT_DIGESTS keccak.lo"
+
+$as_echo "#define USE_SHA3 1" >>confdefs.h
+
+
+   case "${host}" in
+      x86_64-*-*)
+         # Build with the assembly implementation
+         :
+      ;;
+   esac
+
+   if test x"$neonsupport" = xyes ; then
+     # Build with the NEON implementation
+     GCRYPT_DIGESTS="$GCRYPT_DIGESTS keccak-armv7-neon.lo"
+   fi
+fi
+
+
 name=tiger
 list=$enabled_digests
 found=0
@@ -18033,13 +18204,18 @@ if test "$found" = "1" ; then
 
 $as_echo "#define USE_WHIRLPOOL 1" >>confdefs.h
 
-fi
-
-# rmd160 and sha1 should be included always.
-GCRYPT_DIGESTS="$GCRYPT_DIGESTS rmd160.lo sha1.lo"
 
-$as_echo "#define USE_RMD160 1" >>confdefs.h
+   case "${host}" in
+      x86_64-*-*)
+         # Build with the assembly implementation
+         GCRYPT_DIGESTS="$GCRYPT_DIGESTS whirlpool-sse2-amd64.lo"
+      ;;
+   esac
+fi
 
+# SHA-1 needs to be included always for example because it is used by
+# random-csprng.c.
+GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1.lo"
 
 $as_echo "#define USE_SHA1 1" >>confdefs.h
 
@@ -18048,6 +18224,12 @@ case "${host}" in
   x86_64-*-*)
     # Build with the assembly implementation
     GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1-ssse3-amd64.lo"
+    GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1-avx-amd64.lo"
+    GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1-avx-bmi2-amd64.lo"
+  ;;
+  arm*-*-*)
+    # Build with the assembly implementation
+    GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1-armv7-neon.lo"
   ;;
 esac
 
@@ -18250,9 +18432,30 @@ esac
 
 
 #
+# Option to disable building of doc file
+#
+build_doc=yes
+# Check whether --enable-doc was given.
+if test "${enable_doc+set}" = set; then :
+  enableval=$enable_doc; build_doc=$enableval
+else
+  build_doc=yes
+fi
+
+ if test "x$build_doc" != xno; then
+  BUILD_DOC_TRUE=
+  BUILD_DOC_FALSE='#'
+else
+  BUILD_DOC_TRUE='#'
+  BUILD_DOC_FALSE=
+fi
+
+
+
+#
 # Provide information about the build.
 #
-BUILD_REVISION="b3936b6"
+BUILD_REVISION="48aa6d6"
 
 
 cat >>confdefs.h <<_ACEOF
@@ -18261,10 +18464,20 @@ _ACEOF
 
 
 BUILD_FILEVERSION=`echo "$VERSION" | sed 's/\([0-9.]*\).*/\1./;s/\./,/g'`
-BUILD_FILEVERSION="${BUILD_FILEVERSION}45971"
+BUILD_FILEVERSION="${BUILD_FILEVERSION}18602"
 
 
-BUILD_TIMESTAMP=`date -u +%Y-%m-%dT%H:%M+0000 2>/dev/null || date`
+# Check whether --enable-build-timestamp was given.
+if test "${enable_build_timestamp+set}" = set; then :
+  enableval=$enable_build_timestamp; if test "$enableval" = "yes"; then
+        BUILD_TIMESTAMP=`date -u +%Y-%m-%dT%H:%M+0000 2>/dev/null || date`
+      else
+        BUILD_TIMESTAMP="$enableval"
+      fi
+else
+  BUILD_TIMESTAMP="<none>"
+fi
+
 
 
 cat >>confdefs.h <<_ACEOF
@@ -18387,6 +18600,14 @@ LIBOBJS=$ac_libobjs
 LTLIBOBJS=$ac_ltlibobjs
 
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
  if test -n "$EXEEXT"; then
   am__EXEEXT_TRUE=
   am__EXEEXT_FALSE='#'
@@ -18508,6 +18729,10 @@ if test -z "${CROSS_COMPILING_TRUE}" && test -z "${CROSS_COMPILING_FALSE}"; then
   as_fn_error $? "conditional \"CROSS_COMPILING\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${BUILD_DOC_TRUE}" && test -z "${BUILD_DOC_FALSE}"; then
+  as_fn_error $? "conditional \"BUILD_DOC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 
 : "${CONFIG_STATUS=./config.status}"
 ac_write_fail=0
@@ -18905,7 +19130,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by libgcrypt $as_me 1.6.2, which was
+This file was extended by libgcrypt $as_me 1.7.1, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -18975,7 +19200,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-libgcrypt config.status 1.6.2
+libgcrypt config.status 1.7.1
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -20110,7 +20335,7 @@ $as_echo "$as_me: executing $ac_file commands" >&6;}
 
   case $ac_file$ac_mode in
     "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
-  # Autoconf 2.62 quotes --file arguments for eval, but not when files
+  # Older Autoconf quotes --file arguments for eval, but not when files
   # are listed without --file.  Let's play safe and only enable the eval
   # if we detect the quoting.
   case $CONFIG_FILES in
@@ -20123,7 +20348,7 @@ $as_echo "$as_me: executing $ac_file commands" >&6;}
     # Strip MF so we end up with the name of the file.
     mf=`echo "$mf" | sed -e 's/:.*$//'`
     # Check whether this is an Automake generated Makefile or not.
-    # We used to match only the files named `Makefile.in', but
+    # We used to match only the files named 'Makefile.in', but
     # some people rename them; so instead we look at the file content.
     # Grep'ing the first line is not enough: some people post-process
     # each Makefile.in and add a new line on top of each file to say so.
@@ -20157,21 +20382,19 @@ $as_echo X"$mf" |
       continue
     fi
     # Extract the definition of DEPDIR, am__include, and am__quote
-    # from the Makefile without running `make'.
+    # from the Makefile without running 'make'.
     DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
     test -z "$DEPDIR" && continue
     am__include=`sed -n 's/^am__include = //p' < "$mf"`
-    test -z "am__include" && continue
+    test -z "$am__include" && continue
     am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
-    # When using ansi2knr, U may be empty or an underscore; expand it
-    U=`sed -n 's/^U = //p' < "$mf"`
     # Find all dependency output files, they are included files with
     # $(DEPDIR) in their names.  We invoke sed twice because it is the
     # simplest approach to changing $(DEPDIR) to its actual value in the
     # expansion.
     for file in `sed -n "
       s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
-        sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+        sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
       # Make sure the directory exists.
       test -f "$dirpart/$file" && continue
       fdir=`$as_dirname -- "$file" ||
@@ -21139,6 +21362,9 @@ test -n "$detection_module" || detection_module="none"
      echo "        Try using Intel PCLMUL:    $pclmulsupport" 1>&6
 
 
+     echo "        Try using Intel SSE4.1:    $sse41support" 1>&6
+
+
      echo "        Try using DRNG (RDRAND):   $drngsupport" 1>&6
 
 
@@ -21154,9 +21380,17 @@ test -n "$detection_module" || detection_module="none"
      echo "         " 1>&6
 
 
-if test "$print_egd_notice" = "yes"; then
+if test "x${gpg_config_script_warn}" != x; then
 cat <<G10EOF
+        Mismatches between the target platform and the to
+        be used libraries have been been detected for:
+         ${gpg_config_script_warn}
+        Please check above for warning messages.
 
+G10EOF
+fi
+if test "$print_egd_notice" = "yes"; then
+cat <<G10EOF
    The performance of the Unix random gatherer module (rndunix) is not
    very good and it does not keep the entropy pool over multiple
    invocations of Libgcrypt base applications.  The suggested way to
@@ -21165,18 +21399,16 @@ cat <<G10EOF
                  Entropy Gathering Daemon (EGD)
 
    which provides a entropy source for the whole system.  It is written
-   in Perl and available at the GnuPG FTP servers.  To enable EGD you
-   should rerun configure with the option "--enable-static-rnd=egd".
-   For more information consult the GnuPG webpages:
+   in Perl and available at the GnuPG FTP servers.  For more information
+   consult the GnuPG site:
 
-             http://www.gnupg.org/download.html#egd
+          https://gnupg.org/related_software/swlist.html#egd
 
 G10EOF
 fi
 
 if test "$gcry_cv_gcc_attribute_aligned" != "yes" ; then
 cat <<G10EOF
-
    Please not that your compiler does not support the GCC style
    aligned attribute. Using this software may evoke bus errors.
 
@@ -21188,4 +21420,5 @@ if test -n "$gpl"; then
   echo "  $gpl"
   echo "included.  These parts are licensed under the GPL and thus the"
   echo "use of this library has to comply with the conditions of the GPL."
+  echo ""
 fi
index b08c181..d0c7f9c 100644 (file)
@@ -1,7 +1,7 @@
 # Configure.ac script for Libgcrypt
 # Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006,
 #               2007, 2008, 2009, 2011 Free Software Foundation, Inc.
-# Copyright (C) 2012, 2013  g10 Code GmbH
+# Copyright (C) 2012, 2013, 2014, 2015, 2016  g10 Code GmbH
 #
 # This file is part of Libgcrypt.
 #
@@ -21,7 +21,7 @@
 # (Process this file with autoconf to produce a configure script.)
 AC_REVISION($Revision$)
 AC_PREREQ(2.60)
-min_automake_version="1.10"
+min_automake_version="1.14"
 
 # To build a release you need to create a tag with the version number
 # (git tag -s libgcrypt-n.m.k) and run "./autogen.sh --force".  Please
@@ -29,8 +29,8 @@ min_automake_version="1.10"
 # commit and push so that the git magic is able to work.  See below
 # for the LT versions.
 m4_define(mym4_version_major, [1])
-m4_define(mym4_version_minor, [6])
-m4_define(mym4_version_micro, [2])
+m4_define(mym4_version_minor, [7])
+m4_define(mym4_version_micro, [1])
 
 # Below is m4 magic to extract and compute the revision number, the
 # decimalized short revision number, a beta version string, and a flag
@@ -54,9 +54,9 @@ AC_INIT([libgcrypt],[mym4_full_version],[http://bugs.gnupg.org])
 #   (Interfaces removed:    CURRENT++, AGE=0, REVISION=0)
 #   (Interfaces added:      CURRENT++, AGE++, REVISION=0)
 #   (No interfaces changed:                   REVISION++)
-LIBGCRYPT_LT_CURRENT=20
-LIBGCRYPT_LT_AGE=0
-LIBGCRYPT_LT_REVISION=2
+LIBGCRYPT_LT_CURRENT=21
+LIBGCRYPT_LT_AGE=1
+LIBGCRYPT_LT_REVISION=1
 
 
 # If the API is changed in an incompatible way: increment the next counter.
@@ -67,14 +67,14 @@ LIBGCRYPT_CONFIG_API_VERSION=1
 
 # If you change the required gpg-error version, please remove
 # unnecessary error code defines in src/gcrypt-int.h.
-NEED_GPG_ERROR_VERSION=1.11
+NEED_GPG_ERROR_VERSION=1.13
 
 PACKAGE=$PACKAGE_NAME
 VERSION=$PACKAGE_VERSION
 
 AC_CONFIG_AUX_DIR([build-aux])
 AC_CONFIG_SRCDIR([src/libgcrypt.vers])
-AM_INIT_AUTOMAKE
+AM_INIT_AUTOMAKE([serial-tests dist-bzip2])
 AC_CONFIG_HEADER(config.h)
 AC_CONFIG_MACRO_DIR([m4])
 AC_CONFIG_LIBOBJ_DIR([compat])
@@ -82,6 +82,8 @@ AC_CANONICAL_HOST
 AM_MAINTAINER_MODE
 AM_SILENT_RULES
 
+AC_ARG_VAR(SYSROOT,[locate config scripts also below that directory])
+
 AH_TOP([
 #ifndef _GCRYPT_CONFIG_H_INCLUDED
 #define _GCRYPT_CONFIG_H_INCLUDED
@@ -186,7 +188,7 @@ LIBGCRYPT_CONFIG_HOST="$host"
 
 # Definitions for symmetric ciphers.
 available_ciphers="arcfour blowfish cast5 des aes twofish serpent rfc2268 seed"
-available_ciphers="$available_ciphers camellia idea salsa20 gost28147"
+available_ciphers="$available_ciphers camellia idea salsa20 gost28147 chacha20"
 enabled_ciphers=""
 
 # Definitions for public-key ciphers.
@@ -194,13 +196,12 @@ available_pubkey_ciphers="dsa elgamal rsa ecc"
 enabled_pubkey_ciphers=""
 
 # Definitions for message digests.
-available_digests="crc gostr3411-94 md4 md5 rmd160 sha1 sha256"
-available_digests_64="sha512 tiger whirlpool stribog"
+available_digests="crc gostr3411-94 md2 md4 md5 rmd160 sha1 sha256"
+available_digests="$available_digests sha512 sha3 tiger whirlpool stribog"
 enabled_digests=""
 
 # Definitions for kdfs (optional ones)
-available_kdfs="s2k pkdf2"
-available_kdfs_64="scrypt"
+available_kdfs="s2k pkdf2 scrypt"
 enabled_kdfs=""
 
 # Definitions for random modules.
@@ -341,6 +342,7 @@ AC_CHECK_SIZEOF(unsigned short, 2)
 AC_CHECK_SIZEOF(unsigned int, 4)
 AC_CHECK_SIZEOF(unsigned long, 4)
 AC_CHECK_SIZEOF(unsigned long long, 0)
+AC_CHECK_SIZEOF(void *, 0)
 
 AC_TYPE_UINTPTR_T
 
@@ -350,24 +352,36 @@ if test "$ac_cv_sizeof_unsigned_short" = "0" \
     AC_MSG_WARN([Hmmm, something is wrong with the sizes - using defaults]);
 fi
 
+# Ensure that we have UINT64_C before we bother to check for uint64_t
+AC_CACHE_CHECK([for UINT64_C],[gnupg_cv_uint64_c_works],
+   AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <inttypes.h>]],
+       [[uint64_t foo=UINT64_C(42);]])],
+     gnupg_cv_uint64_c_works=yes,gnupg_cv_uint64_c_works=no))
+if test "$gnupg_cv_uint64_c_works" = "yes" ; then
+   AC_CHECK_SIZEOF(uint64_t)
+fi
+
 # Do we have any 64-bit data types?
 if test "$ac_cv_sizeof_unsigned_int" != "8" \
    && test "$ac_cv_sizeof_unsigned_long" != "8" \
    && test "$ac_cv_sizeof_unsigned_long_long" != "8" \
    && test "$ac_cv_sizeof_uint64_t" != "8"; then
-    AC_MSG_WARN([No 64-bit types.  Disabling TIGER/192, SCRYPT, SHA-384, \
- SHA-512 and GOST R 34.11-12])
-else
-  available_digests="$available_digests $available_digests_64"
-  available_kdfs="$available_kdfs $available_kdfs_64"
+    AC_MSG_ERROR([[
+***
+*** No 64-bit integer type available.
+*** It is not possible to build Libgcrypt on this platform.
+***]])
 fi
 
+
 # If not specified otherwise, all available algorithms will be
 # included.
 default_ciphers="$available_ciphers"
 default_pubkey_ciphers="$available_pubkey_ciphers"
 default_digests="$available_digests"
 default_kdfs="$available_kdfs"
+# Blacklist MD2 by default
+default_digests=`echo $default_digests | sed -e 's/md2//g'`
 
 # Substitutions to set generated files in a Emacs buffer to read-only.
 AC_SUBST(emacs_local_vars_begin, ['Local Variables:'])
@@ -440,7 +454,7 @@ AC_MSG_RESULT([$enabled_digests])
 
 # Implementation of the --enable-kdfs switch.
 AC_ARG_ENABLE(kdfs,
-      AC_HELP_STRING([--enable-kdfs=kdfs],
+      AC_HELP_STRING([--enable-kfds=kdfs],
                     [select the KDFs to include]),
       [enabled_kdfs=`echo $enableval | tr ',:' '  ' | tr '[A-Z]' '[a-z]'`],
       [enabled_kdfs=""])
@@ -583,6 +597,14 @@ AC_ARG_ENABLE(pclmul-support,
              pclmulsupport=$enableval,pclmulsupport=yes)
 AC_MSG_RESULT($pclmulsupport)
 
+# Implementation of the --disable-sse41-support switch.
+AC_MSG_CHECKING([whether SSE4.1 support is requested])
+AC_ARG_ENABLE(sse41-support,
+              AC_HELP_STRING([--disable-sse41-support],
+                 [Disable support for the Intel SSE4.1 instructions]),
+             sse41support=$enableval,sse41support=yes)
+AC_MSG_RESULT($sse41support)
+
 # Implementation of the --disable-drng-support switch.
 AC_MSG_CHECKING([whether DRNG support is requested])
 AC_ARG_ENABLE(drng-support,
@@ -717,25 +739,14 @@ fi
 AC_SUBST(PTH_CFLAGS)
 AC_SUBST(PTH_LIBS)
 
-
 #
-# See which thread system we have
+# Check whether pthreads is available
 #
-# Windows has always thread support; thus we don't bother to test for
-# it as it may lead to false results when cross building.
-if test "$have_w32_system" = yes; then
-  AC_DEFINE([USE_WINDOWS_THREADS], [1])
-  LIBTHREAD=
-  LTLIBTHREAD=
-  LIBMULTITHREAD=
-  LTLIBMULTITHREAD=
-  THREADLIB_CPPFLAGS=""
-  AC_SUBST([LIBTHREAD])
-  AC_SUBST([LTLIBTHREAD])
-  AC_SUBST([LIBMULTITHREAD])
-  AC_SUBST([LTLIBMULTITHREAD])
-else
-  gl_LOCK
+if test "$have_w32_system" != yes; then
+  AC_CHECK_LIB(pthread,pthread_create,have_pthread=yes)
+  if test "$have_pthread" = yes; then
+    AC_DEFINE(HAVE_PTHREAD, 1 ,[Define if we have pthread.])
+  fi
 fi
 
 
@@ -824,6 +835,21 @@ fi
 
 
 #
+# Check for __builtin_ctz intrinsic.
+#
+AC_CACHE_CHECK(for __builtin_ctz,
+       [gcry_cv_have_builtin_ctz],
+       [gcry_cv_have_builtin_ctz=no
+        AC_LINK_IFELSE([AC_LANG_PROGRAM([],
+          [unsigned int x = 0; int y = __builtin_ctz(x); return y;])],
+          [gcry_cv_have_builtin_ctz=yes])])
+if test "$gcry_cv_have_builtin_ctz" = "yes" ; then
+   AC_DEFINE(HAVE_BUILTIN_CTZ, 1,
+             [Defined if compiler has '__builtin_ctz' intrinsic])
+fi
+
+
+#
 # Check for VLA support (variable length arrays).
 #
 AC_CACHE_CHECK(whether the variable length arrays are supported,
@@ -940,6 +966,26 @@ fi
 
 
 #
+# Check whether the compiler supports the GCC style packed attribute
+#
+AC_CACHE_CHECK([whether the GCC style packed attribute is supported],
+       [gcry_cv_gcc_attribute_packed],
+       [gcry_cv_gcc_attribute_packed=no
+        AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+          [[struct foolong_s { long b; } __attribute__ ((packed));
+            struct foo_s { char a; struct foolong_s b; }
+              __attribute__ ((packed));
+            enum bar {
+              FOO = 1 / (sizeof(struct foo_s) == (sizeof(char) + sizeof(long))),
+            };]])],
+          [gcry_cv_gcc_attribute_packed=yes])])
+if test "$gcry_cv_gcc_attribute_packed" = "yes" ; then
+   AC_DEFINE(HAVE_GCC_ATTRIBUTE_PACKED,1,
+     [Defined if a GCC style "__attribute__ ((packed))" is supported])
+fi
+
+
+#
 # Check whether the compiler supports 'asm' or '__asm__' keyword for
 # assembler blocks.
 #
@@ -1071,6 +1117,7 @@ AM_CONDITIONAL(MPI_MOD_C_UDIV_QRNND, test "$mpi_mod_c_udiv_qrnnd" = yes)
 if test "$mpi_cpu_arch" != "x86" ; then
    aesnisupport="n/a"
    pclmulsupport="n/a"
+   sse41support="n/a"
    avxsupport="n/a"
    avx2support="n/a"
    padlocksupport="n/a"
@@ -1088,6 +1135,93 @@ fi
 ####                                     ####
 #############################################
 
+
+# Following tests depend on warnings to cause compile to fail, so set -Werror
+# temporarily.
+_gcc_cflags_save=$CFLAGS
+CFLAGS="$CFLAGS -Werror"
+
+
+#
+# Check whether compiler supports 'ms_abi' function attribute.
+#
+AC_CACHE_CHECK([whether compiler supports 'ms_abi' function attribute],
+       [gcry_cv_gcc_attribute_ms_abi],
+       [gcry_cv_gcc_attribute_ms_abi=no
+        AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+          [[int __attribute__ ((ms_abi)) proto(int);]])],
+          [gcry_cv_gcc_attribute_ms_abi=yes])])
+if test "$gcry_cv_gcc_attribute_ms_abi" = "yes" ; then
+   AC_DEFINE(HAVE_GCC_ATTRIBUTE_MS_ABI,1,
+     [Defined if compiler supports "__attribute__ ((ms_abi))" function attribute])
+fi
+
+
+#
+# Check whether compiler supports 'sysv_abi' function attribute.
+#
+AC_CACHE_CHECK([whether compiler supports 'sysv_abi' function attribute],
+       [gcry_cv_gcc_attribute_sysv_abi],
+       [gcry_cv_gcc_attribute_sysv_abi=no
+        AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+          [[int __attribute__ ((sysv_abi)) proto(int);]])],
+          [gcry_cv_gcc_attribute_sysv_abi=yes])])
+if test "$gcry_cv_gcc_attribute_sysv_abi" = "yes" ; then
+   AC_DEFINE(HAVE_GCC_ATTRIBUTE_SYSV_ABI,1,
+     [Defined if compiler supports "__attribute__ ((sysv_abi))" function attribute])
+fi
+
+
+#
+# Check whether default calling convention is 'ms_abi'.
+#
+if test "$gcry_cv_gcc_attribute_ms_abi" = "yes" ; then
+   AC_CACHE_CHECK([whether default calling convention is 'ms_abi'],
+          [gcry_cv_gcc_default_abi_is_ms_abi],
+          [gcry_cv_gcc_default_abi_is_ms_abi=no
+           AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+             [[void *test(void) {
+                 void *(*def_func)(void) = test;
+                 void *__attribute__((ms_abi))(*msabi_func)(void);
+                 /* warning on SysV abi targets, passes on Windows based targets */
+                 msabi_func = def_func;
+                 return msabi_func;
+             }]])],
+             [gcry_cv_gcc_default_abi_is_ms_abi=yes])])
+   if test "$gcry_cv_gcc_default_abi_is_ms_abi" = "yes" ; then
+      AC_DEFINE(HAVE_GCC_DEFAULT_ABI_IS_MS_ABI,1,
+        [Defined if default calling convention is 'ms_abi'])
+   fi
+fi
+
+
+#
+# Check whether default calling convention is 'sysv_abi'.
+#
+if test "$gcry_cv_gcc_attribute_sysv_abi" = "yes" ; then
+   AC_CACHE_CHECK([whether default calling convention is 'sysv_abi'],
+          [gcry_cv_gcc_default_abi_is_sysv_abi],
+          [gcry_cv_gcc_default_abi_is_sysv_abi=no
+           AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+             [[void *test(void) {
+                 void *(*def_func)(void) = test;
+                 void *__attribute__((sysv_abi))(*sysvabi_func)(void);
+                 /* warning on MS ABI targets, passes on SysV ABI targets */
+                 sysvabi_func = def_func;
+                 return sysvabi_func;
+             }]])],
+             [gcry_cv_gcc_default_abi_is_sysv_abi=yes])])
+   if test "$gcry_cv_gcc_default_abi_is_sysv_abi" = "yes" ; then
+      AC_DEFINE(HAVE_GCC_DEFAULT_ABI_IS_SYSV_ABI,1,
+        [Defined if default calling convention is 'sysv_abi'])
+   fi
+fi
+
+
+# Restore flags.
+CFLAGS=$_gcc_cflags_save;
+
+
 #
 # Check whether GCC inline assembler supports SSSE3 instructions
 # This is required for the AES-NI instructions.
@@ -1132,6 +1266,27 @@ if test "$gcry_cv_gcc_inline_asm_pclmul" = "yes" ; then
      [Defined if inline assembler supports PCLMUL instructions])
 fi
 
+#
+# Check whether GCC inline assembler supports SSE4.1 instructions.
+#
+AC_CACHE_CHECK([whether GCC inline assembler supports SSE4.1 instructions],
+       [gcry_cv_gcc_inline_asm_sse41],
+       [if test "$mpi_cpu_arch" != "x86" ; then
+          gcry_cv_gcc_inline_asm_sse41="n/a"
+        else
+          gcry_cv_gcc_inline_asm_sse41=no
+          AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+          [[void a(void) {
+              int i;
+              __asm__("pextrd \$2, %%xmm0, %[out]\n\t" : [out] "=m" (i));
+            }]])],
+          [gcry_cv_gcc_inline_asm_sse41=yes])
+        fi])
+if test "$gcry_cv_gcc_inline_asm_sse41" = "yes" ; then
+   AC_DEFINE(HAVE_GCC_INLINE_ASM_SSE41,1,
+     [Defined if inline assembler supports SSE4.1 instructions])
+fi
+
 
 #
 # Check whether GCC inline assembler supports AVX instructions
@@ -1197,11 +1352,42 @@ fi
 
 
 #
+# Check whether GCC assembler needs "-Wa,--divide" to correctly handle
+# constant division
+#
+if test $amd64_as_feature_detection = yes; then
+  AC_CACHE_CHECK([whether GCC assembler handles division correctly],
+       [gcry_cv_gcc_as_const_division_ok],
+       [gcry_cv_gcc_as_const_division_ok=no
+        AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+          [[__asm__("xorl \$(123456789/12345678), %ebp;\n\t");]])],
+          [gcry_cv_gcc_as_const_division_ok=yes])])
+  if test "$gcry_cv_gcc_as_const_division_ok" = "no" ; then
+    #
+    # Add '-Wa,--divide' to CPPFLAGS and try check again.
+    #
+    _gcc_cppflags_save="$CPPFLAGS"
+    CPPFLAGS="$CPPFLAGS -Wa,--divide"
+    AC_CACHE_CHECK([whether GCC assembler handles division correctly with "-Wa,--divide"],
+         [gcry_cv_gcc_as_const_division_with_wadivide_ok],
+         [gcry_cv_gcc_as_const_division_with_wadivide_ok=no
+          AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+            [[__asm__("xorl \$(123456789/12345678), %ebp;\n\t");]])],
+            [gcry_cv_gcc_as_const_division_with_wadivide_ok=yes])])
+    if test "$gcry_cv_gcc_as_const_division_with_wadivide_ok" = "no" ; then
+      # '-Wa,--divide' did not work, restore old flags.
+      CPPFLAGS="$_gcc_cppflags_save"
+    fi
+  fi
+fi
+
+
+#
 # Check whether GCC assembler supports features needed for our amd64
 # implementations
 #
 if test $amd64_as_feature_detection = yes; then
-    AC_CACHE_CHECK([whether GCC assembler is compatible for amd64 assembly implementations],
+  AC_CACHE_CHECK([whether GCC assembler is compatible for amd64 assembly implementations],
        [gcry_cv_gcc_amd64_platform_as_ok],
        [if test "$mpi_cpu_arch" != "x86" ; then
           gcry_cv_gcc_amd64_platform_as_ok="n/a"
@@ -1211,12 +1397,14 @@ if test $amd64_as_feature_detection = yes; then
           [[__asm__(
                 /* Test if '.type' and '.size' are supported.  */
                 /* These work only on ELF targets. */
-               /* TODO: add COFF (mingw64, cygwin64) support to assembly
-                 * implementations.  Mingw64/cygwin64 also require additional
-                 * work because they use different calling convention. */
                "asmfunc:\n\t"
                 ".size asmfunc,.-asmfunc;\n\t"
                 ".type asmfunc,@function;\n\t"
+               /* Test if assembler allows use of '/' for constant division
+                * (Solaris/x86 issue). If previous constant division check
+                * and "-Wa,--divide" workaround failed, this causes assembly
+                * to be disable on this machine. */
+               "xorl \$(123456789/12345678), %ebp;\n\t"
             );]])],
           [gcry_cv_gcc_amd64_platform_as_ok=yes])
         fi])
@@ -1224,6 +1412,24 @@ if test $amd64_as_feature_detection = yes; then
      AC_DEFINE(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS,1,
               [Defined if underlying assembler is compatible with amd64 assembly implementations])
   fi
+  if test "$gcry_cv_gcc_amd64_platform_as_ok" = "no" &&
+     test "$gcry_cv_gcc_attribute_sysv_abi" = "yes" &&
+     test "$gcry_cv_gcc_default_abi_is_ms_abi" = "yes"; then
+    AC_CACHE_CHECK([whether GCC assembler is compatible for WIN64 assembly implementations],
+      [gcry_cv_gcc_win64_platform_as_ok],
+      [gcry_cv_gcc_win64_platform_as_ok=no
+      AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+        [[__asm__(
+              ".globl asmfunc\n\t"
+              "asmfunc:\n\t"
+              "xorq \$(1234), %rbp;\n\t"
+          );]])],
+        [gcry_cv_gcc_win64_platform_as_ok=yes])])
+    if test "$gcry_cv_gcc_win64_platform_as_ok" = "yes" ; then
+      AC_DEFINE(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS,1,
+                [Defined if underlying assembler is compatible with WIN64 assembly implementations])
+    fi
+  fi
 fi
 
 
@@ -1310,7 +1516,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports NEON instructions],
           AC_COMPILE_IFELSE([AC_LANG_SOURCE(
           [[__asm__(
                 ".syntax unified\n\t"
-                ".thumb\n\t"
+                ".arm\n\t"
                 ".fpu neon\n\t"
                 "vld1.64 {%q0-%q1}, [%r0]!;\n\t"
                 "vrev64.8 %q0, %q3;\n\t"
@@ -1338,7 +1544,7 @@ AC_CHECK_FUNCS(strtoul memmove stricmp atexit raise)
 # Other checks
 AC_CHECK_FUNCS(strerror rand mmap getpagesize sysconf waitpid wait4)
 AC_CHECK_FUNCS(gettimeofday getrusage gethrtime clock_gettime syslog)
-AC_CHECK_FUNCS(fcntl ftruncate flockfile)
+AC_CHECK_FUNCS(syscall fcntl ftruncate flockfile)
 
 GNUPG_CHECK_MLOCK
 
@@ -1362,13 +1568,6 @@ if test "$use_hmac_binary_check" = yes ; then
 fi
 AC_SUBST(DL_LIBS)
 
-#
-# Check whether we need to link with a pthreads library.
-#
-if test "x$LIBTHREAD" != x; then
-  LIBGCRYPT_CONFIG_LIBS="${LIBGCRYPT_CONFIG_LIBS} ${LIBTHREAD}"
-fi
-
 
 #
 # Check whether we can use Linux capabilities as requested.
@@ -1542,6 +1741,11 @@ if test x"$pclmulsupport" = xyes ; then
     pclmulsupport="no (unsupported by compiler)"
   fi
 fi
+if test x"$sse41support" = xyes ; then
+  if test "$gcry_cv_gcc_inline_asm_sse41" != "yes" ; then
+    sse41support="no (unsupported by compiler)"
+  fi
+fi
 if test x"$avxsupport" = xyes ; then
   if test "$gcry_cv_gcc_inline_asm_avx" != "yes" ; then
     avxsupport="no (unsupported by compiler)"
@@ -1566,6 +1770,10 @@ if test x"$pclmulsupport" = xyes ; then
   AC_DEFINE(ENABLE_PCLMUL_SUPPORT, 1,
             [Enable support for Intel PCLMUL instructions.])
 fi
+if test x"$sse41support" = xyes ; then
+  AC_DEFINE(ENABLE_SSE41_SUPPORT, 1,
+            [Enable support for Intel SSE4.1 instructions.])
+fi
 if test x"$avxsupport" = xyes ; then
   AC_DEFINE(ENABLE_AVX_SUPPORT,1,
             [Enable support for Intel AVX instructions.])
@@ -1595,6 +1803,13 @@ LIST_MEMBER(arcfour, $enabled_ciphers)
 if test "$found" = "1"; then
    GCRYPT_CIPHERS="$GCRYPT_CIPHERS arcfour.lo"
    AC_DEFINE(USE_ARCFOUR, 1, [Defined if this module should be included])
+
+   case "${host}" in
+      x86_64-*-*)
+         # Build with the assembly implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS arcfour-amd64.lo"
+      ;;
+   esac
 fi
 
 LIST_MEMBER(blowfish, $enabled_ciphers)
@@ -1635,6 +1850,13 @@ LIST_MEMBER(des, $enabled_ciphers)
 if test "$found" = "1" ; then
    GCRYPT_CIPHERS="$GCRYPT_CIPHERS des.lo"
    AC_DEFINE(USE_DES, 1, [Defined if this module should be included])
+
+   case "${host}" in
+      x86_64-*-*)
+         # Build with the assembly implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS des-amd64.lo"
+      ;;
+   esac
 fi
 
 LIST_MEMBER(aes, $enabled_ciphers)
@@ -1646,12 +1868,25 @@ if test "$found" = "1" ; then
       x86_64-*-*)
          # Build with the assembly implementation
          GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-amd64.lo"
+
+         # Build with the SSSE3 implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-ssse3-amd64.lo"
       ;;
       arm*-*-*)
          # Build with the assembly implementation
          GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-arm.lo"
       ;;
    esac
+
+   case "$mpi_cpu_arch" in
+     x86)
+         # Build with the AES-NI implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-aesni.lo"
+
+         # Build with the Padlock implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-padlock.lo"
+      ;;
+   esac
 fi
 
 LIST_MEMBER(twofish, $enabled_ciphers)
@@ -1763,6 +1998,39 @@ if test "$found" = "1" ; then
    AC_DEFINE(USE_GOST28147, 1, [Defined if this module should be included])
 fi
 
+LIST_MEMBER(chacha20, $enabled_ciphers)
+if test "$found" = "1" ; then
+   GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20.lo"
+   AC_DEFINE(USE_CHACHA20, 1, [Defined if this module should be included])
+
+   case "${host}" in
+      x86_64-*-*)
+         # Build with the assembly implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20-sse2-amd64.lo"
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20-ssse3-amd64.lo"
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20-avx2-amd64.lo"
+      ;;
+   esac
+
+   if test x"$neonsupport" = xyes ; then
+     # Build with the NEON implementation
+     GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20-armv7-neon.lo"
+   fi
+fi
+
+case "${host}" in
+   x86_64-*-*)
+      # Build with the assembly implementation
+      GCRYPT_CIPHERS="$GCRYPT_CIPHERS poly1305-sse2-amd64.lo"
+      GCRYPT_CIPHERS="$GCRYPT_CIPHERS poly1305-avx2-amd64.lo"
+   ;;
+esac
+
+if test x"$neonsupport" = xyes ; then
+   # Build with the NEON implementation
+   GCRYPT_CIPHERS="$GCRYPT_CIPHERS poly1305-armv7-neon.lo"
+fi
+
 LIST_MEMBER(dsa, $enabled_pubkey_ciphers)
 if test "$found" = "1" ; then
    GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS dsa.lo"
@@ -1793,6 +2061,13 @@ LIST_MEMBER(crc, $enabled_digests)
 if test "$found" = "1" ; then
    GCRYPT_DIGESTS="$GCRYPT_DIGESTS crc.lo"
    AC_DEFINE(USE_CRC, 1, [Defined if this module should be included])
+
+   case "${host}" in
+      i?86-*-* | x86_64-*-*)
+         # Build with the assembly implementation
+         GCRYPT_DIGESTS="$GCRYPT_DIGESTS crc-intel-pclmul.lo"
+      ;;
+   esac
 fi
 
 LIST_MEMBER(gostr3411-94, $enabled_digests)
@@ -1811,6 +2086,12 @@ if test "$found" = "1" ; then
    AC_DEFINE(USE_GOST_R_3411_12, 1, [Defined if this module should be included])
 fi
 
+LIST_MEMBER(md2, $enabled_digests)
+if test "$found" = "1" ; then
+   GCRYPT_DIGESTS="$GCRYPT_DIGESTS md2.lo"
+   AC_DEFINE(USE_MD2, 1, [Defined if this module should be included])
+fi
+
 LIST_MEMBER(md4, $enabled_digests)
 if test "$found" = "1" ; then
    GCRYPT_DIGESTS="$GCRYPT_DIGESTS md4.lo"
@@ -1823,6 +2104,12 @@ if test "$found" = "1" ; then
    AC_DEFINE(USE_MD5, 1, [Defined if this module should be included])
 fi
 
+LIST_MEMBER(rmd160, $enabled_digests)
+if test "$found" = "1" ; then
+   GCRYPT_DIGESTS="$GCRYPT_DIGESTS rmd160.lo"
+   AC_DEFINE(USE_RMD160, 1, [Defined if this module should be included])
+fi
+
 LIST_MEMBER(sha256, $enabled_digests)
 if test "$found" = "1" ; then
    GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256.lo"
@@ -1832,6 +2119,8 @@ if test "$found" = "1" ; then
       x86_64-*-*)
          # Build with the assembly implementation
          GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256-ssse3-amd64.lo"
+         GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256-avx-amd64.lo"
+         GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256-avx2-bmi2-amd64.lo"
       ;;
    esac
 fi
@@ -1848,6 +2137,10 @@ if test "$found" = "1" ; then
          GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-avx-amd64.lo"
          GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-avx2-bmi2-amd64.lo"
       ;;
+      arm*-*-*)
+         # Build with the assembly implementation
+         GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-arm.lo"
+      ;;
    esac
 
    if test x"$neonsupport" = xyes ; then
@@ -1856,6 +2149,24 @@ if test "$found" = "1" ; then
    fi
 fi
 
+LIST_MEMBER(sha3, $enabled_digests)
+if test "$found" = "1" ; then
+   GCRYPT_DIGESTS="$GCRYPT_DIGESTS keccak.lo"
+   AC_DEFINE(USE_SHA3, 1, [Defined if this module should be included])
+
+   case "${host}" in
+      x86_64-*-*)
+         # Build with the assembly implementation
+         :
+      ;;
+   esac
+
+   if test x"$neonsupport" = xyes ; then
+     # Build with the NEON implementation
+     GCRYPT_DIGESTS="$GCRYPT_DIGESTS keccak-armv7-neon.lo"
+   fi
+fi
+
 LIST_MEMBER(tiger, $enabled_digests)
 if test "$found" = "1" ; then
    GCRYPT_DIGESTS="$GCRYPT_DIGESTS tiger.lo"
@@ -1866,17 +2177,30 @@ 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-sse2-amd64.lo"
+      ;;
+   esac
 fi
 
-# rmd160 and sha1 should be included always.
-GCRYPT_DIGESTS="$GCRYPT_DIGESTS rmd160.lo sha1.lo"
-AC_DEFINE(USE_RMD160, 1, [Defined if this module should be included])
+# SHA-1 needs to be included always for example because it is used by
+# random-csprng.c.
+GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1.lo"
 AC_DEFINE(USE_SHA1, 1,   [Defined if this module should be included])
 
 case "${host}" in
   x86_64-*-*)
     # Build with the assembly implementation
     GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1-ssse3-amd64.lo"
+    GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1-avx-amd64.lo"
+    GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1-avx-bmi2-amd64.lo"
+  ;;
+  arm*-*-*)
+    # Build with the assembly implementation
+    GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1-armv7-neon.lo"
   ;;
 esac
 
@@ -1980,6 +2304,16 @@ AC_SUBST([GCRYPT_HWF_MODULES])
 
 
 #
+# Option to disable building of doc file
+#
+build_doc=yes
+AC_ARG_ENABLE([doc], AC_HELP_STRING([--disable-doc],
+                                    [do not build the documentation]),
+                     build_doc=$enableval, build_doc=yes)
+AM_CONDITIONAL([BUILD_DOC], [test "x$build_doc" != xno])
+
+
+#
 # Provide information about the build.
 #
 BUILD_REVISION="mym4_revision"
@@ -1993,7 +2327,16 @@ changequote([,])dnl
 BUILD_FILEVERSION="${BUILD_FILEVERSION}mym4_revision_dec"
 AC_SUBST(BUILD_FILEVERSION)
 
-BUILD_TIMESTAMP=`date -u +%Y-%m-%dT%H:%M+0000 2>/dev/null || date`
+AC_ARG_ENABLE([build-timestamp],
+  AC_HELP_STRING([--enable-build-timestamp],
+                 [set an explicit build timestamp for reproducibility.
+                  (default is the current time in ISO-8601 format)]),
+     [if test "$enableval" = "yes"; then
+        BUILD_TIMESTAMP=`date -u +%Y-%m-%dT%H:%M+0000 2>/dev/null || date`
+      else
+        BUILD_TIMESTAMP="$enableval"
+      fi],
+     [BUILD_TIMESTAMP="<none>"])
 AC_SUBST(BUILD_TIMESTAMP)
 AC_DEFINE_UNQUOTED(BUILD_TIMESTAMP, "$BUILD_TIMESTAMP",
                    [The time this package was configured for a build])
@@ -2036,15 +2379,24 @@ GCRY_MSG_SHOW([Using linux capabilities: ],[$use_capabilities])
 GCRY_MSG_SHOW([Try using Padlock crypto: ],[$padlocksupport])
 GCRY_MSG_SHOW([Try using AES-NI crypto:  ],[$aesnisupport])
 GCRY_MSG_SHOW([Try using Intel PCLMUL:   ],[$pclmulsupport])
+GCRY_MSG_SHOW([Try using Intel SSE4.1:   ],[$sse41support])
 GCRY_MSG_SHOW([Try using DRNG (RDRAND):  ],[$drngsupport])
 GCRY_MSG_SHOW([Try using Intel AVX:      ],[$avxsupport])
 GCRY_MSG_SHOW([Try using Intel AVX2:     ],[$avx2support])
 GCRY_MSG_SHOW([Try using ARM NEON:       ],[$neonsupport])
 GCRY_MSG_SHOW([],[])
 
-if test "$print_egd_notice" = "yes"; then
+if test "x${gpg_config_script_warn}" != x; then
 cat <<G10EOF
+        Mismatches between the target platform and the to
+        be used libraries have been been detected for:
+         ${gpg_config_script_warn}
+        Please check above for warning messages.
 
+G10EOF
+fi
+if test "$print_egd_notice" = "yes"; then
+cat <<G10EOF
    The performance of the Unix random gatherer module (rndunix) is not
    very good and it does not keep the entropy pool over multiple
    invocations of Libgcrypt base applications.  The suggested way to
@@ -2053,18 +2405,16 @@ cat <<G10EOF
                  Entropy Gathering Daemon (EGD)
 
    which provides a entropy source for the whole system.  It is written
-   in Perl and available at the GnuPG FTP servers.  To enable EGD you
-   should rerun configure with the option "--enable-static-rnd=egd".
-   For more information consult the GnuPG webpages:
+   in Perl and available at the GnuPG FTP servers.  For more information
+   consult the GnuPG site:
 
-             http://www.gnupg.org/download.html#egd
+          https://gnupg.org/related_software/swlist.html#egd
 
 G10EOF
 fi
 
 if test "$gcry_cv_gcc_attribute_aligned" != "yes" ; then
 cat <<G10EOF
-
    Please not that your compiler does not support the GCC style
    aligned attribute. Using this software may evoke bus errors.
 
@@ -2076,4 +2426,5 @@ if test -n "$gpl"; then
   echo "  $gpl"
   echo "included.  These parts are licensed under the GPL and thus the"
   echo "use of this library has to comply with the conditions of the GPL."
+  echo ""
 fi
index 30330bb..6a7cc8e 100644 (file)
@@ -83,7 +83,7 @@ $(myman_pages) : yat2m-stamp
 # Make sure that gcrypt.texi is touched if any other source file has
 # been modified.  This is required so that the version.texi magic
 # updates the release date.
-gnupg.texi : $(gcrypt_TEXINFOS)
+gcrypt.texi : $(gcrypt_TEXINFOS)
        touch $(srcdir)/gcrypt.texi
 
 online: gcrypt.html gcrypt.pdf gcrypt.info
index 08ef3e8..89c3b30 100644 (file)
@@ -1,9 +1,8 @@
-# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
-# Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 # License along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 VPATH = @srcdir@
-am__make_dryrun = \
-  { \
-    am__dry=no; \
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
     case $$MAKEFLAGS in \
       *\\[\ \  ]*) \
-        echo 'am--echo: ; @echo "AM"  OK' | $(MAKE) -f - 2>/dev/null \
-          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
-      *) \
-        for am__flg in $$MAKEFLAGS; do \
-          case $$am__flg in \
-            *=*|--*) ;; \
-            *n*) am__dry=yes; break;; \
-          esac; \
-        done;; \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs  ]*//g"`;; \
     esac; \
-    test $$am__dry = yes; \
-  }
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -69,32 +96,66 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = doc
-DIST_COMMON = $(gcrypt_TEXINFOS) $(srcdir)/Makefile.am \
-       $(srcdir)/Makefile.in $(srcdir)/stamp-vti \
-       $(srcdir)/version.texi
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+       $(gcrypt_TEXINFOS) $(top_srcdir)/build-aux/mdate-sh \
+       $(srcdir)/version.texi $(srcdir)/stamp-vti \
+       $(top_srcdir)/build-aux/texinfo.tex
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/gpg-error.m4 \
-       $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/lock.m4 \
-       $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
-       $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+       $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+       $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+       $(top_srcdir)/m4/lt~obsolete.m4 \
        $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \
        $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
-       $(top_srcdir)/m4/threadlib.m4 $(top_srcdir)/acinclude.m4 \
-       $(top_srcdir)/configure.ac
+       $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
 AM_V_GEN = $(am__v_GEN_@AM_V@)
 am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
-am__v_GEN_0 = @echo "  GEN   " $@;
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
 AM_V_at = $(am__v_at_@AM_V@)
 am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
 am__v_at_0 = @
+am__v_at_1 = 
 SOURCES =
 DIST_SOURCES =
+AM_V_DVIPS = $(am__v_DVIPS_@AM_V@)
+am__v_DVIPS_ = $(am__v_DVIPS_@AM_DEFAULT_V@)
+am__v_DVIPS_0 = @echo "  DVIPS   " $@;
+am__v_DVIPS_1 = 
+AM_V_MAKEINFO = $(am__v_MAKEINFO_@AM_V@)
+am__v_MAKEINFO_ = $(am__v_MAKEINFO_@AM_DEFAULT_V@)
+am__v_MAKEINFO_0 = @echo "  MAKEINFO" $@;
+am__v_MAKEINFO_1 = 
+AM_V_INFOHTML = $(am__v_INFOHTML_@AM_V@)
+am__v_INFOHTML_ = $(am__v_INFOHTML_@AM_DEFAULT_V@)
+am__v_INFOHTML_0 = @echo "  INFOHTML" $@;
+am__v_INFOHTML_1 = 
+AM_V_TEXI2DVI = $(am__v_TEXI2DVI_@AM_V@)
+am__v_TEXI2DVI_ = $(am__v_TEXI2DVI_@AM_DEFAULT_V@)
+am__v_TEXI2DVI_0 = @echo "  TEXI2DVI" $@;
+am__v_TEXI2DVI_1 = 
+AM_V_TEXI2PDF = $(am__v_TEXI2PDF_@AM_V@)
+am__v_TEXI2PDF_ = $(am__v_TEXI2PDF_@AM_DEFAULT_V@)
+am__v_TEXI2PDF_0 = @echo "  TEXI2PDF" $@;
+am__v_TEXI2PDF_1 = 
+AM_V_texinfo = $(am__v_texinfo_@AM_V@)
+am__v_texinfo_ = $(am__v_texinfo_@AM_DEFAULT_V@)
+am__v_texinfo_0 = -q
+am__v_texinfo_1 = 
+AM_V_texidevnull = $(am__v_texidevnull_@AM_V@)
+am__v_texidevnull_ = $(am__v_texidevnull_@AM_DEFAULT_V@)
+am__v_texidevnull_0 = > /dev/null
+am__v_texidevnull_1 = 
 INFO_DEPS = $(srcdir)/gcrypt.info
 TEXINFO_TEX = $(top_srcdir)/build-aux/texinfo.tex
 am__TEXINFO_TEX_DIR = $(top_srcdir)/build-aux
@@ -144,6 +205,7 @@ am__uninstall_files_from_dir = { \
 man1dir = $(mandir)/man1
 NROFF = nroff
 MANS = $(man_MANS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -189,6 +251,8 @@ GCRYPT_RANDOM = @GCRYPT_RANDOM@
 GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
 GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
 GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GPG_ERROR_MT_CFLAGS = @GPG_ERROR_MT_CFLAGS@
+GPG_ERROR_MT_LIBS = @GPG_ERROR_MT_LIBS@
 GREP = @GREP@
 INSERT_SYS_SELECT_H = @INSERT_SYS_SELECT_H@
 INSTALL = @INSTALL@
@@ -209,16 +273,12 @@ LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@
 LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@
 LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@
 LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@
-LIBMULTITHREAD = @LIBMULTITHREAD@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
-LIBTHREAD = @LIBTHREAD@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
-LTLIBMULTITHREAD = @LTLIBMULTITHREAD@
 LTLIBOBJS = @LTLIBOBJS@
-LTLIBTHREAD = @LTLIBTHREAD@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
@@ -249,6 +309,7 @@ SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
+SYSROOT = @SYSROOT@
 SYS_SOCKET_H = @SYS_SOCKET_H@
 VERSION = @VERSION@
 VERSION_NUMBER = @VERSION_NUMBER@
@@ -370,7 +431,7 @@ clean-libtool:
        -rm -rf .libs _libs
 
 .texi.info:
-       restore=: && backupdir="$(am__leading_dot)am$$$$" && \
+       $(AM_V_MAKEINFO)restore=: && backupdir="$(am__leading_dot)am$$$$" && \
        am__cwd=`pwd` && $(am__cd) $(srcdir) && \
        rm -rf $$backupdir && mkdir $$backupdir && \
        if ($(MAKEINFO) --version) >/dev/null 2>&1; then \
@@ -392,27 +453,25 @@ clean-libtool:
        rm -rf $$backupdir; exit $$rc
 
 .texi.dvi:
-       TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+       $(AM_V_TEXI2DVI)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
        MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
-       $(TEXI2DVI) $<
+       $(TEXI2DVI) $(AM_V_texinfo) --build-dir=$(@:.dvi=.t2d) -o $@ $(AM_V_texidevnull) \
+       $<
 
 .texi.pdf:
-       TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+       $(AM_V_TEXI2PDF)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
        MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
-       $(TEXI2PDF) $<
+       $(TEXI2PDF) $(AM_V_texinfo) --build-dir=$(@:.pdf=.t2p) -o $@ $(AM_V_texidevnull) \
+       $<
 
 .texi.html:
-       rm -rf $(@:.html=.htp)
-       if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+       $(AM_V_MAKEINFO)rm -rf $(@:.html=.htp)
+       $(AM_V_at)if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
         -o $(@:.html=.htp) $<; \
        then \
-         rm -rf $@; \
-         if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
-           mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \
+         rm -rf $@ && mv $(@:.html=.htp) $@; \
        else \
-         if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
-           rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \
-         exit 1; \
+         rm -rf $(@:.html=.htp); exit 1; \
        fi
 $(srcdir)/gcrypt.info: gcrypt.texi $(srcdir)/version.texi $(gcrypt_TEXINFOS)
 gcrypt.dvi: gcrypt.texi $(srcdir)/version.texi $(gcrypt_TEXINFOS)
@@ -438,8 +497,8 @@ mostlyclean-vti:
 maintainer-clean-vti:
 @MAINTAINER_MODE_TRUE@ -rm -f $(srcdir)/stamp-vti $(srcdir)/version.texi
 .dvi.ps:
-       TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
-       $(DVIPS) -o $@ $<
+       $(AM_V_DVIPS)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+       $(DVIPS) $(AM_V_texinfo) -o $@ $<
 
 uninstall-dvi-am:
        @$(NORMAL_UNINSTALL)
@@ -518,9 +577,7 @@ dist-info: $(INFO_DEPS)
        done
 
 mostlyclean-aminfo:
-       -rm -rf gcrypt.aux gcrypt.cp gcrypt.cps gcrypt.fn gcrypt.fns gcrypt.ky \
-         gcrypt.kys gcrypt.log gcrypt.pg gcrypt.tmp gcrypt.toc \
-         gcrypt.tp gcrypt.vr gcrypt.vrs
+       -rm -rf gcrypt.t2d gcrypt.t2p
 
 clean-aminfo:
        -test -z "gcrypt.dvi gcrypt.pdf gcrypt.ps gcrypt.html" \
@@ -575,27 +632,14 @@ uninstall-man1:
        } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
              -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
        dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir)
-tags: TAGS
-TAGS:
+tags TAGS:
 
-ctags: CTAGS
-CTAGS:
+ctags CTAGS:
+
+cscope cscopelist:
 
 
 distdir: $(DISTFILES)
-       @list='$(MANS)'; if test -n "$$list"; then \
-         list=`for p in $$list; do \
-           if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
-           if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \
-         if test -n "$$list" && \
-           grep 'ab help2man is required to generate this page' $$list >/dev/null; then \
-           echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \
-           grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/         /' >&2; \
-           echo "       to fix them, install help2man, remove and regenerate the man pages;" >&2; \
-           echo "       typically \`make maintainer-clean' will remove them" >&2; \
-           exit 1; \
-         else :; fi; \
-       else :; fi
        @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        list='$(DISTFILES)'; \
@@ -835,17 +879,18 @@ uninstall-man: uninstall-man1
 .MAKE: all check install install-am install-strip
 
 .PHONY: all all-am check check-am clean clean-aminfo clean-generic \
-       clean-libtool dist-info distclean distclean-generic \
-       distclean-libtool distdir dvi dvi-am html html-am info info-am \
-       install install-am install-data install-data-am install-dvi \
-       install-dvi-am install-exec install-exec-am install-html \
-       install-html-am install-info install-info-am install-man \
-       install-man1 install-pdf install-pdf-am install-ps \
-       install-ps-am install-strip installcheck installcheck-am \
-       installdirs maintainer-clean maintainer-clean-aminfo \
-       maintainer-clean-generic maintainer-clean-vti mostlyclean \
-       mostlyclean-aminfo mostlyclean-generic mostlyclean-libtool \
-       mostlyclean-vti pdf pdf-am ps ps-am uninstall uninstall-am \
+       clean-libtool cscopelist-am ctags-am dist-info distclean \
+       distclean-generic distclean-libtool distdir dvi dvi-am html \
+       html-am info info-am install install-am install-data \
+       install-data-am install-dvi install-dvi-am install-exec \
+       install-exec-am install-html install-html-am install-info \
+       install-info-am install-man install-man1 install-pdf \
+       install-pdf-am install-ps install-ps-am install-strip \
+       installcheck installcheck-am installdirs maintainer-clean \
+       maintainer-clean-aminfo maintainer-clean-generic \
+       maintainer-clean-vti mostlyclean mostlyclean-aminfo \
+       mostlyclean-generic mostlyclean-libtool mostlyclean-vti pdf \
+       pdf-am ps ps-am tags-am uninstall uninstall-am \
        uninstall-dvi-am uninstall-html-am uninstall-info-am \
        uninstall-man uninstall-man1 uninstall-pdf-am uninstall-ps-am
 
@@ -891,7 +936,7 @@ $(myman_pages) : yat2m-stamp
 # Make sure that gcrypt.texi is touched if any other source file has
 # been modified.  This is required so that the version.texi magic
 # updates the release date.
-gnupg.texi : $(gcrypt_TEXINFOS)
+gcrypt.texi : $(gcrypt_TEXINFOS)
        touch $(srcdir)/gcrypt.texi
 
 online: gcrypt.html gcrypt.pdf gcrypt.info
index 9006b13..d2475a6 100644 (file)
@@ -1,7 +1,7 @@
 %!PS-Adobe-3.0 EPSF-3.0
 %%Title: /home/wk/s/libgcrypt/doc/fips-fsm.fig
-%%Creator: fig2dev Version 3.2 Patchlevel 5d
-%%CreationDate: Wed Jan 29 11:42:20 2014
+%%Creator: fig2dev Version 3.2 Patchlevel 5e
+%%CreationDate: Tue Jan  6 19:07:13 2015
 %%BoundingBox: 0 0 497 579
 %Magnification: 1.0000
 %%EndComments
index 9e24e22..1ebd15b 100644 (file)
Binary files a/doc/fips-fsm.pdf and b/doc/fips-fsm.pdf differ
index 515072c..b4136af 100644 (file)
Binary files a/doc/fips-fsm.png and b/doc/fips-fsm.png differ
index 822b117..81fdb61 100644 (file)
-This is /home/wk/s/libgcrypt/doc/gcrypt.info, produced by makeinfo
-version 4.13 from /home/wk/s/libgcrypt/doc/gcrypt.texi.
+This is gcrypt.info, produced by makeinfo version 5.2 from gcrypt.texi.
 
-This manual is for Libgcrypt (version 1.6.2, 21 August 2014), which is
+This manual is for Libgcrypt (version 1.7.1, 15 June 2016), which is
 GNU's library of cryptographic building blocks.
 
-Copyright (C) 2000, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2011,
-2012 Free Software Foundation, Inc.
-Copyright (C) 2012, 2013 g10 Code GmbH
+Copyright (C) 2000, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2011, 2012
+Free Software Foundation, Inc.
+Copyright (C) 2012, 2013, 2016 g10 Code GmbH
 
      Permission is granted to copy, distribute and/or modify this
      document under the terms of the GNU General Public License as
      published by the Free Software Foundation; either version 2 of the
-     License, or (at your option) any later version. The text of the
+     License, or (at your option) any later version.  The text of the
      license can be found in the section entitled "GNU General Public
      License".
-
 INFO-DIR-SECTION GNU Libraries
 START-INFO-DIR-ENTRY
 * libgcrypt: (gcrypt).  Cryptographic function library.
 END-INFO-DIR-ENTRY
 
 \1f
-Indirect:
-gcrypt.info-1: 876
-gcrypt.info-2: 283506
+File: gcrypt.info,  Node: Top,  Next: Introduction,  Up: (dir)
+
+The Libgcrypt Library
+*********************
+
+This manual is for Libgcrypt (version 1.7.1, 15 June 2016), which is
+GNU's library of cryptographic building blocks.
+
+Copyright (C) 2000, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2011, 2012
+Free Software Foundation, Inc.
+Copyright (C) 2012, 2013, 2016 g10 Code GmbH
+
+     Permission is granted to copy, distribute and/or modify this
+     document under the terms of the GNU General Public License as
+     published by the Free Software Foundation; either version 2 of the
+     License, or (at your option) any later version.  The text of the
+     license can be found in the section entitled "GNU General Public
+     License".
+
+* Menu:
+
+* Introduction::                 What is Libgcrypt.
+* Preparation::                  What you should do before using the library.
+* Generalities::                 General library functions and data types.
+* Handler Functions::            Working with handler functions.
+* Symmetric cryptography::       How to use symmetric cryptography.
+* Public Key cryptography::      How to use public key cryptography.
+* Hashing::                      How to use hash algorithms.
+* Message Authentication Codes:: How to use MAC algorithms.
+* Key Derivation::               How to derive keys from strings
+* Random Numbers::               How to work with random numbers.
+* S-expressions::                How to manage S-expressions.
+* MPI library::                  How to work with multi-precision-integers.
+* Prime numbers::                How to use the Prime number related functions.
+* Utilities::                    Utility functions.
+* Tools::                        Utility tools.
+* Configuration::                Configuration files and evironment variables.
+* Architecture::                 How Libgcrypt works internally.
+
+Appendices
+
+* Self-Tests::                  Description of the self-tests.
+* FIPS Mode::                   Description of the FIPS mode.
+* Library Copying::             The GNU Lesser General Public License
+                                says how you can copy and share Libgcrypt.
+* Copying::                     The GNU General Public License says how you
+                                can copy and share some parts of Libgcrypt.
+
+Indices
+
+* Figures and Tables::          Index of figures and tables.
+* Concept Index::               Index of concepts and programs.
+* Function and Data Index::     Index of functions, variables and data types.
+
+\1f
+File: gcrypt.info,  Node: Introduction,  Next: Preparation,  Prev: Top,  Up: Top
+
+1 Introduction
+**************
+
+Libgcrypt is a library providing cryptographic building blocks.
+
+* Menu:
+
+* Getting Started::             How to use this manual.
+* Features::                    A glance at Libgcrypt's features.
+* Overview::                    Overview about the library.
+
+\1f
+File: gcrypt.info,  Node: Getting Started,  Next: Features,  Up: Introduction
+
+1.1 Getting Started
+===================
+
+This manual documents the Libgcrypt library application programming
+interface (API). All functions and data types provided by the library
+are explained.
+
+The reader is assumed to possess basic knowledge about applied
+cryptography.
+
+   This manual can be used in several ways.  If read from the beginning
+to the end, it gives a good introduction into the library and how it can
+be used in an application.  Forward references are included where
+necessary.  Later on, the manual can be used as a reference manual to
+get just the information needed about any particular interface of the
+library.  Experienced programmers might want to start looking at the
+examples at the end of the manual, and then only read up those parts of
+the interface which are unclear.
+
+\1f
+File: gcrypt.info,  Node: Features,  Next: Overview,  Prev: Getting Started,  Up: Introduction
+
+1.2 Features
+============
+
+Libgcrypt might have a couple of advantages over other libraries doing a
+similar job.
+
+It's Free Software
+     Anybody can use, modify, and redistribute it under the terms of the
+     GNU Lesser General Public License (*note Library Copying::).  Note,
+     that some parts (which are in general not needed by applications)
+     are subject to the terms of the GNU General Public License (*note
+     Copying::); please see the README file of the distribution for of
+     list of these parts.
+
+It encapsulates the low level cryptography
+     Libgcrypt provides a high level interface to cryptographic building
+     blocks using an extensible and flexible API.
+
+\1f
+File: gcrypt.info,  Node: Overview,  Prev: Features,  Up: Introduction
+
+1.3 Overview
+============
+
+The Libgcrypt library is fully thread-safe, where it makes sense to be
+thread-safe.  Not thread-safe are some cryptographic functions that
+modify a certain context stored in handles.  If the user really intents
+to use such functions from different threads on the same handle, he has
+to take care of the serialization of such functions himself.  If not
+described otherwise, every function is thread-safe.
+
+   Libgcrypt depends on the library 'libgpg-error', which contains some
+common code used by other GnuPG components.
+
+\1f
+File: gcrypt.info,  Node: Preparation,  Next: Generalities,  Prev: Introduction,  Up: Top
+
+2 Preparation
+*************
+
+To use Libgcrypt, you have to perform some changes to your sources and
+the build system.  The necessary changes are small and explained in the
+following sections.  At the end of this chapter, it is described how the
+library is initialized, and how the requirements of the library are
+verified.
+
+* Menu:
+
+* Header::                      What header file you need to include.
+* Building sources::            How to build sources using the library.
+* Building sources using Automake::  How to build sources with the help of Automake.
+* Initializing the library::    How to initialize the library.
+* Multi-Threading::             How Libgcrypt can be used in a MT environment.
+* Enabling FIPS mode::          How to enable the FIPS mode.
+* Hardware features::           How to disable hardware features.
+
+\1f
+File: gcrypt.info,  Node: Header,  Next: Building sources,  Up: Preparation
+
+2.1 Header
+==========
+
+All interfaces (data types and functions) of the library are defined in
+the header file 'gcrypt.h'.  You must include this in all source files
+using the library, either directly or through some other header file,
+like this:
+
+     #include <gcrypt.h>
+
+   The name space of Libgcrypt is 'gcry_*' for function and type names
+and 'GCRY*' for other symbols.  In addition the same name prefixes with
+one prepended underscore are reserved for internal use and should never
+be used by an application.  Note that Libgcrypt uses libgpg-error, which
+uses 'gpg_*' as name space for function and type names and 'GPG_*' for
+other symbols, including all the error codes.
+
+Certain parts of gcrypt.h may be excluded by defining these macros:
+
+'GCRYPT_NO_MPI_MACROS'
+     Do not define the shorthand macros 'mpi_*' for 'gcry_mpi_*'.
+
+'GCRYPT_NO_DEPRECATED'
+     Do not include definitions for deprecated features.  This is useful
+     to make sure that no deprecated features are used.
+
+\1f
+File: gcrypt.info,  Node: Building sources,  Next: Building sources using Automake,  Prev: Header,  Up: Preparation
+
+2.2 Building sources
+====================
+
+If you want to compile a source file including the 'gcrypt.h' header
+file, you must make sure that the compiler can find it in the directory
+hierarchy.  This is accomplished by adding the path to the directory in
+which the header file is located to the compilers include file search
+path (via the '-I' option).
+
+   However, the path to the include file is determined at the time the
+source is configured.  To solve this problem, Libgcrypt ships with a
+small helper program 'libgcrypt-config' that knows the path to the
+include file and other configuration options.  The options that need to
+be added to the compiler invocation at compile time are output by the
+'--cflags' option to 'libgcrypt-config'.  The following example shows
+how it can be used at the command line:
+
+     gcc -c foo.c `libgcrypt-config --cflags`
+
+   Adding the output of 'libgcrypt-config --cflags' to the compiler’s
+command line will ensure that the compiler can find the Libgcrypt header
+file.
+
+   A similar problem occurs when linking the program with the library.
+Again, the compiler has to find the library files.  For this to work,
+the path to the library files has to be added to the library search path
+(via the '-L' option).  For this, the option '--libs' to
+'libgcrypt-config' can be used.  For convenience, this option also
+outputs all other options that are required to link the program with the
+Libgcrypt libraries (in particular, the '-lgcrypt' option).  The example
+shows how to link 'foo.o' with the Libgcrypt library to a program 'foo'.
+
+     gcc -o foo foo.o `libgcrypt-config --libs`
+
+   Of course you can also combine both examples to a single command by
+specifying both options to 'libgcrypt-config':
+
+     gcc -o foo foo.c `libgcrypt-config --cflags --libs`
+
+\1f
+File: gcrypt.info,  Node: Building sources using Automake,  Next: Initializing the library,  Prev: Building sources,  Up: Preparation
+
+2.3 Building sources using Automake
+===================================
+
+It is much easier if you use GNU Automake instead of writing your own
+Makefiles.  If you do that, you do not have to worry about finding and
+invoking the 'libgcrypt-config' script at all.  Libgcrypt provides an
+extension to Automake that does all the work for you.
+
+ -- Macro: AM_PATH_LIBGCRYPT ([MINIMUM-VERSION], [ACTION-IF-FOUND],
+          [ACTION-IF-NOT-FOUND])
+     Check whether Libgcrypt (at least version MINIMUM-VERSION, if
+     given) exists on the host system.  If it is found, execute
+     ACTION-IF-FOUND, otherwise do ACTION-IF-NOT-FOUND, if given.
+
+     Additionally, the function defines 'LIBGCRYPT_CFLAGS' to the flags
+     needed for compilation of the program to find the 'gcrypt.h' header
+     file, and 'LIBGCRYPT_LIBS' to the linker flags needed to link the
+     program to the Libgcrypt library.  If the used helper script does
+     not match the target type you are building for a warning is printed
+     and the string 'libgcrypt' is appended to the variable
+     'gpg_config_script_warn'.
+
+     This macro searches for 'libgcrypt-config' along the PATH. If you
+     are cross-compiling, it is useful to set the environment variable
+     'SYSROOT' to the top directory of your target.  The macro will then
+     first look for the helper program in the 'bin' directory below that
+     top directory.  An absolute directory name must be used for
+     'SYSROOT'.  Finally, if the configure command line option
+     '--with-libgcrypt-prefix' is used, only its value is used for the
+     top directory below which the helper script is expected.
+
+   You can use the defined Autoconf variables like this in your
+'Makefile.am':
+
+     AM_CPPFLAGS = $(LIBGCRYPT_CFLAGS)
+     LDADD = $(LIBGCRYPT_LIBS)
+
+\1f
+File: gcrypt.info,  Node: Initializing the library,  Next: Multi-Threading,  Prev: Building sources using Automake,  Up: Preparation
+
+2.4 Initializing the library
+============================
+
+Before the library can be used, it must initialize itself.  This is
+achieved by invoking the function 'gcry_check_version' described below.
+
+   Also, it is often desirable to check that the version of Libgcrypt
+used is indeed one which fits all requirements.  Even with binary
+compatibility, new features may have been introduced, but due to problem
+with the dynamic linker an old version may actually be used.  So you may
+want to check that the version is okay right after program startup.
+
+ -- Function: const char * gcry_check_version (const char *REQ_VERSION)
+
+     The function 'gcry_check_version' initializes some subsystems used
+     by Libgcrypt and must be invoked before any other function in the
+     library.  *Note Multi-Threading::.
+
+     Furthermore, this function returns the version number of the
+     library.  It can also verify that the version number is higher than
+     a certain required version number REQ_VERSION, if this value is not
+     a null pointer.
+
+   Libgcrypt uses a concept known as secure memory, which is a region of
+memory set aside for storing sensitive data.  Because such memory is a
+scarce resource, it needs to be setup in advanced to a fixed size.
+Further, most operating systems have special requirements on how that
+secure memory can be used.  For example, it might be required to install
+an application as "setuid(root)" to allow allocating such memory.
+Libgcrypt requires a sequence of initialization steps to make sure that
+this works correctly.  The following examples show the necessary steps.
+
+   If you don't have a need for secure memory, for example if your
+application does not use secret keys or other confidential data or it
+runs in a controlled environment where key material floating around in
+memory is not a problem, you should initialize Libgcrypt this way:
+
+       /* Version check should be the very first call because it
+          makes sure that important subsystems are initialized. */
+       if (!gcry_check_version (GCRYPT_VERSION))
+         {
+           fputs ("libgcrypt version mismatch\n", stderr);
+           exit (2);
+         }
+
+       /* Disable secure memory.  */
+       gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+
+       /* ... If required, other initialization goes here.  */
+
+       /* Tell Libgcrypt that initialization has completed. */
+       gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+
+   If you have to protect your keys or other information in memory
+against being swapped out to disk and to enable an automatic overwrite
+of used and freed memory, you need to initialize Libgcrypt this way:
+
+       /* Version check should be the very first call because it
+          makes sure that important subsystems are initialized. */
+       if (!gcry_check_version (GCRYPT_VERSION))
+         {
+           fputs ("libgcrypt version mismatch\n", stderr);
+           exit (2);
+         }
+
+       /* We don't want to see any warnings, e.g. because we have not yet
+          parsed program options which might be used to suppress such
+          warnings. */
+       gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
+
+       /* ... If required, other initialization goes here.  Note that the
+          process might still be running with increased privileges and that
+          the secure memory has not been initialized.  */
+
+       /* Allocate a pool of 16k secure memory.  This make the secure memory
+          available and also drops privileges where needed.  */
+       gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
+
+       /* It is now okay to let Libgcrypt complain when there was/is
+          a problem with the secure memory. */
+       gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
+
+       /* ... If required, other initialization goes here.  */
+
+       /* Tell Libgcrypt that initialization has completed. */
+       gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+
+   It is important that these initialization steps are not done by a
+library but by the actual application.  A library using Libgcrypt might
+want to check for finished initialization using:
+
+       if (!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P))
+         {
+           fputs ("libgcrypt has not been initialized\n", stderr);
+           abort ();
+         }
+
+   Instead of terminating the process, the library may instead print a
+warning and try to initialize Libgcrypt itself.  See also the section on
+multi-threading below for more pitfalls.
+
+\1f
+File: gcrypt.info,  Node: Multi-Threading,  Next: Enabling FIPS mode,  Prev: Initializing the library,  Up: Preparation
+
+2.5 Multi-Threading
+===================
+
+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.
+
+   ---------- Footnotes ----------
+
+   (1) At least this is true for POSIX threads, as 'pthread_create' is a
+function that synchronizes memory with respects to other threads.  There
+are many functions which have this property, a complete list can be
+found in POSIX, IEEE Std 1003.1-2003, Base Definitions, Issue 6, in the
+definition of the term "Memory Synchronization".  For other thread
+packages, more relaxed or more strict rules may apply.
+
+\1f
+File: gcrypt.info,  Node: Enabling FIPS mode,  Next: Hardware features,  Prev: Multi-Threading,  Up: Preparation
+
+2.6 How to enable the FIPS mode
+===============================
+
+Libgcrypt may be used in a FIPS 140-2 mode.  Note, that this does not
+necessary mean that Libcgrypt is an appoved FIPS 140-2 module.  Check
+the NIST database at <http://csrc.nist.gov/groups/STM/cmvp/> to see what
+versions of Libgcrypt are approved.
+
+   Because FIPS 140 has certain restrictions on the use of cryptography
+which are not always wanted, Libgcrypt needs to be put into FIPS mode
+explicitly.  Three alternative mechanisms are provided to switch
+Libgcrypt into this mode:
+
+   * If the file '/proc/sys/crypto/fips_enabled' exists and contains a
+     numeric value other than '0', Libgcrypt is put into FIPS mode at
+     initialization time.  Obviously this works only on systems with a
+     'proc' file system (i.e.  GNU/Linux).
+
+   * If the file '/etc/gcrypt/fips_enabled' exists, Libgcrypt is put
+     into FIPS mode at initialization time.  Note that this filename is
+     hardwired and does not depend on any configuration options.
+
+   * If the application requests FIPS mode using the control command
+     'GCRYCTL_FORCE_FIPS_MODE'.  This must be done prior to any
+     initialization (i.e.  before 'gcry_check_version').
+
+   In addition to the standard FIPS mode, Libgcrypt may also be put into
+an Enforced FIPS mode by writing a non-zero value into the file
+'/etc/gcrypt/fips_enabled' or by using the control command
+'GCRYCTL_SET_ENFORCED_FIPS_FLAG' before any other calls to libgcrypt.
+The Enforced FIPS mode helps to detect applications which don't fulfill
+all requirements for using Libgcrypt in FIPS mode (*note FIPS Mode::).
+
+   Once Libgcrypt has been put into FIPS mode, it is not possible to
+switch back to standard mode without terminating the process first.  If
+the logging verbosity level of Libgcrypt has been set to at least 2, the
+state transitions and the self-tests are logged.
+
+\1f
+File: gcrypt.info,  Node: Hardware features,  Prev: Enabling FIPS mode,  Up: Preparation
+
+2.7 How to disable hardware features
+====================================
+
+Libgcrypt makes use of certain hardware features.  If the use of a
+feature is not desired it may be either be disabled by a program or
+globally using a configuration file.  The currently supported features
+are
+
+'padlock-rng'
+'padlock-aes'
+'padlock-sha'
+'padlock-mmul'
+'intel-cpu'
+'intel-fast-shld'
+'intel-bmi2'
+'intel-ssse3'
+'intel-pclmul'
+'intel-aesni'
+'intel-rdrand'
+'intel-avx'
+'intel-avx2'
+'arm-neon'
+
+   To disable a feature for all processes using Libgcrypt 1.6 or newer,
+create the file '/etc/gcrypt/hwf.deny' and put each feature not to be
+used on a single line.  Empty lines, white space, and lines prefixed
+with a hash mark are ignored.  The file should be world readable.
+
+   To disable a feature specifically for a program that program must
+tell it Libgcrypt before before calling 'gcry_check_version'.
+Example:(1)
+
+       gcry_control (GCRYCTL_DISABLE_HWF, "intel-rdrand", NULL);
+
+To print the list of active features you may use this command:
+
+       mpicalc --print-config | grep ^hwflist: | tr : '\n' | tail -n +2
+
+   ---------- Footnotes ----------
+
+   (1) NB. Libgcrypt uses the RDRAND feature only as one source of
+entropy.  A CPU with a broken RDRAND will thus not compromise of the
+random number generator
+
+\1f
+File: gcrypt.info,  Node: Generalities,  Next: Handler Functions,  Prev: Preparation,  Up: Top
+
+3 Generalities
+**************
+
+* Menu:
+
+* Controlling the library::     Controlling Libgcrypt's behavior.
+* Error Handling::              Error codes and such.
+
+\1f
+File: gcrypt.info,  Node: Controlling the library,  Next: Error Handling,  Up: Generalities
+
+3.1 Controlling the library
+===========================
+
+ -- Function: gcry_error_t gcry_control (enum gcry_ctl_cmds CMD, ...)
+
+     This function can be used to influence the general behavior of
+     Libgcrypt in several ways.  Depending on CMD, more arguments can or
+     have to be provided.
+
+     'GCRYCTL_ENABLE_M_GUARD; Arguments: none'
+          This command enables the built-in memory guard.  It must not
+          be used to activate the memory guard after the memory
+          management has already been used; therefore it can ONLY be
+          used before 'gcry_check_version'.  Note that the memory guard
+          is NOT used when the user of the library has set his own
+          memory management callbacks.
+
+     'GCRYCTL_ENABLE_QUICK_RANDOM; Arguments: none'
+          This command inhibits the use the very secure random quality
+          level ('GCRY_VERY_STRONG_RANDOM') and degrades all request
+          down to 'GCRY_STRONG_RANDOM'.  In general this is not
+          recommended.  However, for some applications the extra quality
+          random Libgcrypt tries to create is not justified and this
+          option may help to get better performance.  Please check with
+          a crypto expert whether this option can be used for your
+          application.
+
+          This option can only be used at initialization time.
+
+     'GCRYCTL_DUMP_RANDOM_STATS; Arguments: none'
+          This command dumps random number generator related statistics
+          to the library's logging stream.
+
+     'GCRYCTL_DUMP_MEMORY_STATS; Arguments: none'
+          This command dumps memory management related statistics to the
+          library's logging stream.
+
+     'GCRYCTL_DUMP_SECMEM_STATS; Arguments: none'
+          This command dumps secure memory management related statistics
+          to the library's logging stream.
+
+     'GCRYCTL_DROP_PRIVS; Arguments: none'
+          This command disables the use of secure memory and drops the
+          privileges of the current process.  This command has not much
+          use; the suggested way to disable secure memory is to use
+          'GCRYCTL_DISABLE_SECMEM' right after initialization.
+
+     'GCRYCTL_DISABLE_SECMEM; Arguments: none'
+          This command disables the use of secure memory.  If this
+          command is used in FIPS mode, FIPS mode will be disabled and
+          the function 'gcry_fips_mode_active' returns false.  However,
+          in Enforced FIPS mode this command has no effect at all.
+
+          Many applications do not require secure memory, so they should
+          disable it right away.  This command should be executed right
+          after 'gcry_check_version'.
+
+     'GCRYCTL_DISABLE_LOCKED_SECMEM; Arguments: none'
+          This command disables the use of the mlock call for secure
+          memory.  Disabling the use of mlock may for example be done if
+          an encrypted swap space is in use.  This command should be
+          executed right after 'gcry_check_version'.
+
+     'GCRYCTL_DISABLE_PRIV_DROP; Arguments: none'
+          This command sets a global flag to tell the secure memory
+          subsystem that it shall not drop privileges after secure
+          memory has been allocated.  This command is commonly used
+          right after 'gcry_check_version' but may also be used right
+          away at program startup.  It won't have an effect after the
+          secure memory pool has been initialized.  WARNING: A process
+          running setuid(root) is a severe security risk.  Processes
+          making use of Libgcrypt or other complex code should drop
+          these extra privileges as soon as possible.  If this command
+          has been used the caller is responsible for dropping the
+          privileges.
+
+     'GCRYCTL_INIT_SECMEM; Arguments: int nbytes'
+          This command is used to allocate a pool of secure memory and
+          thus enabling the use of secure memory.  It also drops all
+          extra privileges the process has (i.e.  if it is run as setuid
+          (root)).  If the argument NBYTES is 0, secure memory will be
+          disabled.  The minimum amount of secure memory allocated is
+          currently 16384 bytes; you may thus use a value of 1 to
+          request that default size.
+
+     'GCRYCTL_TERM_SECMEM; Arguments: none'
+          This command zeroises the secure memory and destroys the
+          handler.  The secure memory pool may not be used anymore after
+          running this command.  If the secure memory pool as already
+          been destroyed, this command has no effect.  Applications
+          might want to run this command from their exit handler to make
+          sure that the secure memory gets properly destroyed.  This
+          command is not necessarily thread-safe but that should not be
+          needed in cleanup code.  It may be called from a signal
+          handler.
+
+     'GCRYCTL_DISABLE_SECMEM_WARN; Arguments: none'
+          Disable warning messages about problems with the secure memory
+          subsystem.  This command should be run right after
+          'gcry_check_version'.
+
+     'GCRYCTL_SUSPEND_SECMEM_WARN; Arguments: none'
+          Postpone warning messages from the secure memory subsystem.
+          *Note the initialization example: sample-use-suspend-secmem,
+          on how to use it.
+
+     'GCRYCTL_RESUME_SECMEM_WARN; Arguments: none'
+          Resume warning messages from the secure memory subsystem.
+          *Note the initialization example: sample-use-resume-secmem, on
+          how to use it.
+
+     'GCRYCTL_USE_SECURE_RNDPOOL; Arguments: none'
+          This command tells the PRNG to store random numbers in secure
+          memory.  This command should be run right after
+          'gcry_check_version' and not later than the command
+          GCRYCTL_INIT_SECMEM. Note that in FIPS mode the secure memory
+          is always used.
+
+     'GCRYCTL_SET_RANDOM_SEED_FILE; Arguments: const char *filename'
+          This command specifies the file, which is to be used as seed
+          file for the PRNG. If the seed file is registered prior to
+          initialization of the PRNG, the seed file's content (if it
+          exists and seems to be valid) is fed into the PRNG pool.
+          After the seed file has been registered, the PRNG can be
+          signalled to write out the PRNG pool's content into the seed
+          file with the following command.
+
+     'GCRYCTL_UPDATE_RANDOM_SEED_FILE; Arguments: none'
+          Write out the PRNG pool's content into the registered seed
+          file.
+
+          Multiple instances of the applications sharing the same random
+          seed file can be started in parallel, in which case they will
+          read out the same pool and then race for updating it (the last
+          update overwrites earlier updates).  They will differentiate
+          only by the weak entropy that is added in read_seed_file based
+          on the PID and clock, and up to 16 bytes of weak random
+          non-blockingly.  The consequence is that the output of these
+          different instances is correlated to some extent.  In a
+          perfect attack scenario, the attacker can control (or at least
+          guess) the PID and clock of the application, and drain the
+          system's entropy pool to reduce the "up to 16 bytes" above to
+          0.  Then the dependencies of the initial states of the pools
+          are completely known.  Note that this is not an issue if
+          random of 'GCRY_VERY_STRONG_RANDOM' quality is requested as in
+          this case enough extra entropy gets mixed.  It is also not an
+          issue when using Linux (rndlinux driver), because this one
+          guarantees to read full 16 bytes from /dev/urandom and thus
+          there is no way for an attacker without kernel access to
+          control these 16 bytes.
+
+     'GCRYCTL_CLOSE_RANDOM_DEVICE; Arguments: none'
+          Try to close the random device.  If on Unix system you call
+          fork(), the child process does no call exec(), and you do not
+          intend to use Libgcrypt in the child, it might be useful to
+          use this control code to close the inherited file descriptors
+          of the random device.  If Libgcrypt is later used again by the
+          child, the device will be re-opened.  On non-Unix systems this
+          control code is ignored.
+
+     'GCRYCTL_SET_VERBOSITY; Arguments: int level'
+          This command sets the verbosity of the logging.  A level of 0
+          disables all extra logging whereas positive numbers enable
+          more verbose logging.  The level may be changed at any time
+          but be aware that no memory synchronization is done so the
+          effect of this command might not immediately show up in other
+          threads.  This command may even be used prior to
+          'gcry_check_version'.
+
+     'GCRYCTL_SET_DEBUG_FLAGS; Arguments: unsigned int flags'
+          Set the debug flag bits as given by the argument.  Be aware
+          that that no memory synchronization is done so the effect of
+          this command might not immediately show up in other threads.
+          The debug flags are not considered part of the API and thus
+          may change without notice.  As of now bit 0 enables debugging
+          of cipher functions and bit 1 debugging of
+          multi-precision-integers.  This command may even be used prior
+          to 'gcry_check_version'.
+
+     'GCRYCTL_CLEAR_DEBUG_FLAGS; Arguments: unsigned int flags'
+          Set the debug flag bits as given by the argument.  Be aware
+          that that no memory synchronization is done so the effect of
+          this command might not immediately show up in other threads.
+          This command may even be used prior to 'gcry_check_version'.
+
+     'GCRYCTL_DISABLE_INTERNAL_LOCKING; Arguments: none'
+          This command does nothing.  It exists only for backward
+          compatibility.
+
+     'GCRYCTL_ANY_INITIALIZATION_P; Arguments: none'
+          This command returns true if the library has been basically
+          initialized.  Such a basic initialization happens implicitly
+          with many commands to get certain internal subsystems running.
+          The common and suggested way to do this basic initialization
+          is by calling gcry_check_version.
+
+     'GCRYCTL_INITIALIZATION_FINISHED; Arguments: none'
+          This command tells the library that the application has
+          finished the initialization.
+
+     'GCRYCTL_INITIALIZATION_FINISHED_P; Arguments: none'
+          This command returns true if the command
+          GCRYCTL_INITIALIZATION_FINISHED has already been run.
+
+     'GCRYCTL_SET_THREAD_CBS; Arguments: struct ath_ops *ath_ops'
+          This command is obsolete since version 1.6.
+
+     'GCRYCTL_FAST_POLL; Arguments: none'
+          Run a fast random poll.
+
+     'GCRYCTL_SET_RNDEGD_SOCKET; Arguments: const char *filename'
+          This command may be used to override the default name of the
+          EGD socket to connect to.  It may be used only during
+          initialization as it is not thread safe.  Changing the socket
+          name again is not supported.  The function may return an error
+          if the given filename is too long for a local socket name.
+
+          EGD is an alternative random gatherer, used only on systems
+          lacking a proper random device.
+
+     'GCRYCTL_PRINT_CONFIG; Arguments: FILE *stream'
+          This command dumps information pertaining to the configuration
+          of the library to the given stream.  If NULL is given for
+          STREAM, the log system is used.  This command may be used
+          before the initialization has been finished but not before a
+          'gcry_check_version'.
+
+     'GCRYCTL_OPERATIONAL_P; Arguments: none'
+          This command returns true if the library is in an operational
+          state.  This information makes only sense in FIPS mode.  In
+          contrast to other functions, this is a pure test function and
+          won't put the library into FIPS mode or change the internal
+          state.  This command may be used before the initialization has
+          been finished but not before a 'gcry_check_version'.
+
+     'GCRYCTL_FIPS_MODE_P; Arguments: none'
+          This command returns true if the library is in FIPS mode.
+          Note, that this is no indication about the current state of
+          the library.  This command may be used before the
+          initialization has been finished but not before a
+          'gcry_check_version'.  An application may use this command or
+          the convenience macro below to check whether FIPS mode is
+          actually active.
+
+           -- Function: int gcry_fips_mode_active (void)
+
+               Returns true if the FIPS mode is active.  Note that this
+               is implemented as a macro.
+
+     'GCRYCTL_FORCE_FIPS_MODE; Arguments: none'
+          Running this command puts the library into FIPS mode.  If the
+          library is already in FIPS mode, a self-test is triggered and
+          thus the library will be put into operational state.  This
+          command may be used before a call to 'gcry_check_version' and
+          that is actually the recommended way to let an application
+          switch the library into FIPS mode.  Note that Libgcrypt will
+          reject an attempt to switch to fips mode during or after the
+          initialization.
+
+     'GCRYCTL_SET_ENFORCED_FIPS_FLAG; Arguments: none'
+          Running this command sets the internal flag that puts the
+          library into the enforced FIPS mode during the FIPS mode
+          initialization.  This command does not affect the library if
+          the library is not put into the FIPS mode and it must be used
+          before any other libgcrypt library calls that initialize the
+          library such as 'gcry_check_version'.  Note that Libgcrypt
+          will reject an attempt to switch to the enforced fips mode
+          during or after the initialization.
+
+     'GCRYCTL_SET_PREFERRED_RNG_TYPE; Arguments: int'
+          These are advisory commands to select a certain random number
+          generator.  They are only advisory because libraries may not
+          know what an application actually wants or vice versa.  Thus
+          Libgcrypt employs a priority check to select the actually used
+          RNG. If an applications selects a lower priority RNG but a
+          library requests a higher priority RNG Libgcrypt will switch
+          to the higher priority RNG. Applications and libraries should
+          use these control codes before 'gcry_check_version'.  The
+          available generators are:
+          'GCRY_RNG_TYPE_STANDARD'
+               A conservative standard generator based on the
+               "Continuously Seeded Pseudo Random Number Generator"
+               designed by Peter Gutmann.
+          'GCRY_RNG_TYPE_FIPS'
+               A deterministic random number generator conforming to he
+               document "NIST-Recommended Random Number Generator Based
+               on ANSI X9.31 Appendix A.2.4 Using the 3-Key Triple DES
+               and AES Algorithms" (2005-01-31).  This implementation
+               uses the AES variant.
+          'GCRY_RNG_TYPE_SYSTEM'
+               A wrapper around the system's native RNG. On Unix system
+               these are usually the /dev/random and /dev/urandom
+               devices.
+          The default is 'GCRY_RNG_TYPE_STANDARD' unless FIPS mode as
+          been enabled; in which case 'GCRY_RNG_TYPE_FIPS' is used and
+          locked against further changes.
+
+     'GCRYCTL_GET_CURRENT_RNG_TYPE; Arguments: int *'
+          This command stores the type of the currently used RNG as an
+          integer value at the provided address.
+
+     'GCRYCTL_SELFTEST; Arguments: none'
+          This may be used at anytime to have the library run all
+          implemented self-tests.  It works in standard and in FIPS
+          mode.  Returns 0 on success or an error code on failure.
+
+     'GCRYCTL_DISABLE_HWF; Arguments: const char *name'
+
+          Libgcrypt detects certain features of the CPU at startup time.
+          For performance tests it is sometimes required not to use such
+          a feature.  This option may be used to disable a certain
+          feature; i.e.  Libgcrypt behaves as if this feature has not
+          been detected.  Note that the detection code might be run if
+          the feature has been disabled.  This command must be used at
+          initialization time; i.e.  before calling
+          'gcry_check_version'.
+
+\1f
+File: gcrypt.info,  Node: Error Handling,  Prev: Controlling the library,  Up: Generalities
+
+3.2 Error Handling
+==================
+
+Many functions in Libgcrypt can return an error if they fail.  For this
+reason, the application should always catch the error condition and take
+appropriate measures, for example by releasing the resources and passing
+the error up to the caller, or by displaying a descriptive message to
+the user and cancelling the operation.
+
+   Some error values do not indicate a system error or an error in the
+operation, but the result of an operation that failed properly.  For
+example, if you try to decrypt a tempered message, the decryption will
+fail.  Another error value actually means that the end of a data buffer
+or list has been reached.  The following descriptions explain for many
+error codes what they mean usually.  Some error values have specific
+meanings if returned by a certain functions.  Such cases are described
+in the documentation of those functions.
+
+   Libgcrypt uses the 'libgpg-error' library.  This allows to share the
+error codes with other components of the GnuPG system, and to pass error
+values transparently from the crypto engine, or some helper application
+of the crypto engine, to the user.  This way no information is lost.  As
+a consequence, Libgcrypt does not use its own identifiers for error
+codes, but uses those provided by 'libgpg-error'.  They usually start
+with 'GPG_ERR_'.
+
+   However, Libgcrypt does provide aliases for the functions defined in
+libgpg-error, which might be preferred for name space consistency.
+
+   Most functions in Libgcrypt return an error code in the case of
+failure.  For this reason, the application should always catch the error
+condition and take appropriate measures, for example by releasing the
+resources and passing the error up to the caller, or by displaying a
+descriptive message to the user and canceling the operation.
+
+   Some error values do not indicate a system error or an error in the
+operation, but the result of an operation that failed properly.
+
+   GnuPG components, including Libgcrypt, use an extra library named
+libgpg-error to provide a common error handling scheme.  For more
+information on libgpg-error, see the according manual.
+
+* Menu:
+
+* Error Values::                The error value and what it means.
+* Error Sources::               A list of important error sources.
+* Error Codes::                 A list of important error codes.
+* Error Strings::               How to get a descriptive string from a value.
+
+\1f
+File: gcrypt.info,  Node: Error Values,  Next: Error Sources,  Up: Error Handling
+
+3.2.1 Error Values
+------------------
+
+ -- Data type: gcry_err_code_t
+     The 'gcry_err_code_t' type is an alias for the 'libgpg-error' type
+     'gpg_err_code_t'.  The error code indicates the type of an error,
+     or the reason why an operation failed.
+
+     A list of important error codes can be found in the next section.
+
+ -- Data type: gcry_err_source_t
+     The 'gcry_err_source_t' type is an alias for the 'libgpg-error'
+     type 'gpg_err_source_t'.  The error source has not a precisely
+     defined meaning.  Sometimes it is the place where the error
+     happened, sometimes it is the place where an error was encoded into
+     an error value.  Usually the error source will give an indication
+     to where to look for the problem.  This is not always true, but it
+     is attempted to achieve this goal.
+
+     A list of important error sources can be found in the next section.
+
+ -- Data type: gcry_error_t
+     The 'gcry_error_t' type is an alias for the 'libgpg-error' type
+     'gpg_error_t'.  An error value like this has always two components,
+     an error code and an error source.  Both together form the error
+     value.
+
+     Thus, the error value can not be directly compared against an error
+     code, but the accessor functions described below must be used.
+     However, it is guaranteed that only 0 is used to indicate success
+     ('GPG_ERR_NO_ERROR'), and that in this case all other parts of the
+     error value are set to 0, too.
+
+     Note that in Libgcrypt, the error source is used purely for
+     diagnostic purposes.  Only the error code should be checked to test
+     for a certain outcome of a function.  The manual only documents the
+     error code part of an error value.  The error source is left
+     unspecified and might be anything.
+
+ -- Function: gcry_err_code_t gcry_err_code (gcry_error_t ERR)
+     The static inline function 'gcry_err_code' returns the
+     'gcry_err_code_t' component of the error value ERR.  This function
+     must be used to extract the error code from an error value in order
+     to compare it with the 'GPG_ERR_*' error code macros.
+
+ -- Function: gcry_err_source_t gcry_err_source (gcry_error_t ERR)
+     The static inline function 'gcry_err_source' returns the
+     'gcry_err_source_t' component of the error value ERR.  This
+     function must be used to extract the error source from an error
+     value in order to compare it with the 'GPG_ERR_SOURCE_*' error
+     source macros.
+
+ -- Function: gcry_error_t gcry_err_make (gcry_err_source_t SOURCE,
+          gcry_err_code_t CODE)
+     The static inline function 'gcry_err_make' returns the error value
+     consisting of the error source SOURCE and the error code CODE.
+
+     This function can be used in callback functions to construct an
+     error value to return it to the library.
+
+ -- Function: gcry_error_t gcry_error (gcry_err_code_t CODE)
+     The static inline function 'gcry_error' returns the error value
+     consisting of the default error source and the error code CODE.
+
+     For GCRY applications, the default error source is
+     'GPG_ERR_SOURCE_USER_1'.  You can define 'GCRY_ERR_SOURCE_DEFAULT'
+     before including 'gcrypt.h' to change this default.
+
+     This function can be used in callback functions to construct an
+     error value to return it to the library.
+
+   The 'libgpg-error' library provides error codes for all system error
+numbers it knows about.  If ERR is an unknown error number, the error
+code 'GPG_ERR_UNKNOWN_ERRNO' is used.  The following functions can be
+used to construct error values from system errno numbers.
+
+ -- Function: gcry_error_t gcry_err_make_from_errno
+          (gcry_err_source_t SOURCE, int ERR)
+     The function 'gcry_err_make_from_errno' is like 'gcry_err_make',
+     but it takes a system error like 'errno' instead of a
+     'gcry_err_code_t' error code.
+
+ -- Function: gcry_error_t gcry_error_from_errno (int ERR)
+     The function 'gcry_error_from_errno' is like 'gcry_error', but it
+     takes a system error like 'errno' instead of a 'gcry_err_code_t'
+     error code.
+
+   Sometimes you might want to map system error numbers to error codes
+directly, or map an error code representing a system error back to the
+system error number.  The following functions can be used to do that.
+
+ -- Function: gcry_err_code_t gcry_err_code_from_errno (int ERR)
+     The function 'gcry_err_code_from_errno' returns the error code for
+     the system error ERR.  If ERR is not a known system error, the
+     function returns 'GPG_ERR_UNKNOWN_ERRNO'.
+
+ -- Function: int gcry_err_code_to_errno (gcry_err_code_t ERR)
+     The function 'gcry_err_code_to_errno' returns the system error for
+     the error code ERR.  If ERR is not an error code representing a
+     system error, or if this system error is not defined on this
+     system, the function returns '0'.
+
+\1f
+File: gcrypt.info,  Node: Error Sources,  Next: Error Codes,  Prev: Error Values,  Up: Error Handling
+
+3.2.2 Error Sources
+-------------------
+
+The library 'libgpg-error' defines an error source for every component
+of the GnuPG system.  The error source part of an error value is not
+well defined.  As such it is mainly useful to improve the diagnostic
+error message for the user.
+
+   If the error code part of an error value is '0', the whole error
+value will be '0'.  In this case the error source part is of course
+'GPG_ERR_SOURCE_UNKNOWN'.
+
+   The list of error sources that might occur in applications using
+Libgcrypt is:
+
+'GPG_ERR_SOURCE_UNKNOWN'
+     The error source is not known.  The value of this error source is
+     '0'.
+
+'GPG_ERR_SOURCE_GPGME'
+     The error source is GPGME itself.
+
+'GPG_ERR_SOURCE_GPG'
+     The error source is GnuPG, which is the crypto engine used for the
+     OpenPGP protocol.
+
+'GPG_ERR_SOURCE_GPGSM'
+     The error source is GPGSM, which is the crypto engine used for the
+     OpenPGP protocol.
+
+'GPG_ERR_SOURCE_GCRYPT'
+     The error source is 'libgcrypt', which is used by crypto engines to
+     perform cryptographic operations.
+
+'GPG_ERR_SOURCE_GPGAGENT'
+     The error source is 'gpg-agent', which is used by crypto engines to
+     perform operations with the secret key.
+
+'GPG_ERR_SOURCE_PINENTRY'
+     The error source is 'pinentry', which is used by 'gpg-agent' to
+     query the passphrase to unlock a secret key.
+
+'GPG_ERR_SOURCE_SCD'
+     The error source is the SmartCard Daemon, which is used by
+     'gpg-agent' to delegate operations with the secret key to a
+     SmartCard.
+
+'GPG_ERR_SOURCE_KEYBOX'
+     The error source is 'libkbx', a library used by the crypto engines
+     to manage local keyrings.
+
+'GPG_ERR_SOURCE_USER_1'
+'GPG_ERR_SOURCE_USER_2'
+'GPG_ERR_SOURCE_USER_3'
+'GPG_ERR_SOURCE_USER_4'
+     These error sources are not used by any GnuPG component and can be
+     used by other software.  For example, applications using Libgcrypt
+     can use them to mark error values coming from callback handlers.
+     Thus 'GPG_ERR_SOURCE_USER_1' is the default for errors created with
+     'gcry_error' and 'gcry_error_from_errno', unless you define
+     'GCRY_ERR_SOURCE_DEFAULT' before including 'gcrypt.h'.
+
+\1f
+File: gcrypt.info,  Node: Error Codes,  Next: Error Strings,  Prev: Error Sources,  Up: Error Handling
+
+3.2.3 Error Codes
+-----------------
+
+The library 'libgpg-error' defines many error values.  The following
+list includes the most important error codes.
+
+'GPG_ERR_EOF'
+     This value indicates the end of a list, buffer or file.
+
+'GPG_ERR_NO_ERROR'
+     This value indicates success.  The value of this error code is '0'.
+     Also, it is guaranteed that an error value made from the error code
+     '0' will be '0' itself (as a whole).  This means that the error
+     source information is lost for this error code, however, as this
+     error code indicates that no error occurred, this is generally not
+     a problem.
+
+'GPG_ERR_GENERAL'
+     This value means that something went wrong, but either there is not
+     enough information about the problem to return a more useful error
+     value, or there is no separate error value for this type of
+     problem.
+
+'GPG_ERR_ENOMEM'
+     This value means that an out-of-memory condition occurred.
+
+'GPG_ERR_E...'
+     System errors are mapped to GPG_ERR_EFOO where FOO is the symbol
+     for the system error.
+
+'GPG_ERR_INV_VALUE'
+     This value means that some user provided data was out of range.
+
+'GPG_ERR_UNUSABLE_PUBKEY'
+     This value means that some recipients for a message were invalid.
+
+'GPG_ERR_UNUSABLE_SECKEY'
+     This value means that some signers were invalid.
+
+'GPG_ERR_NO_DATA'
+     This value means that data was expected where no data was found.
+
+'GPG_ERR_CONFLICT'
+     This value means that a conflict of some sort occurred.
+
+'GPG_ERR_NOT_IMPLEMENTED'
+     This value indicates that the specific function (or operation) is
+     not implemented.  This error should never happen.  It can only
+     occur if you use certain values or configuration options which do
+     not work, but for which we think that they should work at some
+     later time.
+
+'GPG_ERR_DECRYPT_FAILED'
+     This value indicates that a decryption operation was unsuccessful.
+
+'GPG_ERR_WRONG_KEY_USAGE'
+     This value indicates that a key is not used appropriately.
+
+'GPG_ERR_NO_SECKEY'
+     This value indicates that no secret key for the user ID is
+     available.
+
+'GPG_ERR_UNSUPPORTED_ALGORITHM'
+     This value means a verification failed because the cryptographic
+     algorithm is not supported by the crypto backend.
+
+'GPG_ERR_BAD_SIGNATURE'
+     This value means a verification failed because the signature is
+     bad.
+
+'GPG_ERR_NO_PUBKEY'
+     This value means a verification failed because the public key is
+     not available.
+
+'GPG_ERR_NOT_OPERATIONAL'
+     This value means that the library is not yet in state which allows
+     to use this function.  This error code is in particular returned if
+     Libgcrypt is operated in FIPS mode and the internal state of the
+     library does not yet or not anymore allow the use of a service.
+
+     This error code is only available with newer libgpg-error versions,
+     thus you might see "invalid error code" when passing this to
+     'gpg_strerror'.  The numeric value of this error code is 176.
+
+'GPG_ERR_USER_1'
+'GPG_ERR_USER_2'
+'...'
+'GPG_ERR_USER_16'
+     These error codes are not used by any GnuPG component and can be
+     freely used by other software.  Applications using Libgcrypt might
+     use them to mark specific errors returned by callback handlers if
+     no suitable error codes (including the system errors) for these
+     errors exist already.
+
+\1f
+File: gcrypt.info,  Node: Error Strings,  Prev: Error Codes,  Up: Error Handling
+
+3.2.4 Error Strings
+-------------------
+
+ -- Function: const char * gcry_strerror (gcry_error_t ERR)
+     The function 'gcry_strerror' returns a pointer to a statically
+     allocated string containing a description of the error code
+     contained in the error value ERR.  This string can be used to
+     output a diagnostic message to the user.
+
+ -- Function: const char * gcry_strsource (gcry_error_t ERR)
+     The function 'gcry_strsource' returns a pointer to a statically
+     allocated string containing a description of the error source
+     contained in the error value ERR.  This string can be used to
+     output a diagnostic message to the user.
+
+   The following example illustrates the use of the functions described
+above:
+
+     {
+       gcry_cipher_hd_t handle;
+       gcry_error_t err = 0;
+
+       err = gcry_cipher_open (&handle, GCRY_CIPHER_AES,
+                               GCRY_CIPHER_MODE_CBC, 0);
+       if (err)
+         {
+           fprintf (stderr, "Failure: %s/%s\n",
+                    gcry_strsource (err),
+                    gcry_strerror (err));
+         }
+     }
+
+\1f
+File: gcrypt.info,  Node: Handler Functions,  Next: Symmetric cryptography,  Prev: Generalities,  Up: Top
+
+4 Handler Functions
+*******************
+
+Libgcrypt makes it possible to install so called 'handler functions',
+which get called by Libgcrypt in case of certain events.
+
+* Menu:
+
+* Progress handler::            Using a progress handler function.
+* Allocation handler::          Using special memory allocation functions.
+* Error handler::               Using error handler functions.
+* Logging handler::             Using a special logging function.
+
+\1f
+File: gcrypt.info,  Node: Progress handler,  Next: Allocation handler,  Up: Handler Functions
+
+4.1 Progress handler
+====================
+
+It is often useful to retrieve some feedback while long running
+operations are performed.
+
+ -- Data type: gcry_handler_progress_t
+     Progress handler functions have to be of the type
+     'gcry_handler_progress_t', which is defined as:
+
+     'void (*gcry_handler_progress_t) (void *, const char *, int, int,
+     int)'
+
+   The following function may be used to register a handler function for
+this purpose.
+
+ -- Function: void gcry_set_progress_handler (gcry_handler_progress_t
+          CB, void *CB_DATA)
+
+     This function installs CB as the 'Progress handler' function.  It
+     may be used only during initialization.  CB must be defined as
+     follows:
+
+          void
+          my_progress_handler (void *CB_DATA, const char *WHAT,
+                               int PRINTCHAR, int CURRENT, int TOTAL)
+          {
+            /* Do something.  */
+          }
+
+     A description of the arguments of the progress handler function
+     follows.
+
+     CB_DATA
+          The argument provided in the call to
+          'gcry_set_progress_handler'.
+     WHAT
+          A string identifying the type of the progress output.  The
+          following values for WHAT are defined:
+
+          'need_entropy'
+               Not enough entropy is available.  TOTAL holds the number
+               of required bytes.
+
+          'wait_dev_random'
+               Waiting to re-open a random device.  TOTAL gives the
+               number of seconds until the next try.
+
+          'primegen'
+               Values for PRINTCHAR:
+               '\n'
+                    Prime generated.
+               '!'
+                    Need to refresh the pool of prime numbers.
+               '<, >'
+                    Number of bits adjusted.
+               '^'
+                    Searching for a generator.
+               '.'
+                    Fermat test on 10 candidates failed.
+               ':'
+                    Restart with a new random value.
+               '+'
+                    Rabin Miller test passed.
+
+\1f
+File: gcrypt.info,  Node: Allocation handler,  Next: Error handler,  Prev: Progress handler,  Up: Handler Functions
+
+4.2 Allocation handler
+======================
+
+It is possible to make Libgcrypt use special memory allocation functions
+instead of the built-in ones.
+
+   Memory allocation functions are of the following types:
+ -- Data type: gcry_handler_alloc_t
+     This type is defined as: 'void *(*gcry_handler_alloc_t) (size_t
+     n)'.
+ -- Data type: gcry_handler_secure_check_t
+     This type is defined as: 'int *(*gcry_handler_secure_check_t)
+     (const void *)'.
+ -- Data type: gcry_handler_realloc_t
+     This type is defined as: 'void *(*gcry_handler_realloc_t) (void *p,
+     size_t n)'.
+ -- Data type: gcry_handler_free_t
+     This type is defined as: 'void *(*gcry_handler_free_t) (void *)'.
+
+   Special memory allocation functions can be installed with the
+following function:
+
+ -- Function: void gcry_set_allocation_handler (gcry_handler_alloc_t
+          FUNC_ALLOC, gcry_handler_alloc_t FUNC_ALLOC_SECURE,
+          gcry_handler_secure_check_t FUNC_SECURE_CHECK,
+          gcry_handler_realloc_t FUNC_REALLOC, gcry_handler_free_t
+          FUNC_FREE)
+     Install the provided functions and use them instead of the built-in
+     functions for doing memory allocation.  Using this function is in
+     general not recommended because the standard Libgcrypt allocation
+     functions are guaranteed to zeroize memory if needed.
+
+     This function may be used only during initialization and may not be
+     used in fips mode.
+
+\1f
+File: gcrypt.info,  Node: Error handler,  Next: Logging handler,  Prev: Allocation handler,  Up: Handler Functions
+
+4.3 Error handler
+=================
+
+The following functions may be used to register handler functions that
+are called by Libgcrypt in case certain error conditions occur.  They
+may and should be registered prior to calling 'gcry_check_version'.
+
+ -- Data type: gcry_handler_no_mem_t
+     This type is defined as: 'int (*gcry_handler_no_mem_t) (void *,
+     size_t, unsigned int)'
+ -- Function: void gcry_set_outofcore_handler (gcry_handler_no_mem_t
+          FUNC_NO_MEM, void *CB_DATA)
+     This function registers FUNC_NO_MEM as 'out-of-core handler', which
+     means that it will be called in the case of not having enough
+     memory available.  The handler is called with 3 arguments: The
+     first one is the pointer CB_DATA as set with this function, the
+     second is the requested memory size and the last being a flag.  If
+     bit 0 of the flag is set, secure memory has been requested.  The
+     handler should either return true to indicate that Libgcrypt should
+     try again allocating memory or return false to let Libgcrypt use
+     its default fatal error handler.
+
+ -- Data type: gcry_handler_error_t
+     This type is defined as: 'void (*gcry_handler_error_t) (void *,
+     int, const char *)'
+
+ -- Function: void gcry_set_fatalerror_handler (gcry_handler_error_t
+          FUNC_ERROR, void *CB_DATA)
+     This function registers FUNC_ERROR as 'error handler', which means
+     that it will be called in error conditions.
+
+\1f
+File: gcrypt.info,  Node: Logging handler,  Prev: Error handler,  Up: Handler Functions
+
+4.4 Logging handler
+===================
+
+ -- Data type: gcry_handler_log_t
+     This type is defined as: 'void (*gcry_handler_log_t) (void *, int,
+     const char *, va_list)'
+
+ -- Function: void gcry_set_log_handler (gcry_handler_log_t FUNC_LOG,
+          void *CB_DATA)
+     This function registers FUNC_LOG as 'logging handler', which means
+     that it will be called in case Libgcrypt wants to log a message.
+     This function may and should be used prior to calling
+     'gcry_check_version'.
+
+\1f
+File: gcrypt.info,  Node: Symmetric cryptography,  Next: Public Key cryptography,  Prev: Handler Functions,  Up: Top
+
+5 Symmetric cryptography
+************************
+
+The cipher functions are used for symmetrical cryptography, i.e.
+cryptography using a shared key.  The programming model follows an
+open/process/close paradigm and is in that similar to other building
+blocks provided by Libgcrypt.
+
+* Menu:
+
+* Available ciphers::           List of ciphers supported by the library.
+* Available cipher modes::      List of cipher modes supported by the library.
+* Working with cipher handles::  How to perform operations related to cipher handles.
+* General cipher functions::    General cipher functions independent of cipher handles.
+
+\1f
+File: gcrypt.info,  Node: Available ciphers,  Next: Available cipher modes,  Up: Symmetric cryptography
+
+5.1 Available ciphers
+=====================
+
+'GCRY_CIPHER_NONE'
+     This is not a real algorithm but used by some functions as error
+     return.  The value always evaluates to false.
+
+'GCRY_CIPHER_IDEA'
+     This is the IDEA algorithm.
+
+'GCRY_CIPHER_3DES'
+     Triple-DES with 3 Keys as EDE. The key size of this algorithm is
+     168 but you have to pass 192 bits because the most significant bits
+     of each byte are ignored.
+
+'GCRY_CIPHER_CAST5'
+     CAST128-5 block cipher algorithm.  The key size is 128 bits.
+
+'GCRY_CIPHER_BLOWFISH'
+     The blowfish algorithm.  The current implementation allows only for
+     a key size of 128 bits.
+
+'GCRY_CIPHER_SAFER_SK128'
+     Reserved and not currently implemented.
+
+'GCRY_CIPHER_DES_SK'
+     Reserved and not currently implemented.
+
+'GCRY_CIPHER_AES'
+'GCRY_CIPHER_AES128'
+'GCRY_CIPHER_RIJNDAEL'
+'GCRY_CIPHER_RIJNDAEL128'
+     AES (Rijndael) with a 128 bit key.
+
+'GCRY_CIPHER_AES192'
+'GCRY_CIPHER_RIJNDAEL192'
+     AES (Rijndael) with a 192 bit key.
+
+'GCRY_CIPHER_AES256'
+'GCRY_CIPHER_RIJNDAEL256'
+     AES (Rijndael) with a 256 bit key.
+
+'GCRY_CIPHER_TWOFISH'
+     The Twofish algorithm with a 256 bit key.
+
+'GCRY_CIPHER_TWOFISH128'
+     The Twofish algorithm with a 128 bit key.
+
+'GCRY_CIPHER_ARCFOUR'
+     An algorithm which is 100% compatible with RSA Inc.'s RC4
+     algorithm.  Note that this is a stream cipher and must be used very
+     carefully to avoid a couple of weaknesses.
+
+'GCRY_CIPHER_DES'
+     Standard DES with a 56 bit key.  You need to pass 64 bit but the
+     high bits of each byte are ignored.  Note, that this is a weak
+     algorithm which can be broken in reasonable time using a brute
+     force approach.
+
+'GCRY_CIPHER_SERPENT128'
+'GCRY_CIPHER_SERPENT192'
+'GCRY_CIPHER_SERPENT256'
+     The Serpent cipher from the AES contest.
+
+'GCRY_CIPHER_RFC2268_40'
+'GCRY_CIPHER_RFC2268_128'
+     Ron's Cipher 2 in the 40 and 128 bit variants.
+
+'GCRY_CIPHER_SEED'
+     A 128 bit cipher as described by RFC4269.
+
+'GCRY_CIPHER_CAMELLIA128'
+'GCRY_CIPHER_CAMELLIA192'
+'GCRY_CIPHER_CAMELLIA256'
+     The Camellia cipher by NTT. See
+     <http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html>.
+
+'GCRY_CIPHER_SALSA20'
+     This is the Salsa20 stream cipher.
+
+'GCRY_CIPHER_SALSA20R12'
+     This is the Salsa20/12 - reduced round version of Salsa20 stream
+     cipher.
+
+'GCRY_CIPHER_GOST28147'
+     The GOST 28147-89 cipher, defined in the respective GOST standard.
+     Translation of this GOST into English is provided in the RFC-5830.
+
+'GCRY_CIPHER_CHACHA20'
+     This is the ChaCha20 stream cipher.
+
+\1f
+File: gcrypt.info,  Node: Available cipher modes,  Next: Working with cipher handles,  Prev: Available ciphers,  Up: Symmetric cryptography
+
+5.2 Available cipher modes
+==========================
+
+'GCRY_CIPHER_MODE_NONE'
+     No mode specified.  This should not be used.  The only exception is
+     that if Libgcrypt is not used in FIPS mode and if any debug flag
+     has been set, this mode may be used to bypass the actual
+     encryption.
+
+'GCRY_CIPHER_MODE_ECB'
+     Electronic Codebook mode.
+
+'GCRY_CIPHER_MODE_CFB'
+'GCRY_CIPHER_MODE_CFB8'
+     Cipher Feedback mode.  For GCRY_CIPHER_MODE_CFB the shift size
+     equals the block size of the cipher (e.g.  for AES it is CFB-128).
+     For GCRY_CIPHER_MODE_CFB8 the shift size is 8 bit but that variant
+     is not yet available.
+
+'GCRY_CIPHER_MODE_CBC'
+     Cipher Block Chaining mode.
+
+'GCRY_CIPHER_MODE_STREAM'
+     Stream mode, only to be used with stream cipher algorithms.
+
+'GCRY_CIPHER_MODE_OFB'
+     Output Feedback mode.
+
+'GCRY_CIPHER_MODE_CTR'
+     Counter mode.
+
+'GCRY_CIPHER_MODE_AESWRAP'
+     This mode is used to implement the AES-Wrap algorithm according to
+     RFC-3394.  It may be used with any 128 bit block length algorithm,
+     however the specs require one of the 3 AES algorithms.  These
+     special conditions apply: If 'gcry_cipher_setiv' has not been used
+     the standard IV is used; if it has been used the lower 64 bit of
+     the IV are used as the Alternative Initial Value.  On encryption
+     the provided output buffer must be 64 bit (8 byte) larger than the
+     input buffer; in-place encryption is still allowed.  On decryption
+     the output buffer may be specified 64 bit (8 byte) shorter than
+     then input buffer.  As per specs the input length must be at least
+     128 bits and the length must be a multiple of 64 bits.
+
+'GCRY_CIPHER_MODE_CCM'
+     Counter with CBC-MAC mode is an Authenticated Encryption with
+     Associated Data (AEAD) block cipher mode, which is specified in
+     'NIST Special Publication 800-38C' and RFC 3610.
+
+'GCRY_CIPHER_MODE_GCM'
+     Galois/Counter Mode (GCM) is an Authenticated Encryption with
+     Associated Data (AEAD) block cipher mode, which is specified in
+     'NIST Special Publication 800-38D'.
+
+'GCRY_CIPHER_MODE_POLY1305'
+     This mode implements the Poly1305 Authenticated Encryption with
+     Associated Data (AEAD) mode according to RFC-7539.  This mode can
+     be used with ChaCha20 stream cipher.
+
+'GCRY_CIPHER_MODE_OCB'
+     OCB is an Authenticated Encryption with Associated Data (AEAD)
+     block cipher mode, which is specified in RFC-7253.  Supported tag
+     lengths are 128, 96, and 64 bit with the default being 128 bit.  To
+     switch to a different tag length 'gcry_cipher_ctl' using the
+     command 'GCRYCTL_SET_TAGLEN' and the address of an 'int' variable
+     set to 12 (for 96 bit) or 8 (for 64 bit) provided for the 'buffer'
+     argument and 'sizeof(int)' for 'buflen'.
+
+     Note that the use of 'gcry_cipher_final' is required.
+
+\1f
+File: gcrypt.info,  Node: Working with cipher handles,  Next: General cipher functions,  Prev: Available cipher modes,  Up: Symmetric cryptography
+
+5.3 Working with cipher handles
+===============================
+
+To use a cipher algorithm, you must first allocate an according handle.
+This is to be done using the open function:
+
+ -- Function: gcry_error_t gcry_cipher_open (gcry_cipher_hd_t *HD, int
+          ALGO, int MODE, unsigned int FLAGS)
+
+     This function creates the context handle required for most of the
+     other cipher functions and returns a handle to it in 'hd'.  In case
+     of an error, an according error code is returned.
+
+     The ID of algorithm to use must be specified via ALGO.  See *Note
+     Available ciphers::, for a list of supported ciphers and the
+     according constants.
+
+     Besides using the constants directly, the function
+     'gcry_cipher_map_name' may be used to convert the textual name of
+     an algorithm into the according numeric ID.
+
+     The cipher mode to use must be specified via MODE.  See *Note
+     Available cipher modes::, for a list of supported cipher modes and
+     the according constants.  Note that some modes are incompatible
+     with some algorithms - in particular, stream mode
+     ('GCRY_CIPHER_MODE_STREAM') only works with stream ciphers.
+     Poly1305 AEAD mode ('GCRY_CIPHER_MODE_POLY1305') only works with
+     ChaCha20 stream cipher.  The block cipher modes
+     ('GCRY_CIPHER_MODE_ECB', 'GCRY_CIPHER_MODE_CBC',
+     'GCRY_CIPHER_MODE_CFB', 'GCRY_CIPHER_MODE_OFB' and
+     'GCRY_CIPHER_MODE_CTR') will work with any block cipher algorithm.
+     GCM mode ('GCRY_CIPHER_MODE_CCM'), CCM mode
+     ('GCRY_CIPHER_MODE_GCM'), and OCB mode ('GCRY_CIPHER_MODE_OCB')
+     will only work with block cipher algorithms which have the block
+     size of 16 bytes.
+
+     The third argument FLAGS can either be passed as '0' or as the
+     bit-wise OR of the following constants.
+
+     'GCRY_CIPHER_SECURE'
+          Make sure that all operations are allocated in secure memory.
+          This is useful when the key material is highly confidential.
+     'GCRY_CIPHER_ENABLE_SYNC'
+          This flag enables the CFB sync mode, which is a special
+          feature of Libgcrypt's CFB mode implementation to allow for
+          OpenPGP's CFB variant.  See 'gcry_cipher_sync'.
+     'GCRY_CIPHER_CBC_CTS'
+          Enable cipher text stealing (CTS) for the CBC mode.  Cannot be
+          used simultaneous as GCRY_CIPHER_CBC_MAC. CTS mode makes it
+          possible to transform data of almost arbitrary size (only
+          limitation is that it must be greater than the algorithm's
+          block size).
+     'GCRY_CIPHER_CBC_MAC'
+          Compute CBC-MAC keyed checksums.  This is the same as CBC
+          mode, but only output the last block.  Cannot be used
+          simultaneous as GCRY_CIPHER_CBC_CTS.
+
+   Use the following function to release an existing handle:
+
+ -- Function: void gcry_cipher_close (gcry_cipher_hd_t H)
+
+     This function releases the context created by 'gcry_cipher_open'.
+     It also zeroises all sensitive information associated with this
+     cipher handle.
+
+   In order to use a handle for performing cryptographic operations, a
+'key' has to be set first:
+
+ -- Function: gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t H, const
+          void *K, size_t L)
+
+     Set the key K used for encryption or decryption in the context
+     denoted by the handle H.  The length L (in bytes) of the key K must
+     match the required length of the algorithm set for this context or
+     be in the allowed range for algorithms with variable key size.  The
+     function checks this and returns an error if there is a problem.  A
+     caller should always check for an error.
+
+   Most crypto modes requires an initialization vector (IV), which
+usually is a non-secret random string acting as a kind of salt value.
+The CTR mode requires a counter, which is also similar to a salt value.
+To set the IV or CTR, use these functions:
+
+ -- Function: gcry_error_t gcry_cipher_setiv (gcry_cipher_hd_t H, const
+          void *K, size_t L)
+
+     Set the initialization vector used for encryption or decryption.
+     The vector is passed as the buffer K of length L bytes and copied
+     to internal data structures.  The function checks that the IV
+     matches the requirement of the selected algorithm and mode.
+
+     This function is also used by AEAD modes and with Salsa20 and
+     ChaCha20 stream ciphers to set or update the required nonce.  In
+     these cases it needs to be called after setting the key.
+
+ -- Function: gcry_error_t gcry_cipher_setctr (gcry_cipher_hd_t H, const
+          void *C, size_t L)
+
+     Set the counter vector used for encryption or decryption.  The
+     counter is passed as the buffer C of length L bytes and copied to
+     internal data structures.  The function checks that the counter
+     matches the requirement of the selected algorithm (i.e., it must be
+     the same size as the block size).
+
+ -- Function: gcry_error_t gcry_cipher_reset (gcry_cipher_hd_t H)
+
+     Set the given handle's context back to the state it had after the
+     last call to gcry_cipher_setkey and clear the initialization
+     vector.
+
+     Note that gcry_cipher_reset is implemented as a macro.
+
+   Authenticated Encryption with Associated Data (AEAD) block cipher
+modes require the handling of the authentication tag and the additional
+authenticated data, which can be done by using the following functions:
+
+ -- Function: gcry_error_t gcry_cipher_authenticate (gcry_cipher_hd_t H,
+          const void *ABUF, size_t ABUFLEN)
+
+     Process the buffer ABUF of length ABUFLEN as the additional
+     authenticated data (AAD) for AEAD cipher modes.
+
+ -- Function: gcry_error_t gcry_cipher_gettag (gcry_cipher_hd_t H,
+          void *TAG, size_t TAGLEN)
+
+     This function is used to read the authentication tag after
+     encryption.  The function finalizes and outputs the authentication
+     tag to the buffer TAG of length TAGLEN bytes.
+
+     Depending on the used mode certain restrictions for TAGLEN are
+     enforced: For GCM TAGLEN must be at least 16 or one of the allowed
+     truncated lengths (4, 8, 12, 13, 14, or 15).
+
+ -- Function: gcry_error_t gcry_cipher_checktag (gcry_cipher_hd_t H,
+          const void *TAG, size_t TAGLEN)
+
+     Check the authentication tag after decryption.  The authentication
+     tag is passed as the buffer TAG of length TAGLEN bytes and compared
+     to internal authentication tag computed during decryption.  Error
+     code 'GPG_ERR_CHECKSUM' is returned if the authentication tag in
+     the buffer TAG does not match the authentication tag calculated
+     during decryption.
+
+     Depending on the used mode certain restrictions for TAGLEN are
+     enforced: For GCM TAGLEN must either be 16 or one of the allowed
+     truncated lengths (4, 8, 12, 13, 14, or 15).
+
+   The actual encryption and decryption is done by using one of the
+following functions.  They may be used as often as required to process
+all the data.
+
+ -- Function: gcry_error_t gcry_cipher_encrypt (gcry_cipher_hd_t H,
+          unsigned char *out, size_t OUTSIZE, const unsigned char *IN,
+          size_t INLEN)
+
+     'gcry_cipher_encrypt' is used to encrypt the data.  This function
+     can either work in place or with two buffers.  It uses the cipher
+     context already setup and described by the handle H.  There are 2
+     ways to use the function: If IN is passed as 'NULL' and INLEN is
+     '0', in-place encryption of the data in OUT of length OUTSIZE takes
+     place.  With IN being not 'NULL', INLEN bytes are encrypted to the
+     buffer OUT which must have at least a size of INLEN.  OUTSIZE must
+     be set to the allocated size of OUT, so that the function can check
+     that there is sufficient space.  Note that overlapping buffers are
+     not allowed.
+
+     Depending on the selected algorithms and encryption mode, the
+     length of the buffers must be a multiple of the block size.
+
+     Some encryption modes require that 'gcry_cipher_final' is used
+     before the final data chunk is passed to this function.
+
+     The function returns '0' on success or an error code.
+
+ -- Function: gcry_error_t gcry_cipher_decrypt (gcry_cipher_hd_t H,
+          unsigned char *out, size_t OUTSIZE, const unsigned char *IN,
+          size_t INLEN)
+
+     'gcry_cipher_decrypt' is used to decrypt the data.  This function
+     can either work in place or with two buffers.  It uses the cipher
+     context already setup and described by the handle H.  There are 2
+     ways to use the function: If IN is passed as 'NULL' and INLEN is
+     '0', in-place decryption of the data in OUT or length OUTSIZE takes
+     place.  With IN being not 'NULL', INLEN bytes are decrypted to the
+     buffer OUT which must have at least a size of INLEN.  OUTSIZE must
+     be set to the allocated size of OUT, so that the function can check
+     that there is sufficient space.  Note that overlapping buffers are
+     not allowed.
+
+     Depending on the selected algorithms and encryption mode, the
+     length of the buffers must be a multiple of the block size.
+
+     Some encryption modes require that 'gcry_cipher_final' is used
+     before the final data chunk is passed to this function.
+
+     The function returns '0' on success or an error code.
+
+   The OCB mode features integrated padding and must thus be told about
+the end of the input data.  This is done with:
+
+ -- Function: gcry_error_t gcry_cipher_final (gcry_cipher_hd_t H)
+
+     Set a flag in the context to tell the encrypt and decrypt functions
+     that their next call will provide the last chunk of data.  Only the
+     first call to this function has an effect and only for modes which
+     support it.  Checking the error is in general not necessary.  This
+     is implemented as a macro.
+
+   OpenPGP (as defined in RFC-4880) requires a special sync operation in
+some places.  The following function is used for this:
+
+ -- Function: gcry_error_t gcry_cipher_sync (gcry_cipher_hd_t H)
+
+     Perform the OpenPGP sync operation on context H.  Note that this is
+     a no-op unless the context was created with the flag
+     'GCRY_CIPHER_ENABLE_SYNC'
+
+   Some of the described functions are implemented as macros utilizing a
+catch-all control function.  This control function is rarely used
+directly but there is nothing which would inhibit it:
+
+ -- Function: gcry_error_t gcry_cipher_ctl (gcry_cipher_hd_t H, int CMD,
+          void *BUFFER, size_t BUFLEN)
+
+     'gcry_cipher_ctl' controls various aspects of the cipher module and
+     specific cipher contexts.  Usually some more specialized functions
+     or macros are used for this purpose.  The semantics of the function
+     and its parameters depends on the the command CMD and the passed
+     context handle H.  Please see the comments in the source code
+     ('src/global.c') for details.
+
+ -- Function: gcry_error_t gcry_cipher_info (gcry_cipher_hd_t H, int
+          WHAT, void *BUFFER, size_t *NBYTES)
+
+     'gcry_cipher_info' is used to retrieve various information about a
+     cipher context or the cipher module in general.
+
+     'GCRYCTL_GET_TAGLEN:'
+          Return the length of the tag for an AE algorithm mode.  An
+          error is returned for modes which do not support a tag.
+          BUFFER must be given as NULL. On success the result is stored
+          NBYTES.  The taglen is returned in bytes.
+
+\1f
+File: gcrypt.info,  Node: General cipher functions,  Prev: Working with cipher handles,  Up: Symmetric cryptography
+
+5.4 General cipher functions
+============================
+
+To work with the algorithms, several functions are available to map
+algorithm names to the internal identifiers, as well as ways to retrieve
+information about an algorithm or the current cipher context.
+
+ -- Function: gcry_error_t gcry_cipher_algo_info (int ALGO, int WHAT,
+          void *BUFFER, size_t *NBYTES)
+
+     This function is used to retrieve information on a specific
+     algorithm.  You pass the cipher algorithm ID as ALGO and the type
+     of information requested as WHAT.  The result is either returned as
+     the return code of the function or copied to the provided BUFFER
+     whose allocated length must be available in an integer variable
+     with the address passed in NBYTES.  This variable will also receive
+     the actual used length of the buffer.
+
+     Here is a list of supported codes for WHAT:
+
+     'GCRYCTL_GET_KEYLEN:'
+          Return the length of the key.  If the algorithm supports
+          multiple key lengths, the maximum supported value is returned.
+          The length is returned as number of octets (bytes) and not as
+          number of bits in NBYTES; BUFFER must be zero.  Note that it
+          is usually better to use the convenience function
+          'gcry_cipher_get_algo_keylen'.
+
+     'GCRYCTL_GET_BLKLEN:'
+          Return the block length of the algorithm.  The length is
+          returned as a number of octets in NBYTES; BUFFER must be zero.
+          Note that it is usually better to use the convenience function
+          'gcry_cipher_get_algo_blklen'.
+
+     'GCRYCTL_TEST_ALGO:'
+          Returns '0' when the specified algorithm is available for use.
+          BUFFER and NBYTES must be zero.
+
+ -- Function: size_t gcry_cipher_get_algo_keylen (ALGO)
+
+     This function returns length of the key for algorithm ALGO.  If the
+     algorithm supports multiple key lengths, the maximum supported key
+     length is returned.  On error '0' is returned.  The key length is
+     returned as number of octets.
+
+     This is a convenience functions which should be preferred over
+     'gcry_cipher_algo_info' because it allows for proper type checking.
+
+ -- Function: size_t gcry_cipher_get_algo_blklen (int ALGO)
+
+     This functions returns the block-length of the algorithm ALGO
+     counted in octets.  On error '0' is returned.
+
+     This is a convenience functions which should be preferred over
+     'gcry_cipher_algo_info' because it allows for proper type checking.
+
+ -- Function: const char * gcry_cipher_algo_name (int ALGO)
+
+     'gcry_cipher_algo_name' returns a string with the name of the
+     cipher algorithm ALGO.  If the algorithm is not known or another
+     error occurred, the string '"?"' is returned.  This function should
+     not be used to test for the availability of an algorithm.
+
+ -- Function: int gcry_cipher_map_name (const char *NAME)
+
+     'gcry_cipher_map_name' returns the algorithm identifier for the
+     cipher algorithm described by the string NAME.  If this algorithm
+     is not available '0' is returned.
+
+ -- Function: int gcry_cipher_mode_from_oid (const char *STRING)
+
+     Return the cipher mode associated with an ASN.1 object identifier.
+     The object identifier is expected to be in the IETF-style dotted
+     decimal notation.  The function returns '0' for an unknown object
+     identifier or when no mode is associated with it.
+
+\1f
+File: gcrypt.info,  Node: Public Key cryptography,  Next: Hashing,  Prev: Symmetric cryptography,  Up: Top
+
+6 Public Key cryptography
+*************************
+
+Public key cryptography, also known as asymmetric cryptography, is an
+easy way for key management and to provide digital signatures.
+Libgcrypt provides two completely different interfaces to public key
+cryptography, this chapter explains the one based on S-expressions.
+
+* Menu:
+
+* Available algorithms::        Algorithms supported by the library.
+* Used S-expressions::          Introduction into the used S-expression.
+* Cryptographic Functions::     Functions for performing the cryptographic actions.
+* General public-key related Functions::  General functions, not implementing any cryptography.
+
+\1f
+File: gcrypt.info,  Node: Available algorithms,  Next: Used S-expressions,  Up: Public Key cryptography
+
+6.1 Available algorithms
+========================
+
+Libgcrypt supports the RSA (Rivest-Shamir-Adleman) algorithms as well as
+DSA (Digital Signature Algorithm) and Elgamal.  The versatile interface
+allows to add more algorithms in the future.
+
+\1f
+File: gcrypt.info,  Node: Used S-expressions,  Next: Cryptographic Functions,  Prev: Available algorithms,  Up: Public Key cryptography
+
+6.2 Used S-expressions
+======================
+
+Libgcrypt's API for asymmetric cryptography is based on data structures
+called S-expressions (see
+<http://people.csail.mit.edu/rivest/sexp.html>) and does not work with
+contexts as most of the other building blocks of Libgcrypt do.
+
+The following information are stored in S-expressions:
+
+   * keys
+
+   * plain text data
+
+   * encrypted data
+
+   * signatures
+
+To describe how Libgcrypt expect keys, we use examples.  Note that words
+in uppercase indicate parameters whereas lowercase words are literals.
+
+   Note that all MPI (multi-precision-integers) values are expected to
+be in 'GCRYMPI_FMT_USG' format.  An easy way to create S-expressions is
+by using 'gcry_sexp_build' which allows to pass a string with
+printf-like escapes to insert MPI values.
+
+* Menu:
+
+* RSA key parameters::  Parameters used with an RSA key.
+* DSA key parameters::  Parameters used with a DSA key.
+* ECC key parameters::  Parameters used with ECC keys.
+
+\1f
+File: gcrypt.info,  Node: RSA key parameters,  Next: DSA key parameters,  Up: Used S-expressions
+
+6.2.1 RSA key parameters
+------------------------
+
+An RSA private key is described by this S-expression:
+
+     (private-key
+       (rsa
+         (n N-MPI)
+         (e E-MPI)
+         (d D-MPI)
+         (p P-MPI)
+         (q Q-MPI)
+         (u U-MPI)))
+
+An RSA public key is described by this S-expression:
+
+     (public-key
+       (rsa
+         (n N-MPI)
+         (e E-MPI)))
+
+N-MPI
+     RSA public modulus n.
+E-MPI
+     RSA public exponent e.
+D-MPI
+     RSA secret exponent d = e^{-1} \bmod (p-1)(q-1).
+P-MPI
+     RSA secret prime p.
+Q-MPI
+     RSA secret prime q with p < q.
+U-MPI
+     Multiplicative inverse u = p^{-1} \bmod q.
+
+   For signing and decryption the parameters (p, q, u) are optional but
+greatly improve the performance.  Either all of these optional
+parameters must be given or none of them.  They are mandatory for
+gcry_pk_testkey.
+
+   Note that OpenSSL uses slighly different parameters: q < p and u =
+q^{-1} \bmod p.  To use these parameters you will need to swap the
+values and recompute u.  Here is example code to do this:
+
+       if (gcry_mpi_cmp (p, q) > 0)
+         {
+           gcry_mpi_swap (p, q);
+           gcry_mpi_invm (u, p, q);
+         }
+
+\1f
+File: gcrypt.info,  Node: DSA key parameters,  Next: ECC key parameters,  Prev: RSA key parameters,  Up: Used S-expressions
+
+6.2.2 DSA key parameters
+------------------------
+
+A DSA private key is described by this S-expression:
+
+     (private-key
+       (dsa
+         (p P-MPI)
+         (q Q-MPI)
+         (g G-MPI)
+         (y Y-MPI)
+         (x X-MPI)))
+
+P-MPI
+     DSA prime p.
+Q-MPI
+     DSA group order q (which is a prime divisor of p-1).
+G-MPI
+     DSA group generator g.
+Y-MPI
+     DSA public key value y = g^x \bmod p.
+X-MPI
+     DSA secret exponent x.
+
+   The public key is similar with "private-key" replaced by "public-key"
+and no X-MPI.
+
+\1f
+File: gcrypt.info,  Node: ECC key parameters,  Prev: DSA key parameters,  Up: Used S-expressions
+
+6.2.3 ECC key parameters
+------------------------
+
+An ECC private key is described by this S-expression:
+
+     (private-key
+       (ecc
+         (p P-MPI)
+         (a A-MPI)
+         (b B-MPI)
+         (g G-POINT)
+         (n N-MPI)
+         (q Q-POINT)
+         (d D-MPI)))
+
+P-MPI
+     Prime specifying the field GF(p).
+A-MPI
+B-MPI
+     The two coefficients of the Weierstrass equation y^2 = x^3 + ax + b
+G-POINT
+     Base point g.
+N-MPI
+     Order of g
+Q-POINT
+     The point representing the public key Q = dG.
+D-MPI
+     The private key d
+
+   All point values are encoded in standard format; Libgcrypt does in
+general only support uncompressed points, thus the first byte needs to
+be '0x04'.  However "EdDSA" describes its own compression scheme which
+is used by default; the non-standard first byte '0x40' may optionally be
+used to explicit flag the use of the algorithm’s native compression
+method.
+
+   The public key is similar with "private-key" replaced by "public-key"
+and no D-MPI.
+
+   If the domain parameters are well-known, the name of this curve may
+be used.  For example
+
+     (private-key
+       (ecc
+         (curve "NIST P-192")
+         (q Q-POINT)
+         (d D-MPI)))
+
+   Note that Q-POINT is optional for a private key.  The 'curve'
+parameter may be given in any case and is used to replace missing
+parameters.
+
+Currently implemented curves are:
+'NIST P-192'
+'1.2.840.10045.3.1.1'
+'prime192v1'
+'secp192r1'
+     The NIST 192 bit curve, its OID, X9.62 and SECP aliases.
+
+'NIST P-224'
+'secp224r1'
+     The NIST 224 bit curve and its SECP alias.
+
+'NIST P-256'
+'1.2.840.10045.3.1.7'
+'prime256v1'
+'secp256r1'
+     The NIST 256 bit curve, its OID, X9.62 and SECP aliases.
+
+'NIST P-384'
+'secp384r1'
+     The NIST 384 bit curve and its SECP alias.
+
+'NIST P-521'
+'secp521r1'
+     The NIST 521 bit curve and its SECP alias.
+
+   As usual the OIDs may optionally be prefixed with the string 'OID.'
+or 'oid.'.
+
+\1f
+File: gcrypt.info,  Node: Cryptographic Functions,  Next: General public-key related Functions,  Prev: Used S-expressions,  Up: Public Key cryptography
+
+6.3 Cryptographic Functions
+===========================
+
+Some functions operating on S-expressions support 'flags' to influence
+the operation.  These flags have to be listed in a sub-S-expression
+named 'flags'.  Flag names are case-sensitive.  The following flags are
+known:
+
+'comp'
+'nocomp'
+     If supported by the algorithm and curve the 'comp' flag requests
+     that points are returned in compact (compressed) representation.
+     The 'nocomp' flag requests that points are returned with full
+     coordinates.  The default depends on the the algorithm and curve.
+     The compact representation requires a small overhead before a point
+     can be used but halves the size of a to be conveyed public key.  If
+     'comp' is used with the "EdDSA" algorithm the key generation prefix
+     the public key with a '0x40' byte.
+
+'pkcs1'
+     Use PKCS#1 block type 2 padding for encryption, block type 1
+     padding for signing.
+
+'oaep'
+     Use RSA-OAEP padding for encryption.
+
+'pss'
+     Use RSA-PSS padding for signing.
+
+'eddsa'
+     Use the EdDSA scheme signing instead of the default ECDSA
+     algorithm.  Note that the EdDSA uses a special form of the public
+     key.
+
+'rfc6979'
+     For DSA and ECDSA use a deterministic scheme for the k parameter.
+
+'no-blinding'
+     Do not use a technique called 'blinding', which is used by default
+     in order to prevent leaking of secret information.  Blinding is
+     only implemented by RSA, but it might be implemented by other
+     algorithms in the future as well, when necessary.
+
+'param'
+     For ECC key generation also return the domain parameters.  For ECC
+     signing and verification override default parameters by provided
+     domain parameters of the public or private key.
+
+'transient-key'
+     This flag is only meaningful for RSA, DSA, and ECC key generation.
+     If given the key is created using a faster and a somewhat less
+     secure random number generator.  This flag may be used for keys
+     which are only used for a short time or per-message and do not
+     require full cryptographic strength.
+
+'no-keytest'
+     This flag skips internal failsafe tests to assert that a generated
+     key is properly working.  It currently has an effect only for
+     standard ECC key generation.  It is mostly useful along with
+     transient-key to achieve fastest ECC key generation.
+
+'use-x931'
+     Force the use of the ANSI X9.31 key generation algorithm instead of
+     the default algorithm.  This flag is only meaningful for RSA key
+     generation and usually not required.  Note that this algorithm is
+     implicitly used if either 'derive-parms' is given or Libgcrypt is
+     in FIPS mode.
+
+'use-fips186'
+     Force the use of the FIPS 186 key generation algorithm instead of
+     the default algorithm.  This flag is only meaningful for DSA and
+     usually not required.  Note that this algorithm is implicitly used
+     if either 'derive-parms' is given or Libgcrypt is in FIPS mode.  As
+     of now FIPS 186-2 is implemented; after the approval of FIPS 186-3
+     the code will be changed to implement 186-3.
+
+'use-fips186-2'
+     Force the use of the FIPS 186-2 key generation algorithm instead of
+     the default algorithm.  This algorithm is slightly different from
+     FIPS 186-3 and allows only 1024 bit keys.  This flag is only
+     meaningful for DSA and only required for FIPS testing backward
+     compatibility.
+
+Now that we know the key basics, we can carry on and explain how to
+encrypt and decrypt data.  In almost all cases the data is a random
+session key which is in turn used for the actual encryption of the real
+data.  There are 2 functions to do this:
+
+ -- Function: gcry_error_t gcry_pk_encrypt (gcry_sexp_t *R_CIPH, gcry_sexp_t DATA,
+          gcry_sexp_t PKEY)
+
+     Obviously a public key must be provided for encryption.  It is
+     expected as an appropriate S-expression (see above) in PKEY.  The
+     data to be encrypted can either be in the simple old format, which
+     is a very simple S-expression consisting only of one MPI, or it may
+     be a more complex S-expression which also allows to specify flags
+     for operation, like e.g.  padding rules.
+
+     If you don't want to let Libgcrypt handle the padding, you must
+     pass an appropriate MPI using this expression for DATA:
+
+          (data
+            (flags raw)
+            (value MPI))
+
+     This has the same semantics as the old style MPI only way.  MPI is
+     the actual data, already padded appropriate for your protocol.
+     Most RSA based systems however use PKCS#1 padding and so you can
+     use this S-expression for DATA:
+
+          (data
+            (flags pkcs1)
+            (value BLOCK))
+
+     Here, the "flags" list has the "pkcs1" flag which let the function
+     know that it should provide PKCS#1 block type 2 padding.  The
+     actual data to be encrypted is passed as a string of octets in
+     BLOCK.  The function checks that this data actually can be used
+     with the given key, does the padding and encrypts it.
+
+     If the function could successfully perform the encryption, the
+     return value will be 0 and a new S-expression with the encrypted
+     result is allocated and assigned to the variable at the address of
+     R_CIPH.  The caller is responsible to release this value using
+     'gcry_sexp_release'.  In case of an error, an error code is
+     returned and R_CIPH will be set to 'NULL'.
+
+     The returned S-expression has this format when used with RSA:
+
+          (enc-val
+            (rsa
+              (a A-MPI)))
+
+     Where A-MPI is an MPI with the result of the RSA operation.  When
+     using the Elgamal algorithm, the return value will have this
+     format:
+
+          (enc-val
+            (elg
+              (a A-MPI)
+              (b B-MPI)))
+
+     Where A-MPI and B-MPI are MPIs with the result of the Elgamal
+     encryption operation.
+
+ -- Function: gcry_error_t gcry_pk_decrypt (gcry_sexp_t *R_PLAIN, gcry_sexp_t DATA,
+          gcry_sexp_t SKEY)
+
+     Obviously a private key must be provided for decryption.  It is
+     expected as an appropriate S-expression (see above) in SKEY.  The
+     data to be decrypted must match the format of the result as
+     returned by 'gcry_pk_encrypt', but should be enlarged with a
+     'flags' element:
+
+          (enc-val
+            (flags)
+            (elg
+              (a A-MPI)
+              (b B-MPI)))
+
+     This function does not remove padding from the data by default.  To
+     let Libgcrypt remove padding, give a hint in 'flags' telling which
+     padding method was used when encrypting:
+
+          (flags PADDING-METHOD)
+
+     Currently PADDING-METHOD is either 'pkcs1' for PKCS#1 block type 2
+     padding, or 'oaep' for RSA-OAEP padding.
+
+     The function returns 0 on success or an error code.  The variable
+     at the address of R_PLAIN will be set to NULL on error or receive
+     the decrypted value on success.  The format of R_PLAIN is a simple
+     S-expression part (i.e.  not a valid one) with just one MPI if
+     there was no 'flags' element in DATA; if at least an empty 'flags'
+     is passed in DATA, the format is:
+
+          (value PLAINTEXT)
+
+   Another operation commonly performed using public key cryptography is
+signing data.  In some sense this is even more important than encryption
+because digital signatures are an important instrument for key
+management.  Libgcrypt supports digital signatures using 2 functions,
+similar to the encryption functions:
+
+ -- Function: gcry_error_t gcry_pk_sign (gcry_sexp_t *R_SIG, gcry_sexp_t DATA,
+          gcry_sexp_t SKEY)
+
+     This function creates a digital signature for DATA using the
+     private key SKEY and place it into the variable at the address of
+     R_SIG.  DATA may either be the simple old style S-expression with
+     just one MPI or a modern and more versatile S-expression which
+     allows to let Libgcrypt handle padding:
+
+           (data
+            (flags pkcs1)
+            (hash HASH-ALGO BLOCK))
+
+     This example requests to sign the data in BLOCK after applying
+     PKCS#1 block type 1 style padding.  HASH-ALGO is a string with the
+     hash algorithm to be encoded into the signature, this may be any
+     hash algorithm name as supported by Libgcrypt.  Most likely, this
+     will be "sha256" or "sha1".  It is obvious that the length of BLOCK
+     must match the size of that message digests; the function checks
+     that this and other constraints are valid.
+
+     If PKCS#1 padding is not required (because the caller does already
+     provide a padded value), either the old format or better the
+     following format should be used:
+
+          (data
+            (flags raw)
+            (value MPI))
+
+     Here, the data to be signed is directly given as an MPI.
+
+     For DSA the input data is expected in this format:
+
+          (data
+            (flags raw)
+            (value MPI))
+
+     Here, the data to be signed is directly given as an MPI.  It is
+     expect that this MPI is the the hash value.  For the standard DSA
+     using a MPI is not a problem in regard to leading zeroes because
+     the hash value is directly used as an MPI. For better standard
+     conformance it would be better to explicit use a memory string
+     (like with pkcs1) but that is currently not supported.  However,
+     for deterministic DSA as specified in RFC6979 this can't be used.
+     Instead the following input is expected.
+
+          (data
+            (flags rfc6979)
+            (hash HASH-ALGO BLOCK))
+
+     Note that the provided hash-algo is used for the internal HMAC; it
+     should match the hash-algo used to create BLOCK.
+
+     The signature is returned as a newly allocated S-expression in
+     R_SIG using this format for RSA:
+
+          (sig-val
+            (rsa
+              (s S-MPI)))
+
+     Where S-MPI is the result of the RSA sign operation.  For DSA the
+     S-expression returned is:
+
+          (sig-val
+            (dsa
+              (r R-MPI)
+              (s S-MPI)))
+
+     Where R-MPI and S-MPI are the result of the DSA sign operation.
+
+     For Elgamal signing (which is slow, yields large numbers and
+     probably is not as secure as the other algorithms), the same format
+     is used with "elg" replacing "dsa"; for ECDSA signing, the same
+     format is used with "ecdsa" replacing "dsa".
+
+     For the EdDSA algorithm (cf.  Ed25515) the required input
+     parameters are:
+
+          (data
+            (flags eddsa)
+            (hash-algo sha512)
+            (value MESSAGE))
+
+     Note that the MESSAGE may be of any length; hashing is part of the
+     algorithm.  Using a large data block for MESSAGE is not suggested;
+     in that case the used protocol should better require that a hash of
+     the message is used as input to the EdDSA algorithm.
+
+The operation most commonly used is definitely the verification of a
+signature.  Libgcrypt provides this function:
+
+ -- Function: gcry_error_t gcry_pk_verify (gcry_sexp_t SIG,
+          gcry_sexp_t DATA, gcry_sexp_t PKEY)
+
+     This is used to check whether the signature SIG matches the DATA.
+     The public key PKEY must be provided to perform this verification.
+     This function is similar in its parameters to 'gcry_pk_sign' with
+     the exceptions that the public key is used instead of the private
+     key and that no signature is created but a signature, in a format
+     as created by 'gcry_pk_sign', is passed to the function in SIG.
+
+     The result is 0 for success (i.e.  the data matches the signature),
+     or an error code where the most relevant code is
+     'GCRY_ERR_BAD_SIGNATURE' to indicate that the signature does not
+     match the provided data.
+
+\1f
+File: gcrypt.info,  Node: General public-key related Functions,  Prev: Cryptographic Functions,  Up: Public Key cryptography
+
+6.4 General public-key related Functions
+========================================
+
+A couple of utility functions are available to retrieve the length of
+the key, map algorithm identifiers and perform sanity checks:
+
+ -- Function: const char * gcry_pk_algo_name (int ALGO)
+
+     Map the public key algorithm id ALGO to a string representation of
+     the algorithm name.  For unknown algorithms this functions returns
+     the string '"?"'.  This function should not be used to test for the
+     availability of an algorithm.
+
+ -- Function: int gcry_pk_map_name (const char *NAME)
+
+     Map the algorithm NAME to a public key algorithm Id.  Returns 0 if
+     the algorithm name is not known.
+
+ -- Function: int gcry_pk_test_algo (int ALGO)
+
+     Return 0 if the public key algorithm ALGO is available for use.
+     Note that this is implemented as a macro.
+
+ -- Function: unsigned int gcry_pk_get_nbits (gcry_sexp_t KEY)
+
+     Return what is commonly referred as the key length for the given
+     public or private in KEY.
+
+ -- Function: unsigned char * gcry_pk_get_keygrip (gcry_sexp_t KEY,
+          unsigned char *ARRAY)
+
+     Return the so called "keygrip" which is the SHA-1 hash of the
+     public key parameters expressed in a way depended on the algorithm.
+     ARRAY must either provide space for 20 bytes or be 'NULL'.  In the
+     latter case a newly allocated array of that size is returned.  On
+     success a pointer to the newly allocated space or to ARRAY is
+     returned.  'NULL' is returned to indicate an error which is most
+     likely an unknown algorithm or one where a "keygrip" has not yet
+     been defined.  The function accepts public or secret keys in KEY.
+
+ -- Function: gcry_error_t gcry_pk_testkey (gcry_sexp_t KEY)
+
+     Return zero if the private key KEY is 'sane', an error code
+     otherwise.  Note that it is not possible to check the 'saneness' of
+     a public key.
+
+ -- Function: gcry_error_t gcry_pk_algo_info (int ALGO, int WHAT,
+          void *BUFFER, size_t *NBYTES)
+
+     Depending on the value of WHAT return various information about the
+     public key algorithm with the id ALGO.  Note that the function
+     returns '-1' on error and the actual error code must be retrieved
+     using the function 'gcry_errno'.  The currently defined values for
+     WHAT are:
+
+     'GCRYCTL_TEST_ALGO:'
+          Return 0 if the specified algorithm is available for use.
+          BUFFER must be 'NULL', NBYTES may be passed as 'NULL' or point
+          to a variable with the required usage of the algorithm.  This
+          may be 0 for "don't care" or the bit-wise OR of these flags:
+
+          'GCRY_PK_USAGE_SIGN'
+               Algorithm is usable for signing.
+          'GCRY_PK_USAGE_ENCR'
+               Algorithm is usable for encryption.
+
+          Unless you need to test for the allowed usage, it is in
+          general better to use the macro gcry_pk_test_algo instead.
+
+     'GCRYCTL_GET_ALGO_USAGE:'
+          Return the usage flags for the given algorithm.  An invalid
+          algorithm return 0.  Disabled algorithms are ignored here
+          because we want to know whether the algorithm is at all
+          capable of a certain usage.
+
+     'GCRYCTL_GET_ALGO_NPKEY'
+          Return the number of elements the public key for algorithm
+          ALGO consist of.  Return 0 for an unknown algorithm.
+
+     'GCRYCTL_GET_ALGO_NSKEY'
+          Return the number of elements the private key for algorithm
+          ALGO consist of.  Note that this value is always larger than
+          that of the public key.  Return 0 for an unknown algorithm.
+
+     'GCRYCTL_GET_ALGO_NSIGN'
+          Return the number of elements a signature created with the
+          algorithm ALGO consists of.  Return 0 for an unknown algorithm
+          or for an algorithm not capable of creating signatures.
+
+     'GCRYCTL_GET_ALGO_NENC'
+          Return the number of elements a encrypted message created with
+          the algorithm ALGO consists of.  Return 0 for an unknown
+          algorithm or for an algorithm not capable of encryption.
+
+     Please note that parameters not required should be passed as
+     'NULL'.
+
+ -- Function: gcry_error_t gcry_pk_ctl (int CMD, void *BUFFER,
+          size_t BUFLEN)
+
+     This is a general purpose function to perform certain control
+     operations.  CMD controls what is to be done.  The return value is
+     0 for success or an error code.  Currently supported values for CMD
+     are:
+
+     'GCRYCTL_DISABLE_ALGO'
+          Disable the algorithm given as an algorithm id in BUFFER.
+          BUFFER must point to an 'int' variable with the algorithm id
+          and BUFLEN must have the value 'sizeof (int)'.  This function
+          is not thread safe and should thus be used before any other
+          threads are started.
+
+Libgcrypt also provides a function to generate public key pairs:
+
+ -- Function: gcry_error_t gcry_pk_genkey (gcry_sexp_t *R_KEY,
+          gcry_sexp_t PARMS)
+
+     This function create a new public key pair using information given
+     in the S-expression PARMS and stores the private and the public key
+     in one new S-expression at the address given by R_KEY.  In case of
+     an error, R_KEY is set to 'NULL'.  The return code is 0 for success
+     or an error code otherwise.
+
+     Here is an example for PARMS to create an 2048 bit RSA key:
+
+          (genkey
+            (rsa
+              (nbits 4:2048)))
+
+     To create an Elgamal key, substitute "elg" for "rsa" and to create
+     a DSA key use "dsa".  Valid ranges for the key length depend on the
+     algorithms; all commonly used key lengths are supported.  Currently
+     supported parameters are:
+
+     'nbits'
+          This is always required to specify the length of the key.  The
+          argument is a string with a number in C-notation.  The value
+          should be a multiple of 8.  Note that the S-expression syntax
+          requires that a number is prefixed with its string length;
+          thus the '4:' in the above example.
+
+     'curve NAME'
+          For ECC a named curve may be used instead of giving the number
+          of requested bits.  This allows to request a specific curve to
+          override a default selection Libgcrypt would have taken if
+          'nbits' has been given.  The available names are listed with
+          the description of the ECC public key parameters.
+
+     'rsa-use-e VALUE'
+          This is only used with RSA to give a hint for the public
+          exponent.  The VALUE will be used as a base to test for a
+          usable exponent.  Some values are special:
+
+          '0'
+               Use a secure and fast value.  This is currently the
+               number 41.
+          '1'
+               Use a value as required by some crypto policies.  This is
+               currently the number 65537.
+          '2'
+               Reserved
+          '> 2'
+               Use the given value.
+
+          If this parameter is not used, Libgcrypt uses for historic
+          reasons 65537.
+
+     'qbits N'
+          This is only meanigful for DSA keys.  If it is given the DSA
+          key is generated with a Q parameyer of size N bits.  If it is
+          not given or zero Q is deduced from NBITS in this way:
+          '512 <= N <= 1024'
+               Q = 160
+          'N = 2048'
+               Q = 224
+          'N = 3072'
+               Q = 256
+          'N = 7680'
+               Q = 384
+          'N = 15360'
+               Q = 512
+          Note that in this case only the values for N, as given in the
+          table, are allowed.  When specifying Q all values of N in the
+          range 512 to 15680 are valid as long as they are multiples of
+          8.
+
+     'domain LIST'
+          This is only meaningful for DLP algorithms.  If specified keys
+          are generated with domain parameters taken from this list.
+          The exact format of this parameter depends on the actual
+          algorithm.  It is currently only implemented for DSA using
+          this format:
+
+               (genkey
+                 (dsa
+                   (domain
+                     (p P-MPI)
+                     (q Q-MPI)
+                     (g Q-MPI))))
+
+          'nbits' and 'qbits' may not be specified because they are
+          derived from the domain parameters.
+
+     'derive-parms LIST'
+          This is currently only implemented for RSA and DSA keys.  It
+          is not allowed to use this together with a 'domain'
+          specification.  If given, it is used to derive the keys using
+          the given parameters.
+
+          If given for an RSA key the X9.31 key generation algorithm is
+          used even if libgcrypt is not in FIPS mode.  If given for a
+          DSA key, the FIPS 186 algorithm is used even if libgcrypt is
+          not in FIPS mode.
+
+               (genkey
+                 (rsa
+                   (nbits 4:1024)
+                   (rsa-use-e 1:3)
+                   (derive-parms
+                     (Xp1 #1A1916DDB29B4EB7EB6732E128#)
+                     (Xp2 #192E8AAC41C576C822D93EA433#)
+                     (Xp  #D8CD81F035EC57EFE822955149D3BFF70C53520D
+                           769D6D76646C7A792E16EBD89FE6FC5B605A6493
+                           39DFC925A86A4C6D150B71B9EEA02D68885F5009
+                           B98BD984#)
+                     (Xq1 #1A5CF72EE770DE50CB09ACCEA9#)
+                     (Xq2 #134E4CAA16D2350A21D775C404#)
+                     (Xq  #CC1092495D867E64065DEE3E7955F2EBC7D47A2D
+                           7C9953388F97DDDC3E1CA19C35CA659EDC2FC325
+                           6D29C2627479C086A699A49C4C9CEE7EF7BD1B34
+                           321DE34A#))))
+
+               (genkey
+                 (dsa
+                   (nbits 4:1024)
+                   (derive-parms
+                     (seed SEED-MPI))))
+
+     'flags FLAGLIST'
+          This is preferred way to define flags.  FLAGLIST may contain
+          any number of flags.  See above for a specification of these
+          flags.
+
+          Here is an example on how to create a key using curve Ed25519
+          with the ECDSA signature algorithm.  Note that the use of
+          ECDSA with that curve is in general not recommended.
+               (genkey
+                 (ecc
+                   (flags transient-key)))
+
+     'transient-key'
+     'use-x931'
+     'use-fips186'
+     'use-fips186-2'
+          These are deprecated ways to set a flag with that name; see
+          above for a description of each flag.
+
+     The key pair is returned in a format depending on the algorithm.
+     Both private and public keys are returned in one container and may
+     be accompanied by some miscellaneous information.
+
+     Here are two examples; the first for Elgamal and the second for
+     elliptic curve key generation:
+
+          (key-data
+            (public-key
+              (elg
+                (p P-MPI)
+                (g G-MPI)
+                (y Y-MPI)))
+            (private-key
+              (elg
+                (p P-MPI)
+                (g G-MPI)
+                (y Y-MPI)
+                (x X-MPI)))
+            (misc-key-info
+              (pm1-factors N1 N2 ... NN))
+
+          (key-data
+            (public-key
+              (ecc
+                (curve Ed25519)
+                (flags eddsa)
+                (q Q-VALUE)))
+            (private-key
+              (ecc
+                (curve Ed25519)
+                (flags eddsa)
+                (q Q-VALUE)
+                (d D-VALUE))))
+
+     As you can see, some of the information is duplicated, but this
+     provides an easy way to extract either the public or the private
+     key.  Note that the order of the elements is not defined, e.g.  the
+     private key may be stored before the public key.  N1 N2 ... NN is a
+     list of prime numbers used to composite P-MPI; this is in general
+     not a very useful information and only available if the key
+     generation algorithm provides them.
+
+Future versions of Libgcrypt will have extended versions of the public
+key interfaced which will take an additional context to allow for
+pre-computations, special operations, and other optimization.  As a
+first step a new function is introduced to help using the ECC algorithms
+in new ways:
+
+ -- Function: gcry_error_t gcry_pubkey_get_sexp (gcry_sexp_t *R_SEXP,
+          int MODE, gcry_ctx_t CTX)
+
+     Return an S-expression representing the context CTX.  Depending on
+     the state of that context, the S-expression may either be a public
+     key, a private key or any other object used with public key
+     operations.  On success 0 is returned and a new S-expression is
+     stored at R_SEXP; on error an error code is returned and NULL is
+     stored at R_SEXP.  MODE must be one of:
+
+     '0'
+          Decide what to return depending on the context.  For example
+          if the private key parameter is available a private key is
+          returned, if not a public key is returned.
+
+     'GCRY_PK_GET_PUBKEY'
+          Return the public key even if the context has the private key
+          parameter.
+
+     'GCRY_PK_GET_SECKEY'
+          Return the private key or the error 'GPG_ERR_NO_SECKEY' if it
+          is not possible.
+
+     As of now this function supports only certain ECC operations
+     because a context object is right now only defined for ECC. Over
+     time this function will be extended to cover more algorithms.
+
+\1f
+File: gcrypt.info,  Node: Hashing,  Next: Message Authentication Codes,  Prev: Public Key cryptography,  Up: Top
+
+7 Hashing
+*********
+
+Libgcrypt provides an easy and consistent to use interface for hashing.
+Hashing is buffered and several hash algorithms can be updated at once.
+It is possible to compute a HMAC using the same routines.  The
+programming model follows an open/process/close paradigm and is in that
+similar to other building blocks provided by Libgcrypt.
+
+   For convenience reasons, a few cyclic redundancy check value
+operations are also supported.
+
+* Menu:
+
+* Available hash algorithms::   List of hash algorithms supported by the library.
+* Working with hash algorithms::  List of functions related to hashing.
+
+\1f
+File: gcrypt.info,  Node: Available hash algorithms,  Next: Working with hash algorithms,  Up: Hashing
+
+7.1 Available hash algorithms
+=============================
+
+'GCRY_MD_NONE'
+     This is not a real algorithm but used by some functions as an error
+     return value.  This constant is guaranteed to have the value '0'.
+
+'GCRY_MD_SHA1'
+     This is the SHA-1 algorithm which yields a message digest of 20
+     bytes.  Note that SHA-1 begins to show some weaknesses and it is
+     suggested to fade out its use if strong cryptographic properties
+     are required.
+
+'GCRY_MD_RMD160'
+     This is the 160 bit version of the RIPE message digest
+     (RIPE-MD-160).  Like SHA-1 it also yields a digest of 20 bytes.
+     This algorithm share a lot of design properties with SHA-1 and thus
+     it is advisable not to use it for new protocols.
+
+'GCRY_MD_MD5'
+     This is the well known MD5 algorithm, which yields a message digest
+     of 16 bytes.  Note that the MD5 algorithm has severe weaknesses,
+     for example it is easy to compute two messages yielding the same
+     hash (collision attack).  The use of this algorithm is only
+     justified for non-cryptographic application.
+
+'GCRY_MD_MD4'
+     This is the MD4 algorithm, which yields a message digest of 16
+     bytes.  This algorithm has severe weaknesses and should not be
+     used.
+
+'GCRY_MD_MD2'
+     This is an reserved identifier for MD-2; there is no implementation
+     yet.  This algorithm has severe weaknesses and should not be used.
+
+'GCRY_MD_TIGER'
+     This is the TIGER/192 algorithm which yields a message digest of 24
+     bytes.  Actually this is a variant of TIGER with a different output
+     print order as used by GnuPG up to version 1.3.2.
+
+'GCRY_MD_TIGER1'
+     This is the TIGER variant as used by the NESSIE project.  It uses
+     the most commonly used output print order.
+
+'GCRY_MD_TIGER2'
+     This is another variant of TIGER with a different padding scheme.
+
+'GCRY_MD_HAVAL'
+     This is an reserved value for the HAVAL algorithm with 5 passes and
+     160 bit.  It yields a message digest of 20 bytes.  Note that there
+     is no implementation yet available.
+
+'GCRY_MD_SHA224'
+     This is the SHA-224 algorithm which yields a message digest of 28
+     bytes.  See Change Notice 1 for FIPS 180-2 for the specification.
+
+'GCRY_MD_SHA256'
+     This is the SHA-256 algorithm which yields a message digest of 32
+     bytes.  See FIPS 180-2 for the specification.
+
+'GCRY_MD_SHA384'
+     This is the SHA-384 algorithm which yields a message digest of 48
+     bytes.  See FIPS 180-2 for the specification.
+
+'GCRY_MD_SHA512'
+     This is the SHA-384 algorithm which yields a message digest of 64
+     bytes.  See FIPS 180-2 for the specification.
+
+'GCRY_MD_SHA3_224'
+     This is the SHA3-224 algorithm which yields a message digest of 28
+     bytes.  See FIPS 202 for the specification.
+
+'GCRY_MD_SHA3_256'
+     This is the SHA3-256 algorithm which yields a message digest of 32
+     bytes.  See FIPS 202 for the specification.
+
+'GCRY_MD_SHA3_384'
+     This is the SHA3-384 algorithm which yields a message digest of 48
+     bytes.  See FIPS 202 for the specification.
+
+'GCRY_MD_SHA3_512'
+     This is the SHA3-384 algorithm which yields a message digest of 64
+     bytes.  See FIPS 202 for the specification.
+
+'GCRY_MD_SHAKE128'
+     This is the SHAKE128 extendable-output function (XOF) algorithm
+     with 128 bit security strength.  See FIPS 202 for the
+     specification.
+
+'GCRY_MD_SHAKE256'
+     This is the SHAKE256 extendable-output function (XOF) algorithm
+     with 256 bit security strength.  See FIPS 202 for the
+     specification.
+
+'GCRY_MD_CRC32'
+     This is the ISO 3309 and ITU-T V.42 cyclic redundancy check.  It
+     yields an output of 4 bytes.  Note that this is not a hash
+     algorithm in the cryptographic sense.
+
+'GCRY_MD_CRC32_RFC1510'
+     This is the above cyclic redundancy check function, as modified by
+     RFC 1510.  It yields an output of 4 bytes.  Note that this is not a
+     hash algorithm in the cryptographic sense.
+
+'GCRY_MD_CRC24_RFC2440'
+     This is the OpenPGP cyclic redundancy check function.  It yields an
+     output of 3 bytes.  Note that this is not a hash algorithm in the
+     cryptographic sense.
+
+'GCRY_MD_WHIRLPOOL'
+     This is the Whirlpool algorithm which yields a message digest of 64
+     bytes.
+
+'GCRY_MD_GOSTR3411_94'
+     This is the hash algorithm described in GOST R 34.11-94 which
+     yields a message digest of 32 bytes.
+
+'GCRY_MD_STRIBOG256'
+     This is the 256-bit version of hash algorithm described in GOST R
+     34.11-2012 which yields a message digest of 32 bytes.
+
+'GCRY_MD_STRIBOG512'
+     This is the 512-bit version of hash algorithm described in GOST R
+     34.11-2012 which yields a message digest of 64 bytes.
+
+\1f
+File: gcrypt.info,  Node: Working with hash algorithms,  Prev: Available hash algorithms,  Up: Hashing
+
+7.2 Working with hash algorithms
+================================
+
+To use most of these function it is necessary to create a context; this
+is done using:
+
+ -- Function: gcry_error_t gcry_md_open (gcry_md_hd_t *HD, int ALGO,
+          unsigned int FLAGS)
+
+     Create a message digest object for algorithm ALGO.  FLAGS may be
+     given as an bitwise OR of constants described below.  ALGO may be
+     given as '0' if the algorithms to use are later set using
+     'gcry_md_enable'.  HD is guaranteed to either receive a valid
+     handle or NULL.
+
+     For a list of supported algorithms, see *Note Available hash
+     algorithms::.
+
+     The flags allowed for MODE are:
+
+     'GCRY_MD_FLAG_SECURE'
+          Allocate all buffers and the resulting digest in "secure
+          memory".  Use this is the hashed data is highly confidential.
+
+     'GCRY_MD_FLAG_HMAC'
+          Turn the algorithm into a HMAC message authentication
+          algorithm.  This only works if just one algorithm is enabled
+          for the handle and that algorithm is not an extendable-output
+          function.  Note that the function 'gcry_md_setkey' must be
+          used to set the MAC key.  The size of the MAC is equal to the
+          message digest of the underlying hash algorithm.  If you want
+          CBC message authentication codes based on a cipher, see *Note
+          Working with cipher handles::.
+
+     'GCRY_MD_FLAG_BUGEMU1'
+          Versions of Libgcrypt before 1.6.0 had a bug in the Whirlpool
+          code which led to a wrong result for certain input sizes and
+          write patterns.  Using this flag emulates that bug.  This may
+          for example be useful for applications which use Whirlpool as
+          part of their key generation.  It is strongly suggested to use
+          this flag only if really needed and if possible to the data
+          should be re-processed using the regular Whirlpool algorithm.
+
+          Note that this flag works for the entire hash context.  If
+          needed arises it may be used to enable bug emulation for other
+          hash algorithms.  Thus you should not use this flag for a
+          multi-algorithm hash context.
+
+     You may use the function 'gcry_md_is_enabled' to later check
+     whether an algorithm has been enabled.
+
+   If you want to calculate several hash algorithms at the same time,
+you have to use the following function right after the 'gcry_md_open':
+
+ -- Function: gcry_error_t gcry_md_enable (gcry_md_hd_t H, int ALGO)
+
+     Add the message digest algorithm ALGO to the digest object
+     described by handle H.  Duplicated enabling of algorithms is
+     detected and ignored.
+
+   If the flag 'GCRY_MD_FLAG_HMAC' was used, the key for the MAC must be
+set using the function:
+
+ -- Function: gcry_error_t gcry_md_setkey (gcry_md_hd_t H, const void
+          *KEY, size_t KEYLEN)
+
+     For use with the HMAC feature, set the MAC key to the value of KEY
+     of length KEYLEN bytes.  There is no restriction on the length of
+     the key.
+
+   After you are done with the hash calculation, you should release the
+resources by using:
+
+ -- Function: void gcry_md_close (gcry_md_hd_t H)
+
+     Release all resources of hash context H.  H should not be used
+     after a call to this function.  A 'NULL' passed as H is ignored.
+     The function also zeroises all sensitive information associated
+     with this handle.
+
+   Often you have to do several hash operations using the same
+algorithm.  To avoid the overhead of creating and releasing context, a
+reset function is provided:
+
+ -- Function: void gcry_md_reset (gcry_md_hd_t H)
+
+     Reset the current context to its initial state.  This is
+     effectively identical to a close followed by an open and enabling
+     all currently active algorithms.
+
+   Often it is necessary to start hashing some data and then continue to
+hash different data.  To avoid hashing the same data several times
+(which might not even be possible if the data is received from a pipe),
+a snapshot of the current hash context can be taken and turned into a
+new context:
+
+ -- Function: gcry_error_t gcry_md_copy (gcry_md_hd_t *HANDLE_DST,
+          gcry_md_hd_t HANDLE_SRC)
+
+     Create a new digest object as an exact copy of the object described
+     by handle HANDLE_SRC and store it in HANDLE_DST.  The context is
+     not reset and you can continue to hash data using this context and
+     independently using the original context.
+
+   Now that we have prepared everything to calculate hashes, it is time
+to see how it is actually done.  There are two ways for this, one to
+update the hash with a block of memory and one macro to update the hash
+by just one character.  Both methods can be used on the same hash
+context.
+
+ -- Function: void gcry_md_write (gcry_md_hd_t H, const void *BUFFER,
+          size_t LENGTH)
+
+     Pass LENGTH bytes of the data in BUFFER to the digest object with
+     handle H to update the digest values.  This function should be used
+     for large blocks of data.  If this function is used after the
+     context has been finalized, it will keep on pushing the data
+     through the algorithm specific transform function and change the
+     context; however the results are not meaningful and this feature is
+     only available to mitigate timing attacks.
+
+ -- Function: void gcry_md_putc (gcry_md_hd_t H, int C)
+
+     Pass the byte in C to the digest object with handle H to update the
+     digest value.  This is an efficient function, implemented as a
+     macro to buffer the data before an actual update.
+
+   The semantics of the hash functions do not provide for reading out
+intermediate message digests because the calculation must be finalized
+first.  This finalization may for example include the number of bytes
+hashed in the message digest or some padding.
+
+ -- Function: void gcry_md_final (gcry_md_hd_t H)
+
+     Finalize the message digest calculation.  This is not really needed
+     because 'gcry_md_read' and 'gcry_md_extract' do this implicitly.
+     After this has been done no further updates (by means of
+     'gcry_md_write' or 'gcry_md_putc' should be done; However, to
+     mitigate timing attacks it is sometimes useful to keep on updating
+     the context after having stored away the actual digest.  Only the
+     first call to this function has an effect.  It is implemented as a
+     macro.
+
+   The way to read out the calculated message digest is by using the
+function:
+
+ -- Function: unsigned char * gcry_md_read (gcry_md_hd_t H, int ALGO)
+
+     'gcry_md_read' returns the message digest after finalizing the
+     calculation.  This function may be used as often as required but it
+     will always return the same value for one handle.  The returned
+     message digest is allocated within the message context and
+     therefore valid until the handle is released or reset-ed (using
+     'gcry_md_close' or 'gcry_md_reset' or it has been updated as a
+     mitigation measure against timing attacks.  ALGO may be given as 0
+     to return the only enabled message digest or it may specify one of
+     the enabled algorithms.  The function does return 'NULL' if the
+     requested algorithm has not been enabled.
+
+   The way to read output of extendable-output function is by using the
+function:
+
+ -- Function: gpg_err_code_t gcry_md_extract (gcry_md_hd_t H, int ALGO,
+          void *BUFFER, size_t LENGTH)
+
+     'gcry_mac_read' returns output from extendable-output function.
+     This function may be used as often as required to generate more
+     output byte stream from the algorithm.  Function extracts the new
+     output bytes to BUFFER of the length LENGTH.  Buffer will be fully
+     populated with new output.  ALGO may be given as 0 to return the
+     only enabled message digest or it may specify one of the enabled
+     algorithms.  The function does return non-zero value if the
+     requested algorithm has not been enabled.
+
+   Because it is often necessary to get the message digest of blocks of
+memory, two fast convenience function are available for this task:
+
+ -- Function: gpg_err_code_t gcry_md_hash_buffers ( int ALGO,
+          unsigned int FLAGS, void *DIGEST, const gcry_buffer_t *IOV, int IOVCNT
+          )
+
+     'gcry_md_hash_buffers' is a shortcut function to calculate a
+     message digest from several buffers.  This function does not
+     require a context and immediately returns the message digest of the
+     data described by IOV and IOVCNT.  DIGEST must be allocated by the
+     caller, large enough to hold the message digest yielded by the the
+     specified algorithm ALGO.  This required size may be obtained by
+     using the function 'gcry_md_get_algo_dlen'.
+
+     IOV is an array of buffer descriptions with IOVCNT items.  The
+     caller should zero out the structures in this array and for each
+     array item set the fields '.data' to the address of the data to be
+     hashed, '.len' to number of bytes to be hashed.  If .OFF is also
+     set, the data is taken starting at .OFF bytes from the begin of the
+     buffer.  The field '.size' is not used.
+
+     The only supported flag value for FLAGS is GCRY_MD_FLAG_HMAC which
+     turns this function into a HMAC function; the first item in IOV is
+     then used as the key.
+
+     On success the function returns 0 and stores the resulting hash or
+     MAC at DIGEST.
+
+ -- Function: void gcry_md_hash_buffer (int ALGO, void *DIGEST, const
+          void *BUFFER, size_t LENGTH);
+
+     'gcry_md_hash_buffer' is a shortcut function to calculate a message
+     digest of a buffer.  This function does not require a context and
+     immediately returns the message digest of the LENGTH bytes at
+     BUFFER.  DIGEST must be allocated by the caller, large enough to
+     hold the message digest yielded by the the specified algorithm
+     ALGO.  This required size may be obtained by using the function
+     'gcry_md_get_algo_dlen'.
+
+     Note that in contrast to 'gcry_md_hash_buffers' this function will
+     abort the process if an unavailable algorithm is used.
+
+   Hash algorithms are identified by internal algorithm numbers (see
+'gcry_md_open' for a list).  However, in most applications they are used
+by names, so two functions are available to map between string
+representations and hash algorithm identifiers.
+
+ -- Function: const char * gcry_md_algo_name (int ALGO)
+
+     Map the digest algorithm id ALGO to a string representation of the
+     algorithm name.  For unknown algorithms this function returns the
+     string '"?"'.  This function should not be used to test for the
+     availability of an algorithm.
+
+ -- Function: int gcry_md_map_name (const char *NAME)
+
+     Map the algorithm with NAME to a digest algorithm identifier.
+     Returns 0 if the algorithm name is not known.  Names representing
+     ASN.1 object identifiers are recognized if the IETF dotted format
+     is used and the OID is prefixed with either "'oid.'" or "'OID.'".
+     For a list of supported OIDs, see the source code at 'cipher/md.c'.
+     This function should not be used to test for the availability of an
+     algorithm.
+
+ -- Function: gcry_error_t gcry_md_get_asnoid (int ALGO, void *BUFFER,
+          size_t *LENGTH)
+
+     Return an DER encoded ASN.1 OID for the algorithm ALGO in the user
+     allocated BUFFER.  LENGTH must point to variable with the available
+     size of BUFFER and receives after return the actual size of the
+     returned OID. The returned error code may be 'GPG_ERR_TOO_SHORT' if
+     the provided buffer is to short to receive the OID; it is possible
+     to call the function with 'NULL' for BUFFER to have it only return
+     the required size.  The function returns 0 on success.
+
+   To test whether an algorithm is actually available for use, the
+following macro should be used:
+
+ -- Function: gcry_error_t gcry_md_test_algo (int ALGO)
+
+     The macro returns 0 if the algorithm ALGO is available for use.
+
+   If the length of a message digest is not known, it can be retrieved
+using the following function:
+
+ -- Function: unsigned int gcry_md_get_algo_dlen (int ALGO)
+
+     Retrieve the length in bytes of the digest yielded by algorithm
+     ALGO.  This is often used prior to 'gcry_md_read' to allocate
+     sufficient memory for the digest.
+
+   In some situations it might be hard to remember the algorithm used
+for the ongoing hashing.  The following function might be used to get
+that information:
+
+ -- Function: int gcry_md_get_algo (gcry_md_hd_t H)
+
+     Retrieve the algorithm used with the handle H.  Note that this does
+     not work reliable if more than one algorithm is enabled in H.
+
+   The following macro might also be useful:
+
+ -- Function: int gcry_md_is_secure (gcry_md_hd_t H)
+
+     This function returns true when the digest object H is allocated in
+     "secure memory"; i.e.  H was created with the
+     'GCRY_MD_FLAG_SECURE'.
+
+ -- Function: int gcry_md_is_enabled (gcry_md_hd_t H, int ALGO)
+
+     This function returns true when the algorithm ALGO has been enabled
+     for the digest object H.
+
+   Tracking bugs related to hashing is often a cumbersome task which
+requires to add a lot of printf statements into the code.  Libgcrypt
+provides an easy way to avoid this.  The actual data hashed can be
+written to files on request.
+
+ -- Function: void gcry_md_debug (gcry_md_hd_t H, const char *SUFFIX)
+
+     Enable debugging for the digest object with handle H.  This creates
+     files named 'dbgmd-<n>.<string>' while doing the actual hashing.
+     SUFFIX is the string part in the filename.  The number is a counter
+     incremented for each new hashing.  The data in the file is the raw
+     data as passed to 'gcry_md_write' or 'gcry_md_putc'.  If 'NULL' is
+     used for SUFFIX, the debugging is stopped and the file closed.
+     This is only rarely required because 'gcry_md_close' implicitly
+     stops debugging.
+
+\1f
+File: gcrypt.info,  Node: Message Authentication Codes,  Next: Key Derivation,  Prev: Hashing,  Up: Top
+
+8 Message Authentication Codes
+******************************
+
+Libgcrypt provides an easy and consistent to use interface for
+generating Message Authentication Codes (MAC). MAC generation is
+buffered and interface similar to the one used with hash algorithms.
+The programming model follows an open/process/close paradigm and is in
+that similar to other building blocks provided by Libgcrypt.
+
+* Menu:
+
+* Available MAC algorithms::   List of MAC algorithms supported by the library.
+* Working with MAC algorithms::  List of functions related to MAC algorithms.
+
+\1f
+File: gcrypt.info,  Node: Available MAC algorithms,  Next: Working with MAC algorithms,  Up: Message Authentication Codes
+
+8.1 Available MAC algorithms
+============================
+
+'GCRY_MAC_NONE'
+     This is not a real algorithm but used by some functions as an error
+     return value.  This constant is guaranteed to have the value '0'.
+
+'GCRY_MAC_HMAC_SHA256'
+     This is keyed-hash message authentication code (HMAC) message
+     authentication algorithm based on the SHA-256 hash algorithm.
+
+'GCRY_MAC_HMAC_SHA224'
+     This is HMAC message authentication algorithm based on the SHA-224
+     hash algorithm.
+
+'GCRY_MAC_HMAC_SHA512'
+     This is HMAC message authentication algorithm based on the SHA-512
+     hash algorithm.
+
+'GCRY_MAC_HMAC_SHA384'
+     This is HMAC message authentication algorithm based on the SHA-384
+     hash algorithm.
+
+'GCRY_MAC_HMAC_SHA3_256'
+     This is HMAC message authentication algorithm based on the SHA3-384
+     hash algorithm.
+
+'GCRY_MAC_HMAC_SHA3_224'
+     This is HMAC message authentication algorithm based on the SHA3-224
+     hash algorithm.
+
+'GCRY_MAC_HMAC_SHA3_512'
+     This is HMAC message authentication algorithm based on the SHA3-512
+     hash algorithm.
+
+'GCRY_MAC_HMAC_SHA3_384'
+     This is HMAC message authentication algorithm based on the SHA3-384
+     hash algorithm.
+
+'GCRY_MAC_HMAC_SHA1'
+     This is HMAC message authentication algorithm based on the SHA-1
+     hash algorithm.
+
+'GCRY_MAC_HMAC_MD5'
+     This is HMAC message authentication algorithm based on the MD5 hash
+     algorithm.
+
+'GCRY_MAC_HMAC_MD4'
+     This is HMAC message authentication algorithm based on the MD4 hash
+     algorithm.
+
+'GCRY_MAC_HMAC_RMD160'
+     This is HMAC message authentication algorithm based on the
+     RIPE-MD-160 hash algorithm.
+
+'GCRY_MAC_HMAC_WHIRLPOOL'
+     This is HMAC message authentication algorithm based on the
+     WHIRLPOOL hash algorithm.
+
+'GCRY_MAC_HMAC_GOSTR3411_94'
+     This is HMAC message authentication algorithm based on the GOST R
+     34.11-94 hash algorithm.
+
+'GCRY_MAC_HMAC_STRIBOG256'
+     This is HMAC message authentication algorithm based on the 256-bit
+     hash algorithm described in GOST R 34.11-2012.
+
+'GCRY_MAC_HMAC_STRIBOG512'
+     This is HMAC message authentication algorithm based on the 512-bit
+     hash algorithm described in GOST R 34.11-2012.
+
+'GCRY_MAC_CMAC_AES'
+     This is CMAC (Cipher-based MAC) message authentication algorithm
+     based on the AES block cipher algorithm.
+
+'GCRY_MAC_CMAC_3DES'
+     This is CMAC message authentication algorithm based on the
+     three-key EDE Triple-DES block cipher algorithm.
+
+'GCRY_MAC_CMAC_CAMELLIA'
+     This is CMAC message authentication algorithm based on the Camellia
+     block cipher algorithm.
+
+'GCRY_MAC_CMAC_CAST5'
+     This is CMAC message authentication algorithm based on the
+     CAST128-5 block cipher algorithm.
+
+'GCRY_MAC_CMAC_BLOWFISH'
+     This is CMAC message authentication algorithm based on the Blowfish
+     block cipher algorithm.
+
+'GCRY_MAC_CMAC_TWOFISH'
+     This is CMAC message authentication algorithm based on the Twofish
+     block cipher algorithm.
+
+'GCRY_MAC_CMAC_SERPENT'
+     This is CMAC message authentication algorithm based on the Serpent
+     block cipher algorithm.
+
+'GCRY_MAC_CMAC_SEED'
+     This is CMAC message authentication algorithm based on the SEED
+     block cipher algorithm.
+
+'GCRY_MAC_CMAC_RFC2268'
+     This is CMAC message authentication algorithm based on the Ron's
+     Cipher 2 block cipher algorithm.
+
+'GCRY_MAC_CMAC_IDEA'
+     This is CMAC message authentication algorithm based on the IDEA
+     block cipher algorithm.
+
+'GCRY_MAC_CMAC_GOST28147'
+     This is CMAC message authentication algorithm based on the GOST
+     28147-89 block cipher algorithm.
+
+'GCRY_MAC_GMAC_AES'
+     This is GMAC (GCM mode based MAC) message authentication algorithm
+     based on the AES block cipher algorithm.
+
+'GCRY_MAC_GMAC_CAMELLIA'
+     This is GMAC message authentication algorithm based on the Camellia
+     block cipher algorithm.
+
+'GCRY_MAC_GMAC_TWOFISH'
+     This is GMAC message authentication algorithm based on the Twofish
+     block cipher algorithm.
+
+'GCRY_MAC_GMAC_SERPENT'
+     This is GMAC message authentication algorithm based on the Serpent
+     block cipher algorithm.
+
+'GCRY_MAC_GMAC_SEED'
+     This is GMAC message authentication algorithm based on the SEED
+     block cipher algorithm.
+
+'GCRY_MAC_POLY1305'
+     This is plain Poly1305 message authentication algorithm, used with
+     one-time key.
+
+'GCRY_MAC_POLY1305_AES'
+     This is Poly1305-AES message authentication algorithm, used with
+     key and one-time nonce.
+
+'GCRY_MAC_POLY1305_CAMELLIA'
+     This is Poly1305-Camellia message authentication algorithm, used
+     with key and one-time nonce.
+
+'GCRY_MAC_POLY1305_TWOFISH'
+     This is Poly1305-Twofish message authentication algorithm, used
+     with key and one-time nonce.
+
+'GCRY_MAC_POLY1305_SERPENT'
+     This is Poly1305-Serpent message authentication algorithm, used
+     with key and one-time nonce.
+
+'GCRY_MAC_POLY1305_SEED'
+     This is Poly1305-SEED message authentication algorithm, used with
+     key and one-time nonce.
+
+\1f
+File: gcrypt.info,  Node: Working with MAC algorithms,  Prev: Available MAC algorithms,  Up: Message Authentication Codes
+
+8.2 Working with MAC algorithms
+===============================
+
+To use most of these function it is necessary to create a context; this
+is done using:
+
+ -- Function: gcry_error_t gcry_mac_open (gcry_mac_hd_t *HD, int ALGO,
+          unsigned int FLAGS, gcry_ctx_t CTX)
+
+     Create a MAC object for algorithm ALGO.  FLAGS may be given as an
+     bitwise OR of constants described below.  HD is guaranteed to
+     either receive a valid handle or NULL. CTX is context object to
+     associate MAC object with.  CTX maybe set to NULL.
+
+     For a list of supported algorithms, see *Note Available MAC
+     algorithms::.
+
+     The flags allowed for MODE are:
+
+     'GCRY_MAC_FLAG_SECURE'
+          Allocate all buffers and the resulting MAC in "secure memory".
+          Use this if the MAC data is highly confidential.
+
+   In order to use a handle for performing MAC algorithm operations, a
+'key' has to be set first:
+
+ -- Function: gcry_error_t gcry_mac_setkey (gcry_mac_hd_t H, const void
+          *KEY, size_t KEYLEN)
+
+     Set the MAC key to the value of KEY of length KEYLEN bytes.  With
+     HMAC algorithms, there is no restriction on the length of the key.
+     With CMAC algorithms, the length of the key is restricted to those
+     supported by the underlying block cipher.
+
+   GMAC algorithms and Poly1305-with-cipher algorithms need
+initialization vector to be set, which can be performed with function:
+
+ -- Function: gcry_error_t gcry_mac_setiv (gcry_mac_hd_t H, const void
+          *IV, size_t IVLEN)
+
+     Set the IV to the value of IV of length IVLEN bytes.
+
+   After you are done with the MAC calculation, you should release the
+resources by using:
+
+ -- Function: void gcry_mac_close (gcry_mac_hd_t H)
+
+     Release all resources of MAC context H.  H should not be used after
+     a call to this function.  A 'NULL' passed as H is ignored.  The
+     function also clears all sensitive information associated with this
+     handle.
+
+   Often you have to do several MAC operations using the same algorithm.
+To avoid the overhead of creating and releasing context, a reset
+function is provided:
+
+ -- Function: gcry_error_t gcry_mac_reset (gcry_mac_hd_t H)
+
+     Reset the current context to its initial state.  This is
+     effectively identical to a close followed by an open and setting
+     same key.
+
+     Note that gcry_mac_reset is implemented as a macro.
+
+   Now that we have prepared everything to calculate MAC, it is time to
+see how it is actually done.
+
+ -- Function: gcry_error_t gcry_mac_write (gcry_mac_hd_t H, const void
+          *BUFFER, size_t LENGTH)
+
+     Pass LENGTH bytes of the data in BUFFER to the MAC object with
+     handle H to update the MAC values.  If this function is used after
+     the context has been finalized, it will keep on pushing the data
+     through the algorithm specific transform function and thereby
+     change the context; however the results are not meaningful and this
+     feature is only available to mitigate timing attacks.
+
+   The way to read out the calculated MAC is by using the function:
+
+ -- Function: gcry_error_t gcry_mac_read (gcry_mac_hd_t H, void *BUFFER,
+          size_t *LENGTH)
+
+     'gcry_mac_read' returns the MAC after finalizing the calculation.
+     Function copies the resulting MAC value to BUFFER of the length
+     LENGTH.  If LENGTH is larger than length of resulting MAC value,
+     then length of MAC is returned through LENGTH.
+
+   To compare existing MAC value with recalculated MAC, one is to use
+the function:
+
+ -- Function: gcry_error_t gcry_mac_verify (gcry_mac_hd_t H, void
+          *BUFFER, size_t LENGTH)
+
+     'gcry_mac_verify' finalizes MAC calculation and compares result
+     with LENGTH bytes of data in BUFFER.  Error code 'GPG_ERR_CHECKSUM'
+     is returned if the MAC value in the buffer BUFFER does not match
+     the MAC calculated in object H.
+
+   In some situations it might be hard to remember the algorithm used
+for the MAC calculation.  The following function might be used to get
+that information:
+
+ -- Function: int gcry_mac_get_algo (gcry_mac_hd_t H)
+
+     Retrieve the algorithm used with the handle H.
+
+   MAC algorithms are identified by internal algorithm numbers (see
+'gcry_mac_open' for a list).  However, in most applications they are
+used by names, so two functions are available to map between string
+representations and MAC algorithm identifiers.
+
+ -- Function: const char * gcry_mac_algo_name (int ALGO)
+
+     Map the MAC algorithm id ALGO to a string representation of the
+     algorithm name.  For unknown algorithms this function returns the
+     string '"?"'.  This function should not be used to test for the
+     availability of an algorithm.
+
+ -- Function: int gcry_mac_map_name (const char *NAME)
+
+     Map the algorithm with NAME to a MAC algorithm identifier.  Returns
+     0 if the algorithm name is not known.  This function should not be
+     used to test for the availability of an algorithm.
+
+   To test whether an algorithm is actually available for use, the
+following macro should be used:
+
+ -- Function: gcry_error_t gcry_mac_test_algo (int ALGO)
+
+     The macro returns 0 if the MAC algorithm ALGO is available for use.
+
+   If the length of a message digest is not known, it can be retrieved
+using the following function:
+
+ -- Function: unsigned int gcry_mac_get_algo_maclen (int ALGO)
+
+     Retrieve the length in bytes of the MAC yielded by algorithm ALGO.
+     This is often used prior to 'gcry_mac_read' to allocate sufficient
+     memory for the MAC value.  On error '0' is returned.
+
+ -- Function: unsigned int gcry_mac_get_algo_keylen (ALGO)
+
+     This function returns length of the key for MAC algorithm ALGO.  If
+     the algorithm supports multiple key lengths, the default supported
+     key length is returned.  On error '0' is returned.  The key length
+     is returned as number of octets.
+
+\1f
+File: gcrypt.info,  Node: Key Derivation,  Next: Random Numbers,  Prev: Message Authentication Codes,  Up: Top
+
+9 Key Derivation
+****************
+
+Libgcypt provides a general purpose function to derive keys from
+strings.
+
+ -- Function: gpg_error_t gcry_kdf_derive ( const void *PASSPHRASE,
+          size_t PASSPHRASELEN, int ALGO, int SUBALGO, const void *SALT,
+          size_t SALTLEN, unsigned long ITERATIONS, size_t KEYSIZE, void *KEYBUFFER
+          )
+
+     Derive a key from a passphrase.  KEYSIZE gives the requested size
+     of the keys in octets.  KEYBUFFER is a caller provided buffer
+     filled on success with the derived key.  The input passphrase is
+     taken from PASSPHRASE which is an arbitrary memory buffer of
+     PASSPHRASELEN octets.  ALGO specifies the KDF algorithm to use; see
+     below.  SUBALGO specifies an algorithm used internally by the KDF
+     algorithms; this is usually a hash algorithm but certain KDF
+     algorithms may use it differently.  SALT is a salt of length
+     SALTLEN octets, as needed by most KDF algorithms.  ITERATIONS is a
+     positive integer parameter to most KDFs.
+
+     On success 0 is returned; on failure an error code.
+
+     Currently supported KDFs (parameter ALGO):
+
+     'GCRY_KDF_SIMPLE_S2K'
+          The OpenPGP simple S2K algorithm (cf.  RFC4880).  Its use is
+          strongly deprecated.  SALT and ITERATIONS are not needed and
+          may be passed as 'NULL'/'0'.
+
+     'GCRY_KDF_SALTED_S2K'
+          The OpenPGP salted S2K algorithm (cf.  RFC4880).  Usually not
+          used.  ITERATIONS is not needed and may be passed as '0'.
+          SALTLEN must be given as 8.
+
+     'GCRY_KDF_ITERSALTED_S2K'
+          The OpenPGP iterated+salted S2K algorithm (cf.  RFC4880).
+          This is the default for most OpenPGP applications.  SALTLEN
+          must be given as 8.  Note that OpenPGP defines a special
+          encoding of the ITERATIONS; however this function takes the
+          plain decoded iteration count.
+
+     'GCRY_KDF_PBKDF2'
+          The PKCS#5 Passphrase Based Key Derivation Function number 2.
+
+     'GCRY_KDF_SCRYPT'
+          The SCRYPT Key Derivation Function.  The subalgorithm is used
+          to specify the CPU/memory cost parameter N, and the number of
+          iterations is used for the parallelization parameter p.  The
+          block size is fixed at 8 in the current implementation.
+
+\1f
+File: gcrypt.info,  Node: Random Numbers,  Next: S-expressions,  Prev: Key Derivation,  Up: Top
+
+10 Random Numbers
+*****************
+
+* Menu:
+
+* Quality of random numbers::   Libgcrypt uses different quality levels.
+* Retrieving random numbers::   How to retrieve random numbers.
+
+\1f
+File: gcrypt.info,  Node: Quality of random numbers,  Next: Retrieving random numbers,  Up: Random Numbers
+
+10.1 Quality of random numbers
+==============================
+
+Libgcypt offers random numbers of different quality levels:
+
+ -- Data type: gcry_random_level_t
+     The constants for the random quality levels are of this enum type.
+
+'GCRY_WEAK_RANDOM'
+     For all functions, except for 'gcry_mpi_randomize', this level maps
+     to GCRY_STRONG_RANDOM. If you do not want this, consider using
+     'gcry_create_nonce'.
+'GCRY_STRONG_RANDOM'
+     Use this level for session keys and similar purposes.
+'GCRY_VERY_STRONG_RANDOM'
+     Use this level for long term key material.
+
+\1f
+File: gcrypt.info,  Node: Retrieving random numbers,  Prev: Quality of random numbers,  Up: Random Numbers
+
+10.2 Retrieving random numbers
+==============================
+
+ -- Function: void gcry_randomize (unsigned char *BUFFER, size_t LENGTH,
+          enum gcry_random_level LEVEL)
+
+     Fill BUFFER with LENGTH random bytes using a random quality as
+     defined by LEVEL.
+
+ -- Function: void * gcry_random_bytes (size_t NBYTES, enum
+          gcry_random_level LEVEL)
+
+     Convenience function to allocate a memory block consisting of
+     NBYTES fresh random bytes using a random quality as defined by
+     LEVEL.
+
+ -- Function: void * gcry_random_bytes_secure (size_t NBYTES, enum
+          gcry_random_level LEVEL)
+
+     Convenience function to allocate a memory block consisting of
+     NBYTES fresh random bytes using a random quality as defined by
+     LEVEL.  This function differs from 'gcry_random_bytes' in that the
+     returned buffer is allocated in a "secure" area of the memory.
+
+ -- Function: void gcry_create_nonce (unsigned char *BUFFER, size_t
+          LENGTH)
+
+     Fill BUFFER with LENGTH unpredictable bytes.  This is commonly
+     called a nonce and may also be used for initialization vectors and
+     padding.  This is an extra function nearly independent of the other
+     random function for 3 reasons: It better protects the regular
+     random generator's internal state, provides better performance and
+     does not drain the precious entropy pool.
+
+\1f
+File: gcrypt.info,  Node: S-expressions,  Next: MPI library,  Prev: Random Numbers,  Up: Top
+
+11 S-expressions
+****************
+
+S-expressions are used by the public key functions to pass complex data
+structures around.  These LISP like objects are used by some
+cryptographic protocols (cf.  RFC-2692) and Libgcrypt provides functions
+to parse and construct them.  For detailed information, see 'Ron Rivest,
+code and description of S-expressions,
+<http://theory.lcs.mit.edu/~rivest/sexp.html>'.
+
+* Menu:
+
+* Data types for S-expressions::  Data types related with S-expressions.
+* Working with S-expressions::  How to work with S-expressions.
+
+\1f
+File: gcrypt.info,  Node: Data types for S-expressions,  Next: Working with S-expressions,  Up: S-expressions
+
+11.1 Data types for S-expressions
+=================================
+
+ -- Data type: gcry_sexp_t
+     The 'gcry_sexp_t' type describes an object with the Libgcrypt
+     internal representation of an S-expression.
+
+\1f
+File: gcrypt.info,  Node: Working with S-expressions,  Prev: Data types for S-expressions,  Up: S-expressions
+
+11.2 Working with S-expressions
+===============================
+
+There are several functions to create an Libgcrypt S-expression object
+from its external representation or from a string template.  There is
+also a function to convert the internal representation back into one of
+the external formats:
+
+ -- Function: gcry_error_t gcry_sexp_new (gcry_sexp_t *R_SEXP,
+          const void *BUFFER, size_t LENGTH, int AUTODETECT)
+
+     This is the generic function to create an new S-expression object
+     from its external representation in BUFFER of LENGTH bytes.  On
+     success the result is stored at the address given by R_SEXP.  With
+     AUTODETECT set to 0, the data in BUFFER is expected to be in
+     canonized format, with AUTODETECT set to 1 the parses any of the
+     defined external formats.  If BUFFER does not hold a valid
+     S-expression an error code is returned and R_SEXP set to 'NULL'.
+     Note that the caller is responsible for releasing the newly
+     allocated S-expression using 'gcry_sexp_release'.
+
+ -- Function: gcry_error_t gcry_sexp_create (gcry_sexp_t *R_SEXP,
+          void *BUFFER, size_t LENGTH, int AUTODETECT,
+          void (*FREEFNC)(void*))
+
+     This function is identical to 'gcry_sexp_new' but has an extra
+     argument FREEFNC, which, when not set to 'NULL', is expected to be
+     a function to release the BUFFER; most likely the standard 'free'
+     function is used for this argument.  This has the effect of
+     transferring the ownership of BUFFER to the created object in
+     R_SEXP.  The advantage of using this function is that Libgcrypt
+     might decide to directly use the provided buffer and thus avoid
+     extra copying.
+
+ -- Function: gcry_error_t gcry_sexp_sscan (gcry_sexp_t *R_SEXP,
+          size_t *ERROFF, const char *BUFFER, size_t LENGTH)
+
+     This is another variant of the above functions.  It behaves nearly
+     identical but provides an ERROFF argument which will receive the
+     offset into the buffer where the parsing stopped on error.
+
+ -- Function: gcry_error_t gcry_sexp_build (gcry_sexp_t *R_SEXP,
+          size_t *ERROFF, const char *FORMAT, ...)
+
+     This function creates an internal S-expression from the string
+     template FORMAT and stores it at the address of R_SEXP.  If there
+     is a parsing error, the function returns an appropriate error code
+     and stores the offset into FORMAT where the parsing stopped in
+     ERROFF.  The function supports a couple of printf-like formatting
+     characters and expects arguments for some of these escape sequences
+     right after FORMAT.  The following format characters are defined:
+
+     '%m'
+          The next argument is expected to be of type 'gcry_mpi_t' and a
+          copy of its value is inserted into the resulting S-expression.
+          The MPI is stored as a signed integer.
+     '%M'
+          The next argument is expected to be of type 'gcry_mpi_t' and a
+          copy of its value is inserted into the resulting S-expression.
+          The MPI is stored as an unsigned integer.
+     '%s'
+          The next argument is expected to be of type 'char *' and that
+          string is inserted into the resulting S-expression.
+     '%d'
+          The next argument is expected to be of type 'int' and its
+          value is inserted into the resulting S-expression.
+     '%u'
+          The next argument is expected to be of type 'unsigned int' and
+          its value is inserted into the resulting S-expression.
+     '%b'
+          The next argument is expected to be of type 'int' directly
+          followed by an argument of type 'char *'.  This represents a
+          buffer of given length to be inserted into the resulting
+          S-expression.
+     '%S'
+          The next argument is expected to be of type 'gcry_sexp_t' and
+          a copy of that S-expression is embedded in the resulting
+          S-expression.  The argument needs to be a regular
+          S-expression, starting with a parenthesis.
+
+     No other format characters are defined and would return an error.
+     Note that the format character '%%' does not exists, because a
+     percent sign is not a valid character in an S-expression.
+
+ -- Function: void gcry_sexp_release (gcry_sexp_t SEXP)
+
+     Release the S-expression object SEXP.  If the S-expression is
+     stored in secure memory it explicitly zeroises that memory; note
+     that this is done in addition to the zeroisation always done when
+     freeing secure memory.
+
+The next 2 functions are used to convert the internal representation
+back into a regular external S-expression format and to show the
+structure for debugging.
+
+ -- Function: size_t gcry_sexp_sprint (gcry_sexp_t SEXP, int MODE,
+          char *BUFFER, size_t MAXLENGTH)
+
+     Copies the S-expression object SEXP into BUFFER using the format
+     specified in MODE.  MAXLENGTH must be set to the allocated length
+     of BUFFER.  The function returns the actual length of valid bytes
+     put into BUFFER or 0 if the provided buffer is too short.  Passing
+     'NULL' for BUFFER returns the required length for BUFFER.  For
+     convenience reasons an extra byte with value 0 is appended to the
+     buffer.
+
+     The following formats are supported:
+
+     'GCRYSEXP_FMT_DEFAULT'
+          Returns a convenient external S-expression representation.
+
+     'GCRYSEXP_FMT_CANON'
+          Return the S-expression in canonical format.
+
+     'GCRYSEXP_FMT_BASE64'
+          Not currently supported.
+
+     'GCRYSEXP_FMT_ADVANCED'
+          Returns the S-expression in advanced format.
+
+ -- Function: void gcry_sexp_dump (gcry_sexp_t SEXP)
+
+     Dumps SEXP in a format suitable for debugging to Libgcrypt's
+     logging stream.
+
+Often canonical encoding is used in the external representation.  The
+following function can be used to check for valid encoding and to learn
+the length of the S-expression.
+
+ -- Function: size_t gcry_sexp_canon_len (const unsigned char *BUFFER,
+          size_t LENGTH, size_t *ERROFF, int *ERRCODE)
+
+     Scan the canonical encoded BUFFER with implicit length values and
+     return the actual length this S-expression uses.  For a valid
+     S-expression it should never return 0.  If LENGTH is not 0, the
+     maximum length to scan is given; this can be used for syntax checks
+     of data passed from outside.  ERRCODE and ERROFF may both be passed
+     as 'NULL'.
+
+There are functions to parse S-expressions and retrieve elements:
+
+ -- Function: gcry_sexp_t gcry_sexp_find_token (const gcry_sexp_t LIST,
+          const char *TOKEN, size_t TOKLEN)
+
+     Scan the S-expression for a sublist with a type (the car of the
+     list) matching the string TOKEN.  If TOKLEN is not 0, the token is
+     assumed to be raw memory of this length.  The function returns a
+     newly allocated S-expression consisting of the found sublist or
+     'NULL' when not found.
+
+ -- Function: int gcry_sexp_length (const gcry_sexp_t LIST)
+
+     Return the length of the LIST.  For a valid S-expression this
+     should be at least 1.
+
+ -- Function: gcry_sexp_t gcry_sexp_nth (const gcry_sexp_t LIST,
+          int NUMBER)
+
+     Create and return a new S-expression from the element with index
+     NUMBER in LIST.  Note that the first element has the index 0.  If
+     there is no such element, 'NULL' is returned.
+
+ -- Function: gcry_sexp_t gcry_sexp_car (const gcry_sexp_t LIST)
+
+     Create and return a new S-expression from the first element in
+     LIST; this is called the "type" and should always exist per
+     S-expression specification and in general be a string.  'NULL' is
+     returned in case of a problem.
+
+ -- Function: gcry_sexp_t gcry_sexp_cdr (const gcry_sexp_t LIST)
+
+     Create and return a new list form all elements except for the first
+     one.  Note that this function may return an invalid S-expression
+     because it is not guaranteed, that the type exists and is a string.
+     However, for parsing a complex S-expression it might be useful for
+     intermediate lists.  Returns 'NULL' on error.
+
+ -- Function: const char * gcry_sexp_nth_data (const gcry_sexp_t LIST,
+          int NUMBER, size_t *DATALEN)
+
+     This function is used to get data from a LIST.  A pointer to the
+     actual data with index NUMBER is returned and the length of this
+     data will be stored to DATALEN.  If there is no data at the given
+     index or the index represents another list, 'NULL' is returned.
+     *Caution:* The returned pointer is valid as long as LIST is not
+     modified or released.
+
+     Here is an example on how to extract and print the surname (Meier)
+     from the S-expression '(Name Otto Meier (address Burgplatz 3))':
+
+          size_t len;
+          const char *name;
+
+          name = gcry_sexp_nth_data (list, 2, &len);
+          printf ("my name is %.*s\n", (int)len, name);
+
+ -- Function: void * gcry_sexp_nth_buffer (const gcry_sexp_t LIST,
+          int NUMBER, size_t *RLENGTH)
+
+     This function is used to get data from a LIST.  A malloced buffer
+     with the actual data at list index NUMBER is returned and the
+     length of this buffer will be stored to RLENGTH.  If there is no
+     data at the given index or the index represents another list,
+     'NULL' is returned.  The caller must release the result using
+     'gcry_free'.
+
+     Here is an example on how to extract and print the CRC value from
+     the S-expression '(hash crc32 #23ed00d7)':
+
+          size_t len;
+          char *value;
+
+          value = gcry_sexp_nth_buffer (list, 2, &len);
+          if (value)
+            fwrite (value, len, 1, stdout);
+          gcry_free (value);
+
+ -- Function: char * gcry_sexp_nth_string (gcry_sexp_t LIST, int NUMBER)
+
+     This function is used to get and convert data from a LIST.  The
+     data is assumed to be a Nul terminated string.  The caller must
+     release this returned value using 'gcry_free'.  If there is no data
+     at the given index, the index represents a list or the value can't
+     be converted to a string, 'NULL' is returned.
+
+ -- Function: gcry_mpi_t gcry_sexp_nth_mpi (gcry_sexp_t LIST,
+          int NUMBER, int MPIFMT)
+
+     This function is used to get and convert data from a LIST.  This
+     data is assumed to be an MPI stored in the format described by
+     MPIFMT and returned as a standard Libgcrypt MPI. The caller must
+     release this returned value using 'gcry_mpi_release'.  If there is
+     no data at the given index, the index represents a list or the
+     value can't be converted to an MPI, 'NULL' is returned.  If you use
+     this function to parse results of a public key function, you most
+     likely want to use 'GCRYMPI_FMT_USG'.
+
+ -- Function: gpg_error_t gcry_sexp_extract_param ( gcry_sexp_t SEXP,
+          const char *PATH, const char *LIST, ...)
+
+     Extract parameters from an S-expression using a list of parameter
+     names.  The names of these parameters are specified in LIST. White
+     space between the parameter names are ignored.  Some special
+     characters may be given to control the conversion:
+
+     '+'
+          Switch to unsigned integer format (GCRYMPI_FMT_USG). This is
+          the default mode.
+     '-'
+          Switch to standard signed format (GCRYMPI_FMT_STD).
+     '/'
+          Switch to opaque MPI format.  The resulting MPIs may not be
+          used for computations; see 'gcry_mpi_get_opaque' for details.
+     '&'
+          Switch to buffer descriptor mode.  See below for details.
+     '?'
+          If immediately following a parameter letter (no white space
+          allowed), that parameter is considered optional.
+
+     In general parameter names are single letters.  To use a string for
+     a parameter name, enclose the name in single quotes.
+
+     Unless in buffer descriptor mode for each parameter name a pointer
+     to an 'gcry_mpi_t' variable is expected that must be set to 'NULL'
+     prior to invoking this function, and finally a 'NULL' is expected.
+     For example
+
+            _gcry_sexp_extract_param (key, NULL, "n/x+e d-'foo'",
+                                      &mpi_n, &mpi_x, &mpi_e, &mpi_foo, NULL)
+
+     stores the parameter 'n' from KEY as an unsigned MPI into MPI_N,
+     the parameter 'x' as an opaque MPI into MPI_X, the parameter 'e'
+     again as an unsigned MPI into MPI_E, and the parameter 'foo' as a
+     signed MPI.
+
+     PATH is an optional string used to locate a token.  The exclamation
+     mark separated tokens are used via 'gcry_sexp_find_token' to find a
+     start point inside the S-expression.
+
+     In buffer descriptor mode a pointer to a 'gcry_buffer_t' descriptor
+     is expected instead of a pointer to an MPI. The caller may use two
+     different operation modes here: If the DATA field of the provided
+     descriptor is 'NULL', the function allocates a new buffer and
+     stores it at DATA; the other fields are set accordingly with OFF
+     set to 0.  If DATA is not 'NULL', the function assumes that the
+     DATA, SIZE, and OFF fields specify a buffer where to but the value
+     of the respective parameter; on return the LEN field receives the
+     number of bytes copied to that buffer; in case the buffer is too
+     small, the function immediately returns with an error code (and LEN
+     is set to 0).
+
+     The function returns 0 on success.  On error an error code is
+     returned, all passed MPIs that might have been allocated up to this
+     point are deallocated and set to 'NULL', and all passed buffers are
+     either truncated if the caller supplied the buffer, or deallocated
+     if the function allocated the buffer.
+
+\1f
+File: gcrypt.info,  Node: MPI library,  Next: Prime numbers,  Prev: S-expressions,  Up: Top
+
+12 MPI library
+**************
+
+* Menu:
+
+* Data types::                  MPI related data types.
+* Basic functions::             First steps with MPI numbers.
+* MPI formats::                 External representation of MPIs.
+* Calculations::                Performing MPI calculations.
+* Comparisons::                 How to compare MPI values.
+* Bit manipulations::           How to access single bits of MPI values.
+* EC functions::                Elliptic curve related functions.
+* Miscellaneous::               Miscellaneous MPI functions.
+
+Public key cryptography is based on mathematics with large numbers.  To
+implement the public key functions, a library for handling these large
+numbers is required.  Because of the general usefulness of such a
+library, its interface is exposed by Libgcrypt.  In the context of
+Libgcrypt and in most other applications, these large numbers are called
+MPIs (multi-precision-integers).
+
+\1f
+File: gcrypt.info,  Node: Data types,  Next: Basic functions,  Up: MPI library
+
+12.1 Data types
+===============
+
+ -- Data type: gcry_mpi_t
+     This type represents an object to hold an MPI.
+
+ -- Data type: gcry_mpi_point_t
+     This type represents an object to hold a point for elliptic curve
+     math.
+
+\1f
+File: gcrypt.info,  Node: Basic functions,  Next: MPI formats,  Prev: Data types,  Up: MPI library
+
+12.2 Basic functions
+====================
+
+To work with MPIs, storage must be allocated and released for the
+numbers.  This can be done with one of these functions:
+
+ -- Function: gcry_mpi_t gcry_mpi_new (unsigned int NBITS)
+
+     Allocate a new MPI object, initialize it to 0 and initially
+     allocate enough memory for a number of at least NBITS.  This
+     pre-allocation is only a small performance issue and not actually
+     necessary because Libgcrypt automatically re-allocates the required
+     memory.
+
+ -- Function: gcry_mpi_t gcry_mpi_snew (unsigned int NBITS)
+
+     This is identical to 'gcry_mpi_new' but allocates the MPI in the so
+     called "secure memory" which in turn will take care that all
+     derived values will also be stored in this "secure memory".  Use
+     this for highly confidential data like private key parameters.
+
+ -- Function: gcry_mpi_t gcry_mpi_copy (const gcry_mpi_t A)
+
+     Create a new MPI as the exact copy of A but with the constant and
+     immutable flags cleared.
+
+ -- Function: void gcry_mpi_release (gcry_mpi_t A)
+
+     Release the MPI A and free all associated resources.  Passing
+     'NULL' is allowed and ignored.  When a MPI stored in the "secure
+     memory" is released, that memory gets wiped out immediately.
+
+The simplest operations are used to assign a new value to an MPI:
+
+ -- Function: gcry_mpi_t gcry_mpi_set (gcry_mpi_t W, const gcry_mpi_t U)
+
+     Assign the value of U to W and return W.  If 'NULL' is passed for
+     W, a new MPI is allocated, set to the value of U and returned.
+
+ -- Function: gcry_mpi_t gcry_mpi_set_ui (gcry_mpi_t W, unsigned long U)
+
+     Assign the value of U to W and return W.  If 'NULL' is passed for
+     W, a new MPI is allocated, set to the value of U and returned.
+     This function takes an 'unsigned int' as type for U and thus it is
+     only possible to set W to small values (usually up to the word size
+     of the CPU).
+
+ -- Function: void gcry_mpi_swap (gcry_mpi_t A, gcry_mpi_t B)
+
+     Swap the values of A and B.
+
+ -- Function: void gcry_mpi_snatch (gcry_mpi_t W, const gcry_mpi_t U)
+
+     Set U into W and release U.  If W is 'NULL' only U will be
+     released.
+
+ -- Function: void gcry_mpi_neg (gcry_mpi_t W, gcry_mpi_t U)
+
+     Set the sign of W to the negative of U.
+
+ -- Function: void gcry_mpi_abs (gcry_mpi_t W)
+
+     Clear the sign of W.
+
+\1f
+File: gcrypt.info,  Node: MPI formats,  Next: Calculations,  Prev: Basic functions,  Up: MPI library
+
+12.3 MPI formats
+================
+
+The following functions are used to convert between an external
+representation of an MPI and the internal one of Libgcrypt.
+
+ -- Function: gcry_error_t gcry_mpi_scan (gcry_mpi_t *R_MPI,
+          enum gcry_mpi_format FORMAT, const unsigned char *BUFFER,
+          size_t BUFLEN, size_t *NSCANNED)
+
+     Convert the external representation of an integer stored in BUFFER
+     with a length of BUFLEN into a newly created MPI returned which
+     will be stored at the address of R_MPI.  For certain formats the
+     length argument is not required and should be passed as '0'.  A
+     BUFLEN larger than 16 MiByte will be rejected.  After a successful
+     operation the variable NSCANNED receives the number of bytes
+     actually scanned unless NSCANNED was given as 'NULL'.  FORMAT
+     describes the format of the MPI as stored in BUFFER:
+
+     'GCRYMPI_FMT_STD'
+          2-complement stored without a length header.  Note that
+          'gcry_mpi_print' stores a '0' as a string of zero length.
+
+     'GCRYMPI_FMT_PGP'
+          As used by OpenPGP (only defined as unsigned).  This is
+          basically 'GCRYMPI_FMT_STD' with a 2 byte big endian length
+          header.  A length header indicating a length of more than
+          16384 is not allowed.
+
+     'GCRYMPI_FMT_SSH'
+          As used in the Secure Shell protocol.  This is
+          'GCRYMPI_FMT_STD' with a 4 byte big endian header.
+
+     'GCRYMPI_FMT_HEX'
+          Stored as a string with each byte of the MPI encoded as 2 hex
+          digits.  Negative numbers are prefix with a minus sign and in
+          addition the high bit is always zero to make clear that an
+          explicit sign ist used.  When using this format, BUFLEN must
+          be zero.
+
+     'GCRYMPI_FMT_USG'
+          Simple unsigned integer.
+
+     Note that all of the above formats store the integer in big-endian
+     format (MSB first).
+
+ -- Function: gcry_error_t gcry_mpi_print (enum gcry_mpi_format FORMAT,
+          unsigned char *BUFFER, size_t BUFLEN, size_t *NWRITTEN,
+          const gcry_mpi_t A)
+
+     Convert the MPI A into an external representation described by
+     FORMAT (see above) and store it in the provided BUFFER which has a
+     usable length of at least the BUFLEN bytes.  If NWRITTEN is not
+     NULL, it will receive the number of bytes actually stored in BUFFER
+     after a successful operation.
+
+ -- Function: gcry_error_t gcry_mpi_aprint (enum gcry_mpi_format FORMAT,
+          unsigned char **BUFFER, size_t *NBYTES, const gcry_mpi_t A)
+
+     Convert the MPI A into an external representation described by
+     FORMAT (see above) and store it in a newly allocated buffer which
+     address will be stored in the variable BUFFER points to.  The
+     number of bytes stored in this buffer will be stored in the
+     variable NBYTES points to, unless NBYTES is 'NULL'.
+
+     Even if NBYTES is zero, the function allocates at least one byte
+     and store a zero there.  Thus with formats 'GCRYMPI_FMT_STD' and
+     'GCRYMPI_FMT_USG' the caller may safely set a returned length of 0
+     to 1 to represent a zero as a 1 byte string.
+
+ -- Function: void gcry_mpi_dump (const gcry_mpi_t A)
+
+     Dump the value of A in a format suitable for debugging to
+     Libgcrypt's logging stream.  Note that one leading space but no
+     trailing space or linefeed will be printed.  It is okay to pass
+     'NULL' for A.
+
+\1f
+File: gcrypt.info,  Node: Calculations,  Next: Comparisons,  Prev: MPI formats,  Up: MPI library
+
+12.4 Calculations
+=================
+
+Basic arithmetic operations:
+
+ -- Function: void gcry_mpi_add (gcry_mpi_t W, gcry_mpi_t U,
+          gcry_mpi_t V)
+
+     W = U + V.
+
+ -- Function: void gcry_mpi_add_ui (gcry_mpi_t W, gcry_mpi_t U,
+          unsigned long V)
+
+     W = U + V.  Note that V is an unsigned integer.
+
+ -- Function: void gcry_mpi_addm (gcry_mpi_t W, gcry_mpi_t U,
+          gcry_mpi_t V, gcry_mpi_t M)
+
+     W = U + V \bmod M.
+
+ -- Function: void gcry_mpi_sub (gcry_mpi_t W, gcry_mpi_t U,
+          gcry_mpi_t V)
+
+     W = U - V.
+
+ -- Function: void gcry_mpi_sub_ui (gcry_mpi_t W, gcry_mpi_t U,
+          unsigned long V)
+
+     W = U - V.  V is an unsigned integer.
+
+ -- Function: void gcry_mpi_subm (gcry_mpi_t W, gcry_mpi_t U,
+          gcry_mpi_t V, gcry_mpi_t M)
+
+     W = U - V \bmod M.
+
+ -- Function: void gcry_mpi_mul (gcry_mpi_t W, gcry_mpi_t U,
+          gcry_mpi_t V)
+
+     W = U * V.
+
+ -- Function: void gcry_mpi_mul_ui (gcry_mpi_t W, gcry_mpi_t U,
+          unsigned long V)
+
+     W = U * V.  V is an unsigned integer.
+
+ -- Function: void gcry_mpi_mulm (gcry_mpi_t W, gcry_mpi_t U,
+          gcry_mpi_t V, gcry_mpi_t M)
+
+     W = U * V \bmod M.
+
+ -- Function: void gcry_mpi_mul_2exp (gcry_mpi_t W, gcry_mpi_t U,
+          unsigned long E)
+
+     W = U * 2^e.
+
+ -- Function: void gcry_mpi_div (gcry_mpi_t Q, gcry_mpi_t R,
+          gcry_mpi_t DIVIDEND, gcry_mpi_t DIVISOR, int ROUND)
+
+     Q = DIVIDEND / DIVISOR, R = DIVIDEND \bmod DIVISOR.  Q and R may be
+     passed as 'NULL'.  ROUND should be negative or 0.
+
+ -- Function: void gcry_mpi_mod (gcry_mpi_t R, gcry_mpi_t DIVIDEND,
+          gcry_mpi_t DIVISOR)
+
+     R = DIVIDEND \bmod DIVISOR.
+
+ -- Function: void gcry_mpi_powm (gcry_mpi_t W, const gcry_mpi_t B,
+          const gcry_mpi_t E, const gcry_mpi_t M)
+
+     W = B^e \bmod M.
+
+ -- Function: int gcry_mpi_gcd (gcry_mpi_t G, gcry_mpi_t A,
+          gcry_mpi_t B)
+
+     Set G to the greatest common divisor of A and B.  Return true if
+     the G is 1.
+
+ -- Function: int gcry_mpi_invm (gcry_mpi_t X, gcry_mpi_t A,
+          gcry_mpi_t M)
+
+     Set X to the multiplicative inverse of A \bmod M.  Return true if
+     the inverse exists.
+
+\1f
+File: gcrypt.info,  Node: Comparisons,  Next: Bit manipulations,  Prev: Calculations,  Up: MPI library
+
+12.5 Comparisons
+================
+
+The next 2 functions are used to compare MPIs:
+
+ -- Function: int gcry_mpi_cmp (const gcry_mpi_t U, const gcry_mpi_t V)
+
+     Compare the multi-precision-integers number U and V returning 0 for
+     equality, a positive value for U > V and a negative for U < V.  If
+     both numbers are opaque values (cf, gcry_mpi_set_opaque) the
+     comparison is done by checking the bit sizes using memcmp.  If only
+     one number is an opaque value, the opaque value is less than the
+     other number.
+
+ -- Function: int gcry_mpi_cmp_ui (const gcry_mpi_t U, unsigned long V)
+
+     Compare the multi-precision-integers number U with the unsigned
+     integer V returning 0 for equality, a positive value for U > V and
+     a negative for U < V.
+
+ -- Function: int gcry_mpi_is_neg (const gcry_mpi_t A)
+
+     Return 1 if A is less than zero; return 0 if zero or positive.
+
+\1f
+File: gcrypt.info,  Node: Bit manipulations,  Next: EC functions,  Prev: Comparisons,  Up: MPI library
+
+12.6 Bit manipulations
+======================
+
+There are a couple of functions to get information on arbitrary bits in
+an MPI and to set or clear them:
+
+ -- Function: unsigned int gcry_mpi_get_nbits (gcry_mpi_t A)
+
+     Return the number of bits required to represent A.
+
+ -- Function: int gcry_mpi_test_bit (gcry_mpi_t A, unsigned int N)
+
+     Return true if bit number N (counting from 0) is set in A.
+
+ -- Function: void gcry_mpi_set_bit (gcry_mpi_t A, unsigned int N)
+
+     Set bit number N in A.
+
+ -- Function: void gcry_mpi_clear_bit (gcry_mpi_t A, unsigned int N)
+
+     Clear bit number N in A.
+
+ -- Function: void gcry_mpi_set_highbit (gcry_mpi_t A, unsigned int N)
+
+     Set bit number N in A and clear all bits greater than N.
+
+ -- Function: void gcry_mpi_clear_highbit (gcry_mpi_t A, unsigned int N)
+
+     Clear bit number N in A and all bits greater than N.
+
+ -- Function: void gcry_mpi_rshift (gcry_mpi_t X, gcry_mpi_t A,
+          unsigned int N)
+
+     Shift the value of A by N bits to the right and store the result in
+     X.
+
+ -- Function: void gcry_mpi_lshift (gcry_mpi_t X, gcry_mpi_t A,
+          unsigned int N)
+
+     Shift the value of A by N bits to the left and store the result in
+     X.
+
+\1f
+File: gcrypt.info,  Node: EC functions,  Next: Miscellaneous,  Prev: Bit manipulations,  Up: MPI library
+
+12.7 EC functions
+=================
+
+Libgcrypt provides an API to access low level functions used by its
+elliptic curve implementation.  These functions allow to implement
+elliptic curve methods for which no explicit support is available.
+
+ -- Function: gcry_mpi_point_t gcry_mpi_point_new (unsigned int NBITS)
+
+     Allocate a new point object, initialize it to 0, and allocate
+     enough memory for a points of at least NBITS.  This pre-allocation
+     yields only a small performance win and is not really necessary
+     because Libgcrypt automatically re-allocates the required memory.
+     Using 0 for NBITS is usually the right thing to do.
+
+ -- Function: void gcry_mpi_point_release (gcry_mpi_point_t POINT)
+
+     Release POINT and free all associated resources.  Passing 'NULL' is
+     allowed and ignored.
+
+ -- Function: void gcry_mpi_point_get (gcry_mpi_t X, gcry_mpi_t Y,
+          gcry_mpi_t Z, gcry_mpi_point_t POINT)
+
+     Store the projective coordinates from POINT into the MPIs X, Y, and
+     Z.  If a coordinate is not required, 'NULL' may be used for X, Y,
+     or Z.
+
+ -- Function: void gcry_mpi_point_snatch_get (gcry_mpi_t X,
+          gcry_mpi_t Y, gcry_mpi_t Z, gcry_mpi_point_t POINT)
+
+     Store the projective coordinates from POINT into the MPIs X, Y, and
+     Z.  If a coordinate is not required, 'NULL' may be used for X, Y,
+     or Z.  The object POINT is then released.  Using this function
+     instead of 'gcry_mpi_point_get' and 'gcry_mpi_point_release' has
+     the advantage of avoiding some extra memory allocations and copies.
+
+ -- Function: gcry_mpi_point_t gcry_mpi_point_set (
+          gcry_mpi_point_t POINT, gcry_mpi_t X, gcry_mpi_t Y,
+          gcry_mpi_t Z)
+
+     Store the projective coordinates from X, Y, and Z into POINT.  If a
+     coordinate is given as 'NULL', the value 0 is used.  If 'NULL' is
+     used for POINT a new point object is allocated and returned.
+     Returns POINT or the newly allocated point object.
+
+ -- Function: gcry_mpi_point_t gcry_mpi_point_snatch_set (
+          gcry_mpi_point_t POINT, gcry_mpi_t X, gcry_mpi_t Y,
+          gcry_mpi_t Z)
+
+     Store the projective coordinates from X, Y, and Z into POINT.  If a
+     coordinate is given as 'NULL', the value 0 is used.  If 'NULL' is
+     used for POINT a new point object is allocated and returned.  The
+     MPIs X, Y, and Z are released.  Using this function instead of
+     'gcry_mpi_point_set' and 3 calls to 'gcry_mpi_release' has the
+     advantage of avoiding some extra memory allocations and copies.
+     Returns POINT or the newly allocated point object.
+
+ -- Function: gpg_error_t gcry_mpi_ec_new (gcry_ctx_t *R_CTX,
+          gcry_sexp_t KEYPARAM, const char *CURVENAME)
+
+     Allocate a new context for elliptic curve operations.  If KEYPARAM
+     is given it specifies the parameters of the curve (*note
+     ecc_keyparam::).  If CURVENAME is given in addition to KEYPARAM and
+     the key parameters do not include a named curve reference, the
+     string CURVENAME is used to fill in missing parameters.  If only
+     CURVENAME is given, the context is initialized for this named
+     curve.
+
+     If a parameter specifying a point (e.g.  'g' or 'q') is not found,
+     the parser looks for a non-encoded point by appending '.x', '.y',
+     and '.z' to the parameter name and looking them all up to create a
+     point.  A parameter with the suffix '.z' is optional and defaults
+     to 1.
+
+     On success the function returns 0 and stores the new context object
+     at R_CTX; this object eventually needs to be released (*note
+     gcry_ctx_release::).  On error the function stores 'NULL' at R_CTX
+     and returns an error code.
+
+ -- Function: gcry_mpi_t gcry_mpi_ec_get_mpi ( const char *NAME,
+          gcry_ctx_t CTX, int COPY)
+
+     Return the MPI with NAME from the context CTX.  If not found 'NULL'
+     is returned.  If the returned MPI may later be modified, it is
+     suggested to pass '1' to COPY, so that the function guarantees that
+     a modifiable copy of the MPI is returned.  If '0' is used for COPY,
+     this function may return a constant flagged MPI. In any case
+     'gcry_mpi_release' needs to be called to release the result.  For
+     valid names *note ecc_keyparam::.  If the public key 'q' is
+     requested but only the private key 'd' is available, 'q' will be
+     recomputed on the fly.  If a point parameter is requested it is
+     returned as an uncompressed encoded point unless these special
+     names are used:
+     Q@EDDSA
+          Return an EdDSA style compressed point.  This is only
+          supported for Twisted Edwards curves.
+
+ -- Function: gcry_mpi_point_t gcry_mpi_ec_get_point ( const char *NAME,
+          gcry_ctx_t CTX, int COPY)
+
+     Return the point with NAME from the context CTX.  If not found
+     'NULL' is returned.  If the returned MPI may later be modified, it
+     is suggested to pass '1' to COPY, so that the function guarantees
+     that a modifiable copy of the MPI is returned.  If '0' is used for
+     COPY, this function may return a constant flagged point.  In any
+     case 'gcry_mpi_point_release' needs to be called to release the
+     result.  If the public key 'q' is requested but only the private
+     key 'd' is available, 'q' will be recomputed on the fly.
+
+ -- Function: gpg_error_t gcry_mpi_ec_set_mpi ( const char *NAME,
+          gcry_mpi_t NEWVALUE, gcry_ctx_t CTX)
+
+     Store the MPI NEWVALUE at NAME into the context CTX.  On success
+     '0' is returned; on error an error code.  Valid names are the MPI
+     parameters of an elliptic curve (*note ecc_keyparam::).
+
+ -- Function: gpg_error_t gcry_mpi_ec_set_point ( const char *NAME,
+          gcry_mpi_point_t NEWVALUE, gcry_ctx_t CTX)
+
+     Store the point NEWVALUE at NAME into the context CTX.  On success
+     '0' is returned; on error an error code.  Valid names are the point
+     parameters of an elliptic curve (*note ecc_keyparam::).
+
+ -- Function: gpg_err_code_t gcry_mpi_ec_decode_point (
+          mpi_point_t RESULT, gcry_mpi_t VALUE, gcry_ctx_t CTX)
+
+     Decode the point given as an MPI in VALUE and store at RESULT.  To
+     decide which encoding is used the function takes a context CTX
+     which can be created with 'gcry_mpi_ec_new'.  If 'NULL' is given
+     for the context the function assumes a 0x04 prefixed uncompressed
+     encoding.  On error an error code is returned and RESULT might be
+     changed.
+
+ -- Function: int gcry_mpi_ec_get_affine ( gcry_mpi_t X, gcry_mpi_t Y,
+          gcry_mpi_point_t POINT, gcry_ctx_t CTX)
+
+     Compute the affine coordinates from the projective coordinates in
+     POINT and store them into X and Y.  If one coordinate is not
+     required, 'NULL' may be passed to X or Y.  CTX is the context
+     object which has been created using 'gcry_mpi_ec_new'.  Returns 0
+     on success or not 0 if POINT is at infinity.
+
+     Note that you can use 'gcry_mpi_ec_set_point' with the value
+     'GCRYMPI_CONST_ONE' for Z to convert affine coordinates back into
+     projective coordinates.
+
+ -- Function: void gcry_mpi_ec_dup ( gcry_mpi_point_t W,
+          gcry_mpi_point_t U, gcry_ctx_t CTX)
+
+     Double the point U of the elliptic curve described by CTX and store
+     the result into W.
+
+ -- Function: void gcry_mpi_ec_add ( gcry_mpi_point_t W,
+          gcry_mpi_point_t U, gcry_mpi_point_t V, gcry_ctx_t CTX)
+
+     Add the points U and V of the elliptic curve described by CTX and
+     store the result into W.
+
+ -- Function: void gcry_mpi_ec_sub ( gcry_mpi_point_t W,
+          gcry_mpi_point_t U, gcry_mpi_point_t V, gcry_ctx_t CTX)
+
+     Subtracts the point V from the point U of the elliptic curve
+     described by CTX and store the result into W.  Only Twisted Edwards
+     curves are supported for now.
+
+ -- Function: void gcry_mpi_ec_mul ( gcry_mpi_point_t W, gcry_mpi_t N,
+          gcry_mpi_point_t U, gcry_ctx_t CTX)
+
+     Multiply the point U of the elliptic curve described by CTX by N
+     and store the result into W.
+
+ -- Function: int gcry_mpi_ec_curve_point ( gcry_mpi_point_t POINT,
+          gcry_ctx_t CTX)
+
+     Return true if POINT is on the elliptic curve described by CTX.
+
+\1f
+File: gcrypt.info,  Node: Miscellaneous,  Prev: EC functions,  Up: MPI library
+
+12.8 Miscellaneous
+==================
+
+An MPI data type is allowed to be "misused" to store an arbitrary value.
+Two functions implement this kludge:
+
+ -- Function: gcry_mpi_t gcry_mpi_set_opaque (gcry_mpi_t A, void *P,
+          unsigned int NBITS)
+
+     Store NBITS of the value P points to in A and mark A as an opaque
+     value (i.e.  an value that can't be used for any math calculation
+     and is only used to store an arbitrary bit pattern in A).
+     Ownership of P is taken by this function and thus the user may not
+     use dereference the passed value anymore.  It is required that them
+     memory referenced by P has been allocated in a way that 'gcry_free'
+     is able to release it.
+
+     WARNING: Never use an opaque MPI for actual math operations.  The
+     only valid functions are gcry_mpi_get_opaque and gcry_mpi_release.
+     Use gcry_mpi_scan to convert a string of arbitrary bytes into an
+     MPI.
+
+ -- Function: gcry_mpi_t gcry_mpi_set_opaque_copy (gcry_mpi_t A,
+          const void *P, unsigned int NBITS)
+
+     Same as 'gcry_mpi_set_opaque' but ownership of P is not taken
+     instead a copy of P is used.
+
+ -- Function: void * gcry_mpi_get_opaque (gcry_mpi_t A,
+          unsigned int *NBITS)
+
+     Return a pointer to an opaque value stored in A and return its size
+     in NBITS.  Note that the returned pointer is still owned by A and
+     that the function should never be used for an non-opaque MPI.
+
+   Each MPI has an associated set of flags for special purposes.  The
+currently defined flags are:
+
+'GCRYMPI_FLAG_SECURE'
+     Setting this flag converts A into an MPI stored in "secure memory".
+     Clearing this flag is not allowed.
+'GCRYMPI_FLAG_OPAQUE'
+     This is an interanl flag, indicating the an opaque valuue and not
+     an integer is stored.  This is an read-only flag; it may not be set
+     or cleared.
+'GCRYMPI_FLAG_IMMUTABLE'
+     If this flag is set, the MPI is marked as immutable.  Setting or
+     changing the value of that MPI is ignored and an error message is
+     logged.  The flag is sometimes useful for debugging.
+'GCRYMPI_FLAG_CONST'
+     If this flag is set, the MPI is marked as a constant and as
+     immutable Setting or changing the value of that MPI is ignored and
+     an error message is logged.  Such an MPI will never be deallocated
+     and may thus be used without copying.  Note that using
+     gcry_mpi_copy will return a copy of that constant with this and the
+     immutable flag cleared.  A few commonly used constants are
+     pre-defined and accessible using the macros 'GCRYMPI_CONST_ONE',
+     'GCRYMPI_CONST_TWO', 'GCRYMPI_CONST_THREE', 'GCRYMPI_CONST_FOUR',
+     and 'GCRYMPI_CONST_EIGHT'.
+'GCRYMPI_FLAG_USER1'
+'GCRYMPI_FLAG_USER2'
+'GCRYMPI_FLAG_USER3'
+'GCRYMPI_FLAG_USER4'
+     These flags are reserved for use by the application.
+
+ -- Function: void gcry_mpi_set_flag (gcry_mpi_t A,
+          enum gcry_mpi_flag FLAG)
+
+     Set the FLAG for the MPI A.  The only allowed flags are
+     'GCRYMPI_FLAG_SECURE', 'GCRYMPI_FLAG_IMMUTABLE', and
+     'GCRYMPI_FLAG_CONST'.
+
+ -- Function: void gcry_mpi_clear_flag (gcry_mpi_t A,
+          enum gcry_mpi_flag FLAG)
+
+     Clear FLAG for the multi-precision-integers A.  The only allowed
+     flag is 'GCRYMPI_FLAG_IMMUTABLE' but only if 'GCRYMPI_FLAG_CONST'
+     is not set.  If 'GCRYMPI_FLAG_CONST' is set, clearing
+     'GCRYMPI_FLAG_IMMUTABLE' will simply be ignored.
+   o
+ -- Function: int gcry_mpi_get_flag (gcry_mpi_t A,
+          enum gcry_mpi_flag FLAG)
+
+     Return true if FLAG is set for A.
+
+   To put a random value into an MPI, the following convenience function
+may be used:
+
+ -- Function: void gcry_mpi_randomize (gcry_mpi_t W, unsigned int NBITS,
+          enum gcry_random_level LEVEL)
+
+     Set the multi-precision-integers W to a random non-negative number
+     of NBITS, using random data quality of level LEVEL.  In case NBITS
+     is not a multiple of a byte, NBITS is rounded up to the next byte
+     boundary.  When using a LEVEL of 'GCRY_WEAK_RANDOM' this function
+     makes use of 'gcry_create_nonce'.
+
+\1f
+File: gcrypt.info,  Node: Prime numbers,  Next: Utilities,  Prev: MPI library,  Up: Top
+
+13 Prime numbers
+****************
+
+* Menu:
+
+* Generation::                  Generation of new prime numbers.
+* Checking::                    Checking if a given number is prime.
+
+\1f
+File: gcrypt.info,  Node: Generation,  Next: Checking,  Up: Prime numbers
+
+13.1 Generation
+===============
+
+ -- Function: gcry_error_t gcry_prime_generate (gcry_mpi_t
+          *PRIME,unsigned int PRIME_BITS, unsigned int FACTOR_BITS,
+          gcry_mpi_t **FACTORS, gcry_prime_check_func_t CB_FUNC, void
+          *CB_ARG, gcry_random_level_t RANDOM_LEVEL, unsigned int FLAGS)
+
+     Generate a new prime number of PRIME_BITS bits and store it in
+     PRIME.  If FACTOR_BITS is non-zero, one of the prime factors of
+     (PRIME - 1) / 2 must be FACTOR_BITS bits long.  If FACTORS is
+     non-zero, allocate a new, 'NULL'-terminated array holding the prime
+     factors and store it in FACTORS.  FLAGS might be used to influence
+     the prime number generation process.
+
+ -- Function: gcry_error_t gcry_prime_group_generator (gcry_mpi_t *R_G,
+          gcry_mpi_t PRIME, gcry_mpi_t *FACTORS, gcry_mpi_t START_G)
+
+     Find a generator for PRIME where the factorization of (PRIME-1) is
+     in the 'NULL' terminated array FACTORS.  Return the generator as a
+     newly allocated MPI in R_G.  If START_G is not NULL, use this as
+     the start for the search.
+
+ -- Function: void gcry_prime_release_factors (gcry_mpi_t *FACTORS)
+
+     Convenience function to release the FACTORS array.
+
+\1f
+File: gcrypt.info,  Node: Checking,  Prev: Generation,  Up: Prime numbers
+
+13.2 Checking
+=============
+
+ -- Function: gcry_error_t gcry_prime_check (gcry_mpi_t P, unsigned int
+          FLAGS)
+
+     Check whether the number P is prime.  Returns zero in case P is
+     indeed a prime, returns 'GPG_ERR_NO_PRIME' in case P is not a prime
+     and a different error code in case something went horribly wrong.
+
+\1f
+File: gcrypt.info,  Node: Utilities,  Next: Tools,  Prev: Prime numbers,  Up: Top
+
+14 Utilities
+************
+
+* Menu:
+
+* Memory allocation::   Functions related with memory allocation.
+* Context management::  Functions related with context management.
+* Buffer description::  A data type to describe buffers.
+
+\1f
+File: gcrypt.info,  Node: Memory allocation,  Next: Context management,  Up: Utilities
+
+14.1 Memory allocation
+======================
+
+ -- Function: void * gcry_malloc (size_t N)
+
+     This function tries to allocate N bytes of memory.  On success it
+     returns a pointer to the memory area, in an out-of-core condition,
+     it returns NULL.
+
+ -- Function: void * gcry_malloc_secure (size_t N)
+     Like 'gcry_malloc', but uses secure memory.
+
+ -- Function: void * gcry_calloc (size_t N, size_t M)
+
+     This function allocates a cleared block of memory (i.e.
+     initialized with zero bytes) long enough to contain a vector of N
+     elements, each of size M bytes.  On success it returns a pointer to
+     the memory block; in an out-of-core condition, it returns NULL.
+
+ -- Function: void * gcry_calloc_secure (size_t N, size_t M)
+     Like 'gcry_calloc', but uses secure memory.
+
+ -- Function: void * gcry_realloc (void *P, size_t N)
+
+     This function tries to resize the memory area pointed to by P to N
+     bytes.  On success it returns a pointer to the new memory area, in
+     an out-of-core condition, it returns NULL. Depending on whether the
+     memory pointed to by P is secure memory or not, gcry_realloc tries
+     to use secure memory as well.
+
+ -- Function: void gcry_free (void *P)
+     Release the memory area pointed to by P.
+
+\1f
+File: gcrypt.info,  Node: Context management,  Next: Buffer description,  Prev: Memory allocation,  Up: Utilities
+
+14.2 Context management
+=======================
+
+Some function make use of a context object.  As of now there are only a
+few math functions.  However, future versions of Libgcrypt may make more
+use of this context object.
+
+ -- Data type: gcry_ctx_t
+     This type is used to refer to the general purpose context object.
+
+ -- Function: void gcry_ctx_release (gcry_ctx_t CTX)
+     Release the context object CTX and all associated resources.  A
+     'NULL' passed as CTX is ignored.
+
+\1f
+File: gcrypt.info,  Node: Buffer description,  Prev: Context management,  Up: Utilities
+
+14.3 Buffer description
+=======================
+
+To help hashing non-contiguous areas of memory a general purpose data
+type is defined:
+
+ -- Data type: gcry_buffer_t
+     This type is a structure to describe a buffer.  The user should
+     make sure that this structure is initialized to zero.  The
+     available fields of this structure are:
+
+     '.size'
+          This is either 0 for no information available or indicates the
+          allocated length of the buffer.
+     '.off'
+          This is the offset into the buffer.
+     '.len'
+          This is the valid length of the buffer starting at '.off'.
+     '.data'
+          This is the address of the buffer.
+
+\1f
+File: gcrypt.info,  Node: Tools,  Next: Configuration,  Prev: Utilities,  Up: Top
+
+15 Tools
+********
+
+* Menu:
+
+* hmac256:: A standalone HMAC-SHA-256 implementation
+
+\1f
+File: gcrypt.info,  Node: hmac256,  Up: Tools
+
+15.1 A HMAC-SHA-256 tool
+========================
+
+This is a standalone HMAC-SHA-256 implementation used to compute an
+HMAC-SHA-256 message authentication code.  The tool has originally been
+developed as a second implementation for Libgcrypt to allow comparing
+against the primary implementation and to be used for internal
+consistency checks.  It should not be used for sensitive data because no
+mechanisms to clear the stack etc are used.
+
+   The code has been written in a highly portable manner and requires
+only a few standard definitions to be provided in a config.h file.
+
+'hmac256' is commonly invoked as
+
+     hmac256 "This is my key" foo.txt
+
+This compute the MAC on the file 'foo.txt' using the key given on the
+command line.
+
+'hmac256' understands these options:
+
+'--binary'
+     Print the MAC as a binary string.  The default is to print the MAC
+     encoded has lower case hex digits.
+
+'--version'
+     Print version of the program and exit.
+
+\1f
+File: gcrypt.info,  Node: Configuration,  Next: Architecture,  Prev: Tools,  Up: Top
+
+16 Configuration files and evironment variables
+***********************************************
+
+This chapter describes which files and environment variables can be used
+to change the behaviour of Libgcrypt.
+
+The environment variables considered by Libgcrypt are:
+
+'GCRYPT_BARRETT'
+     By setting this variable to any value a different algorithm for
+     modular reduction is used for ECC.
+
+'GCRYPT_RNDUNIX_DBG'
+'GCRYPT_RNDUNIX_DBGALL'
+     These two environment variables are used to enable debug output for
+     the rndunix entropy gatherer, which is used on systems lacking a
+     /dev/random device.  The value of 'GCRYPT_RNDUNIX_DBG' is a file
+     name or '-' for stdout.  Debug output is the written to this file.
+     By setting 'GCRYPT_RNDUNIX_DBGALL' to any value the debug output
+     will be more verbose.
+
+'GCRYPT_RNDW32_NOPERF'
+     Setting this environment variable on Windows to any value disables
+     the use of performance data ('HKEY_PERFORMANCE_DATA') as source for
+     entropy.  On some older Windows systems this could help to speed up
+     the creation of random numbers but also decreases the amount of
+     data used to init the random number generator.
+
+'HOME'
+     This is used to locate the socket to connect to the EGD random
+     daemon.  The EGD can be used on system without a /dev/random to
+     speed up the random number generator.  It is not needed on the
+     majority of today's operating systems and support for EGD requires
+     the use of a configure option at build time.
+
+The files which Libgcrypt uses to retrieve system information and the
+files which can be created by the user to modify Libgcrypt's behavior
+are:
+
+'/etc/gcrypt/hwf.deny'
+     This file can be used to disable the use of hardware based
+     optimizations, *note hardware features::.
+
+'/etc/gcrypt/fips_enabled'
+'/proc/sys/crypto/fips_enabled'
+     On Linux these files are used to enable FIPS mode, *note enabling
+     fips mode::.
+
+'/proc/cpuinfo'
+'/proc/self/auxv'
+     On Linux running on the ARM architecture, these files are used to
+     read hardware capabilities of the CPU.
+
+\1f
+File: gcrypt.info,  Node: Architecture,  Next: Self-Tests,  Prev: Configuration,  Up: Top
+
+17 Architecture
+***************
+
+This chapter describes the internal architecture of Libgcrypt.
+
+   Libgcrypt is a function library written in ISO C-90.  Any compliant
+compiler should be able to build Libgcrypt as long as the target is
+either a POSIX platform or compatible to the API used by Windows NT.
+Provisions have been take so that the library can be directly used from
+C++ applications; however building with a C++ compiler is not supported.
+
+   Building Libgcrypt is done by using the common './configure && make'
+approach.  The configure command is included in the source distribution
+and as a portable shell script it works on any Unix-alike system.  The
+result of running the configure script are a C header file ('config.h'),
+customized Makefiles, the setup of symbolic links and a few other
+things.  After that the make tool builds and optionally installs the
+library and the documentation.  See the files 'INSTALL' and 'README' in
+the source distribution on how to do this.
+
+   Libgcrypt is developed using a Subversion(1) repository.  Although
+all released versions are tagged in this repository, they should not be
+used to build production versions of Libgcrypt.  Instead released
+tarballs should be used.  These tarballs are available from several
+places with the master copy at 'ftp://ftp.gnupg.org/gcrypt/libgcrypt/'.
+Announcements of new releases are posted to the
+'gnupg-announce@gnupg.org' mailing list(2).
+
+    \0\b[image src="libgcrypt-modules.png" alt="Libgcrypt subsystems"\0\b]
+
+Figure 17.1: Libgcrypt subsystems
+
+   Libgcrypt consists of several subsystems (*note Figure 17.1:
+fig:subsystems.) and all these subsystems provide a public API; this
+includes the helper subsystems like the one for S-expressions.  The API
+style depends on the subsystem; in general an open-use-close approach is
+implemented.  The open returns a handle to a context used for all
+further operations on this handle, several functions may then be used on
+this handle and a final close function releases all resources associated
+with the handle.
+
+* Menu:
+
+* Public-Key Subsystem Architecture::              About public keys.
+* Symmetric Encryption Subsystem Architecture::    About standard ciphers.
+* Hashing and MACing Subsystem Architecture::      About hashing.
+* Multi-Precision-Integer Subsystem Architecture:: About big integers.
+* Prime-Number-Generator Subsystem Architecture::  About prime numbers.
+* Random-Number Subsystem Architecture::           About random stuff.
+
+   ---------- Footnotes ----------
+
+   (1) A version control system available for many platforms
+
+   (2) See <http://www.gnupg.org/documentation/mailing-lists.en.html>
+for details.
+
+\1f
+File: gcrypt.info,  Node: Public-Key Subsystem Architecture,  Next: Symmetric Encryption Subsystem Architecture,  Up: Architecture
+
+17.1 Public-Key Architecture
+============================
+
+Because public key cryptography is almost always used to process small
+amounts of data (hash values or session keys), the interface is not
+implemented using the open-use-close paradigm, but with single
+self-contained functions.  Due to the wide variety of parameters
+required by different algorithms S-expressions, as flexible way to
+convey these parameters, are used.  There is a set of helper functions
+to work with these S-expressions.
+
+   Aside of functions to register new algorithms, map algorithms names
+to algorithms identifiers and to lookup properties of a key, the
+following main functions are available:
+
+'gcry_pk_encrypt'
+     Encrypt data using a public key.
+
+'gcry_pk_decrypt'
+     Decrypt data using a private key.
+
+'gcry_pk_sign'
+     Sign data using a private key.
+
+'gcry_pk_verify'
+     Verify that a signature matches the data.
+
+'gcry_pk_testkey'
+     Perform a consistency over a public or private key.
+
+'gcry_pk_genkey'
+     Create a new public/private key pair.
+
+   All these functions lookup the module implementing the algorithm and
+pass the actual work to that module.  The parsing of the S-expression
+input and the construction of S-expression for the return values is done
+by the high level code ('cipher/pubkey.c').  Thus the internal interface
+between the algorithm modules and the high level functions passes data
+in a custom format.
+
+   By default Libgcrypt uses a blinding technique for RSA decryption to
+mitigate real world timing attacks over a network: Instead of using the
+RSA decryption directly, a blinded value y = x r^{e} \bmod n is
+decrypted and the unblinded value x' = y' r^{-1} \bmod n returned.  The
+blinding value r is a random value with the size of the modulus n and
+generated with 'GCRY_WEAK_RANDOM' random level.
+
+   The algorithm used for RSA and DSA key generation depends on whether
+Libgcrypt is operated in standard or in FIPS mode.  In standard mode an
+algorithm based on the Lim-Lee prime number generator is used.  In FIPS
+mode RSA keys are generated as specified in ANSI X9.31 (1998) and DSA
+keys as specified in FIPS 186-2.
+
+\1f
+File: gcrypt.info,  Node: Symmetric Encryption Subsystem Architecture,  Next: Hashing and MACing Subsystem Architecture,  Prev: Public-Key Subsystem Architecture,  Up: Architecture
+
+17.2 Symmetric Encryption Subsystem Architecture
+================================================
+
+The interface to work with symmetric encryption algorithms is made up of
+functions from the 'gcry_cipher_' name space.  The implementation
+follows the open-use-close paradigm and uses registered algorithm
+modules for the actual work.  Unless a module implements optimized
+cipher mode implementations, the high level code ('cipher/cipher.c')
+implements the modes and calls the core algorithm functions to process
+each block.
+
+   The most important functions are:
+
+'gcry_cipher_open'
+     Create a new instance to encrypt or decrypt using a specified
+     algorithm and mode.
+
+'gcry_cipher_close'
+     Release an instance.
+
+'gcry_cipher_setkey'
+     Set a key to be used for encryption or decryption.
+
+'gcry_cipher_setiv'
+     Set an initialization vector to be used for encryption or
+     decryption.
+
+'gcry_cipher_encrypt'
+'gcry_cipher_decrypt'
+     Encrypt or decrypt data.  These functions may be called with
+     arbitrary amounts of data and as often as needed to encrypt or
+     decrypt all data.
+
+   There are also functions to query properties of algorithms or
+context, like block length, key length, map names or to enable features
+like padding methods.
+
+\1f
+File: gcrypt.info,  Node: Hashing and MACing Subsystem Architecture,  Next: Multi-Precision-Integer Subsystem Architecture,  Prev: Symmetric Encryption Subsystem Architecture,  Up: Architecture
+
+17.3 Hashing and MACing Subsystem Architecture
+==============================================
+
+The interface to work with message digests and CRC algorithms is made up
+of functions from the 'gcry_md_' name space.  The implementation follows
+the open-use-close paradigm and uses registered algorithm modules for
+the actual work.  Although CRC algorithms are not considered
+cryptographic hash algorithms, they share enough properties so that it
+makes sense to handle them in the same way.  It is possible to use
+several algorithms at once with one context and thus compute them all on
+the same data.
+
+   The most important functions are:
+
+'gcry_md_open'
+     Create a new message digest instance and optionally enable one
+     algorithm.  A flag may be used to turn the message digest algorithm
+     into a HMAC algorithm.
+
+'gcry_md_enable'
+     Enable an additional algorithm for the instance.
+
+'gcry_md_setkey'
+     Set the key for the MAC.
+
+'gcry_md_write'
+     Pass more data for computing the message digest to an instance.
+
+'gcry_md_putc'
+     Buffered version of 'gcry_md_write' implemented as a macro.
+
+'gcry_md_read'
+     Finalize the computation of the message digest or HMAC and return
+     the result.
+
+'gcry_md_close'
+     Release an instance
+
+'gcry_md_hash_buffer'
+     Convenience function to directly compute a message digest over a
+     memory buffer without the need to create an instance first.
+
+   There are also functions to query properties of algorithms or the
+instance, like enabled algorithms, digest length, map algorithm names.
+it is also possible to reset an instance or to copy the current state of
+an instance at any time.  Debug functions to write the hashed data to
+files are available as well.
+
+\1f
+File: gcrypt.info,  Node: Multi-Precision-Integer Subsystem Architecture,  Next: Prime-Number-Generator Subsystem Architecture,  Prev: Hashing and MACing Subsystem Architecture,  Up: Architecture
+
+17.4 Multi-Precision-Integer Subsystem Architecture
+===================================================
+
+The implementation of Libgcrypt's big integer computation code is based
+on an old release of GNU Multi-Precision Library (GMP). The decision not
+to use the GMP library directly was due to stalled development at that
+time and due to security requirements which could not be provided by the
+code in GMP. As GMP does, Libgcrypt provides high performance assembler
+implementations of low level code for several CPUS to gain much better
+performance than with a generic C implementation.
+
+Major features of Libgcrypt's multi-precision-integer code compared to
+GMP are:
+
+   * Avoidance of stack based allocations to allow protection against
+     swapping out of sensitive data and for easy zeroing of sensitive
+     intermediate results.
+
+   * Optional use of secure memory and tracking of its use so that
+     results are also put into secure memory.
+
+   * MPIs are identified by a handle (implemented as a pointer) to give
+     better control over allocations and to augment them with extra
+     properties like opaque data.
+
+   * Removal of unnecessary code to reduce complexity.
+
+   * Functions specialized for public key cryptography.
+
+\1f
+File: gcrypt.info,  Node: Prime-Number-Generator Subsystem Architecture,  Next: Random-Number Subsystem Architecture,  Prev: Multi-Precision-Integer Subsystem Architecture,  Up: Architecture
+
+17.5 Prime-Number-Generator Subsystem Architecture
+==================================================
+
+Libgcrypt provides an interface to its prime number generator.  These
+functions make use of the internal prime number generator which is
+required for the generation for public key key pairs.  The plain prime
+checking function is exported as well.
+
+   The generation of random prime numbers is based on the Lim and Lee
+algorithm to create practically save primes.(1)  This algorithm creates
+a pool of smaller primes, select a few of them to create candidate
+primes of the form 2 * p_0 * p_1 * ... * p_n + 1, tests the candidate
+for primality and permutates the pool until a prime has been found.  It
+is possible to clamp one of the small primes to a certain size to help
+DSA style algorithms.  Because most of the small primes in the pool are
+not used for the resulting prime number, they are saved for later use
+(see 'save_pool_prime' and 'get_pool_prime' in 'cipher/primegen.c').
+The prime generator optionally supports the finding of an appropriate
+generator.
+
+The primality test works in three steps:
+
+  1. The standard sieve algorithm using the primes up to 4999 is used as
+     a quick first check.
+
+  2. A Fermat test filters out almost all non-primes.
+
+  3. A 5 round Rabin-Miller test is finally used.  The first round uses
+     a witness of 2, whereas the next rounds use a random witness.
+
+   To support the generation of RSA and DSA keys in FIPS mode according
+to X9.31 and FIPS 186-2, Libgcrypt implements two additional prime
+generation functions: '_gcry_derive_x931_prime' and
+'_gcry_generate_fips186_2_prime'.  These functions are internal and not
+available through the public API.
+
+   ---------- Footnotes ----------
+
+   (1) Chae Hoon Lim and Pil Joong Lee.  A key recovery attack on
+discrete log-based schemes using a prime order subgroup.  In Burton S.
+Kaliski Jr., editor, Advances in Cryptology: Crypto '97, pages
+249­-263, Berlin / Heidelberg / New York, 1997.  Springer-Verlag.
+Described on page 260.
+
+\1f
+File: gcrypt.info,  Node: Random-Number Subsystem Architecture,  Prev: Prime-Number-Generator Subsystem Architecture,  Up: Architecture
+
+17.6 Random-Number Subsystem Architecture
+=========================================
+
+Libgcrypt provides 3 levels or random quality: The level
+'GCRY_VERY_STRONG_RANDOM' usually used for key generation, the level
+'GCRY_STRONG_RANDOM' for all other strong random requirements and the
+function 'gcry_create_nonce' which is used for weaker usages like
+nonces.  There is also a level 'GCRY_WEAK_RANDOM' which in general maps
+to 'GCRY_STRONG_RANDOM' except when used with the function
+'gcry_mpi_randomize', where it randomizes an multi-precision-integer
+using the 'gcry_create_nonce' function.
+
+There are two distinct random generators available:
+
+   * The Continuously Seeded Pseudo Random Number Generator (CSPRNG),
+     which is based on the classic GnuPG derived big pool
+     implementation.  Implemented in 'random/random-csprng.c' and used
+     by default.
+   * A FIPS approved ANSI X9.31 PRNG using AES with a 128 bit key.
+     Implemented in 'random/random-fips.c' and used if Libgcrypt is in
+     FIPS mode.
+
+Both generators make use of so-called entropy gathering modules:
+
+rndlinux
+     Uses the operating system provided '/dev/random' and '/dev/urandom'
+     devices.
+
+rndunix
+     Runs several operating system commands to collect entropy from
+     sources like virtual machine and process statistics.  It is a kind
+     of poor-man's '/dev/random' implementation.  It is not available in
+     FIPS mode.
+
+rndegd
+     Uses the operating system provided Entropy Gathering Daemon (EGD).
+     The EGD basically uses the same algorithms as rndunix does.
+     However as a system daemon it keeps on running and thus can serve
+     several processes requiring entropy input and does not waste
+     collected entropy if the application does not need all the
+     collected entropy.  It is not available in FIPS mode.
+
+rndw32
+     Targeted for the Microsoft Windows OS. It uses certain properties
+     of that system and is the only gathering module available for that
+     OS.
+
+rndhw
+     Extra module to collect additional entropy by utilizing a hardware
+     random number generator.  As of now the supported hardware RNG is
+     the Padlock engine of VIA (Centaur) CPUs and x86 CPUs with the
+     RDRAND instruction.  It is not available in FIPS mode.
+
+* Menu:
+
+* CSPRNG Description::      Description of the CSPRNG.
+* FIPS PRNG Description::   Description of the FIPS X9.31 PRNG.
+
+\1f
+File: gcrypt.info,  Node: CSPRNG Description,  Next: FIPS PRNG Description,  Up: Random-Number Subsystem Architecture
+
+17.6.1 Description of the CSPRNG
+--------------------------------
+
+This random number generator is loosely modelled after the one described
+in Peter Gutmann's paper: "Software Generation of Practically Strong
+Random Numbers".(1)
+
+   A pool of 600 bytes is used and mixed using the core SHA-1 hash
+transform function.  Several extra features are used to make the robust
+against a wide variety of attacks and to protect against failures of
+subsystems.  The state of the generator may be saved to a file and
+initially seed form a file.
+
+   Depending on how Libgcrypt was build the generator is able to select
+the best working entropy gathering module.  It makes use of the slow and
+fast collection methods and requires the pool to initially seeded form
+the slow gatherer or a seed file.  An entropy estimation is used to mix
+in enough data from the gather modules before returning the actual
+random output.  Process fork detection and protection is implemented.
+
+   The implementation of the nonce generator (for 'gcry_create_nonce')
+is a straightforward repeated hash design: A 28 byte buffer is initially
+seeded with the PID and the time in seconds in the first 20 bytes and
+with 8 bytes of random taken from the 'GCRY_STRONG_RANDOM' generator.
+Random numbers are then created by hashing all the 28 bytes with SHA-1
+and saving that again in the first 20 bytes.  The hash is also returned
+as result.
+
+   ---------- Footnotes ----------
+
+   (1) Also described in chapter 6 of his book "Cryptographic Security
+Architecture", New York, 2004, ISBN 0-387-95387-6.
+
+\1f
+File: gcrypt.info,  Node: FIPS PRNG Description,  Prev: CSPRNG Description,  Up: Random-Number Subsystem Architecture
+
+17.6.2 Description of the FIPS X9.31 PRNG
+-----------------------------------------
+
+The core of this deterministic random number generator is implemented
+according to the document "NIST-Recommended Random Number Generator
+Based on ANSI X9.31 Appendix A.2.4 Using the 3-Key Triple DES and AES
+Algorithms", dated 2005-01-31.  This implementation uses the AES
+variant.
+
+   The generator is based on contexts to utilize the same core functions
+for all random levels as required by the high-level interface.  All
+random generators return their data in 128 bit blocks.  If the caller
+requests less bits, the extra bits are not used.  The key for each
+generator is only set once at the first time a generator context is
+used.  The seed value is set along with the key and again after 1000
+output blocks.
+
+   On Unix like systems the 'GCRY_VERY_STRONG_RANDOM' and
+'GCRY_STRONG_RANDOM' generators are keyed and seeded using the rndlinux
+module with the '/dev/random' device.  Thus these generators may block
+until the OS kernel has collected enough entropy.  When used with
+Microsoft Windows the rndw32 module is used instead.
+
+   The generator used for 'gcry_create_nonce' is keyed and seeded from
+the 'GCRY_STRONG_RANDOM' generator.  Thus is may also block if the
+'GCRY_STRONG_RANDOM' generator has not yet been used before and thus
+gets initialized on the first use by 'gcry_create_nonce'.  This special
+treatment is justified by the weaker requirements for a nonce generator
+and to save precious kernel entropy for use by the "real" random
+generators.
+
+   A self-test facility uses a separate context to check the
+functionality of the core X9.31 functions using a known answers test.
+During runtime each output block is compared to the previous one to
+detect a stuck generator.
+
+   The DT value for the generator is made up of the current time down to
+microseconds (if available) and a free running 64 bit counter.  When
+used with the test context the DT value is taken from the context and
+incremented on each use.
+
+\1f
+File: gcrypt.info,  Node: Self-Tests,  Next: FIPS Mode,  Prev: Architecture,  Up: Top
+
+Appendix A Description of the Self-Tests
+****************************************
+
+In addition to the build time regression test suite, Libgcrypt
+implements self-tests to be performed at runtime.  Which self-tests are
+actually used depends on the mode Libgcrypt is used in.  In standard
+mode a limited set of self-tests is run at the time an algorithm is
+first used.  Note that not all algorithms feature a self-test in
+standard mode.  The 'GCRYCTL_SELFTEST' control command may be used to
+run all implemented self-tests at any time; this will even run more
+tests than those run in FIPS mode.
+
+   If any of the self-tests fails, the library immediately returns an
+error code to the caller.  If Libgcrypt is in FIPS mode the self-tests
+will be performed within the "Self-Test" state and any failure puts the
+library into the "Error" state.
+
+A.1 Power-Up Tests
+==================
+
+Power-up tests are only performed if Libgcrypt is in FIPS mode.
+
+A.1.1 Symmetric Cipher Algorithm Power-Up Tests
+-----------------------------------------------
+
+The following symmetric encryption algorithm tests are run during
+power-up:
+
+3DES
+     To test the 3DES 3-key EDE encryption in ECB mode these tests are
+     run:
+       1. A known answer test is run on a 64 bit test vector processed
+          by 64 rounds of Single-DES block encryption and decryption
+          using a key changed with each round.
+       2. A known answer test is run on a 64 bit test vector processed
+          by 16 rounds of 2-key and 3-key Triple-DES block encryption
+          and decryptions using a key changed with each round.
+       3. 10 known answer tests using 3-key Triple-DES EDE encryption,
+          comparing the ciphertext to the known value, then running a
+          decryption and comparing it to the initial plaintext.
+     ('cipher/des.c:selftest')
+
+AES-128
+     A known answer tests is run using one test vector and one test key
+     with AES in ECB mode.  ('cipher/rijndael.c:selftest_basic_128')
+
+AES-192
+     A known answer tests is run using one test vector and one test key
+     with AES in ECB mode.  ('cipher/rijndael.c:selftest_basic_192')
+
+AES-256
+     A known answer tests is run using one test vector and one test key
+     with AES in ECB mode.  ('cipher/rijndael.c:selftest_basic_256')
+
+A.1.2 Hash Algorithm Power-Up Tests
+-----------------------------------
+
+The following hash algorithm tests are run during power-up:
+
+SHA-1
+     A known answer test using the string '"abc"' is run.
+     ('cipher/sha1.c:selftests_sha1')
+SHA-224
+     A known answer test using the string '"abc"' is run.
+     ('cipher/sha256.c:selftests_sha224')
+SHA-256
+     A known answer test using the string '"abc"' is run.
+     ('cipher/sha256.c:selftests_sha256')
+SHA-384
+     A known answer test using the string '"abc"' is run.
+     ('cipher/sha512.c:selftests_sha384')
+SHA-512
+     A known answer test using the string '"abc"' is run.
+     ('cipher/sha512.c:selftests_sha512')
+
+A.1.3 MAC Algorithm Power-Up Tests
+----------------------------------
+
+The following MAC algorithm tests are run during power-up:
+
+HMAC SHA-1
+     A known answer test using 9 byte of data and a 64 byte key is run.
+     ('cipher/hmac-tests.c:selftests_sha1')
+HMAC SHA-224
+     A known answer test using 28 byte of data and a 4 byte key is run.
+     ('cipher/hmac-tests.c:selftests_sha224')
+HMAC SHA-256
+     A known answer test using 28 byte of data and a 4 byte key is run.
+     ('cipher/hmac-tests.c:selftests_sha256')
+HMAC SHA-384
+     A known answer test using 28 byte of data and a 4 byte key is run.
+     ('cipher/hmac-tests.c:selftests_sha384')
+HMAC SHA-512
+     A known answer test using 28 byte of data and a 4 byte key is run.
+     ('cipher/hmac-tests.c:selftests_sha512')
+
+A.1.4 Random Number Power-Up Test
+---------------------------------
+
+The DRNG is tested during power-up this way:
+
+  1. Requesting one block of random using the public interface to check
+     general working and the duplicated block detection.
+  2. 3 know answer tests using pre-defined keys, seed and initial DT
+     values.  For each test 3 blocks of 16 bytes are requested and
+     compared to the expected result.  The DT value is incremented for
+     each block.
+
+A.1.5 Public Key Algorithm Power-Up Tests
+-----------------------------------------
+
+The public key algorithms are tested during power-up:
+
+RSA
+     A pre-defined 1024 bit RSA key is used and these tests are run in
+     turn:
+       1. Conversion of S-expression to internal format.
+          ('cipher/rsa.c:selftests_rsa')
+       2. Private key consistency check.  ('cipher/rsa.c:selftests_rsa')
+       3. A pre-defined 20 byte value is signed with PKCS#1 padding for
+          SHA-1.  The result is verified using the public key against
+          the original data and against modified data.
+          ('cipher/rsa.c:selftest_sign_1024')
+       4. A 1000 bit random value is encrypted and checked that it does
+          not match the original random value.  The encrypted result is
+          then decrypted and checked that it matches the original random
+          value.  ('cipher/rsa.c:selftest_encr_1024')
+
+DSA
+     A pre-defined 1024 bit DSA key is used and these tests are run in
+     turn:
+       1. Conversion of S-expression to internal format.
+          ('cipher/dsa.c:selftests_dsa')
+       2. Private key consistency check.  ('cipher/dsa.c:selftests_dsa')
+       3. A pre-defined 20 byte value is signed with PKCS#1 padding for
+          SHA-1.  The result is verified using the public key against
+          the original data and against modified data.
+          ('cipher/dsa.c:selftest_sign_1024')
+
+A.1.6 Integrity Power-Up Tests
+------------------------------
+
+The integrity of the Libgcrypt is tested during power-up but only if
+checking has been enabled at build time.  The check works by computing a
+HMAC SHA-256 checksum over the file used to load Libgcrypt into memory.
+That checksum is compared against a checksum stored in a file of the
+same name but with a single dot as a prefix and a suffix of '.hmac'.
+
+A.1.7 Critical Functions Power-Up Tests
+---------------------------------------
+
+The 3DES weak key detection is tested during power-up by calling the
+detection function with keys taken from a table listening all weak keys.
+The table itself is protected using a SHA-1 hash.
+('cipher/des.c:selftest')
+
+A.2 Conditional Tests
+=====================
+
+The conditional tests are performed if a certain condition is met.  This
+may occur at any time; the library does not necessary enter the
+"Self-Test" state to run these tests but will transit to the "Error"
+state if a test failed.
+
+A.2.1 Key-Pair Generation Tests
+-------------------------------
+
+After an asymmetric key-pair has been generated, Libgcrypt runs a
+pair-wise consistency tests on the generated key.  On failure the
+generated key is not used, an error code is returned and, if in FIPS
+mode, the library is put into the "Error" state.
+
+RSA
+     The test uses a random number 64 bits less the size of the modulus
+     as plaintext and runs an encryption and decryption operation in
+     turn.  The encrypted value is checked to not match the plaintext
+     and the result of the decryption is checked to match the plaintext.
+
+     A new random number of the same size is generated, signed and
+     verified to test the correctness of the signing operation.  As a
+     second signing test, the signature is modified by incrementing its
+     value and then verified with the expected result that the
+     verification fails.  ('cipher/rsa.c:test_keys')
+DSA
+     The test uses a random number of the size of the Q parameter to
+     create a signature and then checks that the signature verifies.  As
+     a second signing test, the data is modified by incrementing its
+     value and then verified against the signature with the expected
+     result that the verification fails.  ('cipher/dsa.c:test_keys')
+
+A.2.2 Software Load Tests
+-------------------------
+
+No code is loaded at runtime.
+
+A.2.3 Manual Key Entry Tests
+----------------------------
+
+A manual key entry feature is not implemented in Libgcrypt.
+
+A.2.4 Continuous RNG Tests
+--------------------------
+
+The continuous random number test is only used in FIPS mode.  The RNG
+generates blocks of 128 bit size; the first block generated per context
+is saved in the context and another block is generated to be returned to
+the caller.  Each block is compared against the saved block and then
+stored in the context.  If a duplicated block is detected an error is
+signaled and the library is put into the "Fatal-Error" state.
+('random/random-fips.c:x931_aes_driver')
+
+A.3 Application Requested Tests
+===============================
+
+The application may requests tests at any time by means of the
+'GCRYCTL_SELFTEST' control command.  Note that using these tests is not
+FIPS conform: Although Libgcrypt rejects all application requests for
+services while running self-tests, it does not ensure that no other
+operations of Libgcrypt are still being executed.  Thus, in FIPS mode an
+application requesting self-tests needs to power-cycle Libgcrypt
+instead.
+
+   When self-tests are requested, Libgcrypt runs all the tests it does
+during power-up as well as a few extra checks as described below.
+
+A.3.1 Symmetric Cipher Algorithm Tests
+--------------------------------------
+
+The following symmetric encryption algorithm tests are run in addition
+to the power-up tests:
+
+AES-128
+     A known answer tests with test vectors taken from NIST SP800-38a
+     and using the high level functions is run for block modes CFB and
+     OFB.
+
+A.3.2 Hash Algorithm Tests
+--------------------------
+
+The following hash algorithm tests are run in addition to the power-up
+tests:
+
+SHA-1
+SHA-224
+SHA-256
+       1. A known answer test using a 56 byte string is run.
+       2. A known answer test using a string of one million letters "a"
+          is run.
+     ('cipher/sha1.c:selftests_sha1',
+     'cipher/sha256.c:selftests_sha224',
+     'cipher/sha256.c:selftests_sha256')
+SHA-384
+SHA-512
+       1. A known answer test using a 112 byte string is run.
+       2. A known answer test using a string of one million letters "a"
+          is run.
+     ('cipher/sha512.c:selftests_sha384',
+     'cipher/sha512.c:selftests_sha512')
+
+A.3.3 MAC Algorithm Tests
+-------------------------
+
+The following MAC algorithm tests are run in addition to the power-up
+tests:
+
+HMAC SHA-1
+       1. A known answer test using 9 byte of data and a 20 byte key is
+          run.
+       2. A known answer test using 9 byte of data and a 100 byte key is
+          run.
+       3. A known answer test using 9 byte of data and a 49 byte key is
+          run.
+     ('cipher/hmac-tests.c:selftests_sha1')
+HMAC SHA-224
+HMAC SHA-256
+HMAC SHA-384
+HMAC SHA-512
+       1. A known answer test using 9 byte of data and a 20 byte key is
+          run.
+       2. A known answer test using 50 byte of data and a 20 byte key is
+          run.
+       3. A known answer test using 50 byte of data and a 26 byte key is
+          run.
+       4. A known answer test using 54 byte of data and a 131 byte key
+          is run.
+       5. A known answer test using 152 byte of data and a 131 byte key
+          is run.
+     ('cipher/hmac-tests.c:selftests_sha224',
+     'cipher/hmac-tests.c:selftests_sha256',
+     'cipher/hmac-tests.c:selftests_sha384',
+     'cipher/hmac-tests.c:selftests_sha512')
+
+\1f
+File: gcrypt.info,  Node: FIPS Mode,  Next: Library Copying,  Prev: Self-Tests,  Up: Top
+
+Appendix B Description of the FIPS Mode
+***************************************
+
+This appendix gives detailed information pertaining to the FIPS mode.
+In particular, the changes to the standard mode and the finite state
+machine are described.  The self-tests required in this mode are
+described in the appendix on self-tests.
+
+B.1 Restrictions in FIPS Mode
+=============================
+
+If Libgcrypt is used in FIPS mode these restrictions are effective:
+
+   * The cryptographic algorithms are restricted to this list:
+
+     GCRY_CIPHER_3DES
+          3 key EDE Triple-DES symmetric encryption.
+     GCRY_CIPHER_AES128
+          AES 128 bit symmetric encryption.
+     GCRY_CIPHER_AES192
+          AES 192 bit symmetric encryption.
+     GCRY_CIPHER_AES256
+          AES 256 bit symmetric encryption.
+     GCRY_MD_SHA1
+          SHA-1 message digest.
+     GCRY_MD_SHA224
+          SHA-224 message digest.
+     GCRY_MD_SHA256
+          SHA-256 message digest.
+     GCRY_MD_SHA384
+          SHA-384 message digest.
+     GCRY_MD_SHA512
+          SHA-512 message digest.
+     GCRY_MD_SHA1,GCRY_MD_FLAG_HMAC
+          HMAC using a SHA-1 message digest.
+     GCRY_MD_SHA224,GCRY_MD_FLAG_HMAC
+          HMAC using a SHA-224 message digest.
+     GCRY_MD_SHA256,GCRY_MD_FLAG_HMAC
+          HMAC using a SHA-256 message digest.
+     GCRY_MD_SHA384,GCRY_MD_FLAG_HMAC
+          HMAC using a SHA-384 message digest.
+     GCRY_MD_SHA512,GCRY_MD_FLAG_HMAC
+          HMAC using a SHA-512 message digest.
+     GCRY_PK_RSA
+          RSA encryption and signing.
+     GCRY_PK_DSA
+          DSA signing.
+
+     Note that the CRC algorithms are not considered cryptographic
+     algorithms and thus are in addition available.
+
+   * RSA key generation refuses to create a key with a keysize of less
+     than 1024 bits.
+
+   * DSA key generation refuses to create a key with a keysize other
+     than 1024 bits.
+
+   * The 'transient-key' flag for RSA and DSA key generation is ignored.
+
+   * Support for the VIA Padlock engine is disabled.
+
+   * FIPS mode may only be used on systems with a /dev/random device.
+     Switching into FIPS mode on other systems will fail at runtime.
+
+   * Saving and loading a random seed file is ignored.
+
+   * An X9.31 style random number generator is used in place of the
+     large-pool-CSPRNG generator.
+
+   * The command 'GCRYCTL_ENABLE_QUICK_RANDOM' is ignored.
+
+   * Message digest debugging is disabled.
+
+   * All debug output related to cryptographic data is suppressed.
+
+   * On-the-fly self-tests are not performed, instead self-tests are run
+     before entering operational state.
+
+   * The function 'gcry_set_allocation_handler' may not be used.  If it
+     is used Libgcrypt disables FIPS mode unless Enforced FIPS mode is
+     enabled, in which case Libgcrypt will enter the error state.
+
+   * The digest algorithm MD5 may not be used.  If it is used Libgcrypt
+     disables FIPS mode unless Enforced FIPS mode is enabled, in which
+     case Libgcrypt will enter the error state.
+
+   * In Enforced FIPS mode the command 'GCRYCTL_DISABLE_SECMEM' is
+     ignored.  In standard FIPS mode it disables FIPS mode.
+
+   * A handler set by 'gcry_set_outofcore_handler' is ignored.
+   * A handler set by 'gcry_set_fatalerror_handler' is ignored.
+
+   Note that when we speak about disabling FIPS mode, it merely means
+that the function 'gcry_fips_mode_active' returns false; it does not
+mean that any non FIPS algorithms are allowed.
+
+B.2 FIPS Finite State Machine
+=============================
+
+The FIPS mode of libgcrypt implements a finite state machine (FSM) using
+8 states (*note Table B.1: tbl:fips-states.) and checks at runtime that
+only valid transitions (*note Table B.2: tbl:fips-state-transitions.)
+may happen.
+
+           \0\b[image src="fips-fsm.png" alt="FIPS FSM Diagram"\0\b]
+
+Figure B.1: FIPS mode state diagram
+
+States used by the FIPS FSM:
+
+Power-Off
+     Libgcrypt is not runtime linked to another application.  This
+     usually means that the library is not loaded into main memory.
+     This state is documentation only.
+
+Power-On
+     Libgcrypt is loaded into memory and API calls may be made.
+     Compiler introduced constructor functions may be run.  Note that
+     Libgcrypt does not implement any arbitrary constructor functions to
+     be called by the operating system
+
+Init
+     The Libgcrypt initialization functions are performed and the
+     library has not yet run any self-test.
+
+Self-Test
+     Libgcrypt is performing self-tests.
+
+Operational
+     Libgcrypt is in the operational state and all interfaces may be
+     used.
+
+Error
+     Libgrypt is in the error state.  When calling any FIPS relevant
+     interfaces they either return an error ('GPG_ERR_NOT_OPERATIONAL')
+     or put Libgcrypt into the Fatal-Error state and won't return.
+
+Fatal-Error
+     Libgcrypt is in a non-recoverable error state and will
+     automatically transit into the Shutdown state.
+
+Shutdown
+     Libgcrypt is about to be terminated and removed from the memory.
+     The application may at this point still running cleanup handlers.
+
+Table B.1: FIPS mode states
+
+The valid state transitions (*note Figure B.1: fig:fips-fsm.) are:
+'1'
+     Power-Off to Power-On is implicitly done by the OS loading
+     Libgcrypt as a shared library and having it linked to an
+     application.
+
+'2'
+     Power-On to Init is triggered by the application calling the
+     Libgcrypt initialization function 'gcry_check_version'.
+
+'3'
+     Init to Self-Test is either triggered by a dedicated API call or
+     implicit by invoking a libgrypt service controlled by the FSM.
+
+'4'
+     Self-Test to Operational is triggered after all self-tests passed
+     successfully.
+
+'5'
+     Operational to Shutdown is an artificial state without any direct
+     action in Libgcrypt.  When reaching the Shutdown state the library
+     is deinitialized and can't return to any other state again.
+
+'6'
+     Shutdown to Power-off is the process of removing Libgcrypt from the
+     computer's memory.  For obvious reasons the Power-Off state can't
+     be represented within Libgcrypt and thus this transition is for
+     documentation only.
+
+'7'
+     Operational to Error is triggered if Libgcrypt detected an
+     application error which can't be returned to the caller but still
+     allows Libgcrypt to properly run.  In the Error state all FIPS
+     relevant interfaces return an error code.
+
+'8'
+     Error to Shutdown is similar to the Operational to Shutdown
+     transition (5).
+
+'9'
+     Error to Fatal-Error is triggered if Libgrypt detects an fatal
+     error while already being in Error state.
+
+'10'
+     Fatal-Error to Shutdown is automatically entered by Libgcrypt after
+     having reported the error.
+
+'11'
+     Power-On to Shutdown is an artificial state to document that
+     Libgcrypt has not ye been initialized but the process is about to
+     terminate.
+
+'12'
+     Power-On to Fatal-Error will be triggered if certain Libgcrypt
+     functions are used without having reached the Init state.
+
+'13'
+     Self-Test to Fatal-Error is triggered by severe errors in Libgcrypt
+     while running self-tests.
+
+'14'
+     Self-Test to Error is triggered by a failed self-test.
+
+'15'
+     Operational to Fatal-Error is triggered if Libcrypt encountered a
+     non-recoverable error.
+
+'16'
+     Operational to Self-Test is triggered if the application requested
+     to run the self-tests again.
+
+'17'
+     Error to Self-Test is triggered if the application has requested to
+     run self-tests to get to get back into operational state after an
+     error.
+
+'18'
+     Init to Error is triggered by errors in the initialization code.
+
+'19'
+     Init to Fatal-Error is triggered by non-recoverable errors in the
+     initialization code.
+
+'20'
+     Error to Error is triggered by errors while already in the Error
+     state.
+
+Table B.2: FIPS mode state transitions
+
+B.3 FIPS Miscellaneous Information
+==================================
+
+Libgcrypt does not do any key management on itself; the application
+needs to care about it.  Keys which are passed to Libgcrypt should be
+allocated in secure memory as available with the functions
+'gcry_malloc_secure' and 'gcry_calloc_secure'.  By calling 'gcry_free'
+on this memory, the memory and thus the keys are overwritten with zero
+bytes before releasing the memory.
+
+   For use with the random number generator, Libgcrypt generates 3
+internal keys which are stored in the encryption contexts used by the
+RNG. These keys are stored in secure memory for the lifetime of the
+process.  Application are required to use 'GCRYCTL_TERM_SECMEM' before
+process termination.  This will zero out the entire secure memory and
+thus also the encryption contexts with these keys.
+
+\1f
+File: gcrypt.info,  Node: Library Copying,  Next: Copying,  Prev: FIPS Mode,  Up: Top
+
+GNU Lesser General Public License
+*********************************
+
+                      Version 2.1, February 1999
+
+     Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+     Everyone is permitted to copy and distribute verbatim copies
+     of this license document, but changing it is not allowed.
+
+     [This is the first released version of the Lesser GPL.  It also counts
+     as the successor of the GNU Library Public License, version 2, hence the
+     version number 2.1.]
+
+Preamble
+========
+
+The licenses for most software are designed to take away your freedom to
+share and change it.  By contrast, the GNU General Public Licenses are
+intended to guarantee your freedom to share and change free software--to
+make sure the software is free for all its users.
+
+   This license, the Lesser General Public License, applies to some
+specially designated software--typically libraries--of the Free Software
+Foundation and other authors who decide to use it.  You can use it too,
+but we suggest you first think carefully about whether this license or
+the ordinary General Public License is the better strategy to use in any
+particular case, based on the explanations below.
+
+   When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of it
+in new free programs; and that you are informed that you can do these
+things.
+
+   To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+   For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling it.
+And you must show them these terms so they know their rights.
+
+   We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+   To protect each distributor, we want to make it very clear that there
+is no warranty for the free library.  Also, if the library is modified
+by someone else and passed on, the recipients should know that what they
+have is not the original version, so that the original author's
+reputation will not be affected by problems that might be introduced by
+others.
+
+   Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that any
+patent license obtained for a version of the library must be consistent
+with the full freedom of use specified in this license.
+
+   Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and is
+quite different from the ordinary General Public License.  We use this
+license for certain libraries in order to permit linking those libraries
+into non-free programs.
+
+   When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the entire
+combination fits its criteria of freedom.  The Lesser General Public
+License permits more lax criteria for linking other code with the
+library.
+
+   We call this license the "Lesser" General Public License because it
+does _Less_ to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less of
+an advantage over competing non-free programs.  These disadvantages are
+the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+   For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it
+becomes a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free library
+does the same job as widely used non-free libraries.  In this case,
+there is little to gain by limiting the free library to free software
+only, so we use the Lesser General Public License.
+
+   In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of free
+software.  For example, permission to use the GNU C Library in non-free
+programs enables many more people to use the whole GNU operating system,
+as well as its variant, the GNU/Linux operating system.
+
+   Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is linked
+with the Library has the freedom and the wherewithal to run that program
+using a modified version of the Library.
+
+   The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+                   GNU LESSER GENERAL PUBLIC LICENSE
+    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+     program which contains a notice placed by the copyright holder or
+     other authorized party saying it may be distributed under the terms
+     of this Lesser General Public License (also called "this License").
+     Each licensee is addressed as "you".
+
+     A "library" means a collection of software functions and/or data
+     prepared so as to be conveniently linked with application programs
+     (which use some of those functions and data) to form executables.
+
+     The "Library", below, refers to any such software library or work
+     which has been distributed under these terms.  A "work based on the
+     Library" means either the Library or any derivative work under
+     copyright law: that is to say, a work containing the Library or a
+     portion of it, either verbatim or with modifications and/or
+     translated straightforwardly into another language.  (Hereinafter,
+     translation is included without limitation in the term
+     "modification".)
+
+     "Source code" for a work means the preferred form of the work for
+     making modifications to it.  For a library, complete source code
+     means all the source code for all modules it contains, plus any
+     associated interface definition files, plus the scripts used to
+     control compilation and installation of the library.
+
+     Activities other than copying, distribution and modification are
+     not covered by this License; they are outside its scope.  The act
+     of running a program using the Library is not restricted, and
+     output from such a program is covered only if its contents
+     constitute a work based on the Library (independent of the use of
+     the Library in a tool for writing it).  Whether that is true
+     depends on what the Library does and what the program that uses the
+     Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+     complete source code as you receive it, in any medium, provided
+     that you conspicuously and appropriately publish on each copy an
+     appropriate copyright notice and disclaimer of warranty; keep
+     intact all the notices that refer to this License and to the
+     absence of any warranty; and distribute a copy of this License
+     along with the Library.
+
+     You may charge a fee for the physical act of transferring a copy,
+     and you may at your option offer warranty protection in exchange
+     for a fee.
+
+  2. You may modify your copy or copies of the Library or any portion of
+     it, thus forming a work based on the Library, and copy and
+     distribute such modifications or work under the terms of Section 1
+     above, provided that you also meet all of these conditions:
+
+       a. The modified work must itself be a software library.
+
+       b. You must cause the files modified to carry prominent notices
+          stating that you changed the files and the date of any change.
+
+       c. You must cause the whole of the work to be licensed at no
+          charge to all third parties under the terms of this License.
+
+       d. If a facility in the modified Library refers to a function or
+          a table of data to be supplied by an application program that
+          uses the facility, other than as an argument passed when the
+          facility is invoked, then you must make a good faith effort to
+          ensure that, in the event an application does not supply such
+          function or table, the facility still operates, and performs
+          whatever part of its purpose remains meaningful.
+
+          (For example, a function in a library to compute square roots
+          has a purpose that is entirely well-defined independent of the
+          application.  Therefore, Subsection 2d requires that any
+          application-supplied function or table used by this function
+          must be optional: if the application does not supply it, the
+          square root function must still compute square roots.)
+
+     These requirements apply to the modified work as a whole.  If
+     identifiable sections of that work are not derived from the
+     Library, and can be reasonably considered independent and separate
+     works in themselves, then this License, and its terms, do not apply
+     to those sections when you distribute them as separate works.  But
+     when you distribute the same sections as part of a whole which is a
+     work based on the Library, the distribution of the whole must be on
+     the terms of this License, whose permissions for other licensees
+     extend to the entire whole, and thus to each and every part
+     regardless of who wrote it.
+
+     Thus, it is not the intent of this section to claim rights or
+     contest your rights to work written entirely by you; rather, the
+     intent is to exercise the right to control the distribution of
+     derivative or collective works based on the Library.
+
+     In addition, mere aggregation of another work not based on the
+     Library with the Library (or with a work based on the Library) on a
+     volume of a storage or distribution medium does not bring the other
+     work under the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+     License instead of this License to a given copy of the Library.  To
+     do this, you must alter all the notices that refer to this License,
+     so that they refer to the ordinary GNU General Public License,
+     version 2, instead of to this License.  (If a newer version than
+     version 2 of the ordinary GNU General Public License has appeared,
+     then you can specify that version instead if you wish.)  Do not
+     make any other change in these notices.
+
+     Once this change is made in a given copy, it is irreversible for
+     that copy, so the ordinary GNU General Public License applies to
+     all subsequent copies and derivative works made from that copy.
+
+     This option is useful when you wish to copy part of the code of the
+     Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or derivative
+     of it, under Section 2) in object code or executable form under the
+     terms of Sections 1 and 2 above provided that you accompany it with
+     the complete corresponding machine-readable source code, which must
+     be distributed under the terms of Sections 1 and 2 above on a
+     medium customarily used for software interchange.
+
+     If distribution of object code is made by offering access to copy
+     from a designated place, then offering equivalent access to copy
+     the source code from the same place satisfies the requirement to
+     distribute the source code, even though third parties are not
+     compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+     Library, but is designed to work with the Library by being compiled
+     or linked with it, is called a "work that uses the Library".  Such
+     a work, in isolation, is not a derivative work of the Library, and
+     therefore falls outside the scope of this License.
+
+     However, linking a "work that uses the Library" with the Library
+     creates an executable that is a derivative of the Library (because
+     it contains portions of the Library), rather than a "work that uses
+     the library".  The executable is therefore covered by this License.
+     Section 6 states terms for distribution of such executables.
+
+     When a "work that uses the Library" uses material from a header
+     file that is part of the Library, the object code for the work may
+     be a derivative work of the Library even though the source code is
+     not.  Whether this is true is especially significant if the work
+     can be linked without the Library, or if the work is itself a
+     library.  The threshold for this to be true is not precisely
+     defined by law.
+
+     If such an object file uses only numerical parameters, data
+     structure layouts and accessors, and small macros and small inline
+     functions (ten lines or less in length), then the use of the object
+     file is unrestricted, regardless of whether it is legally a
+     derivative work.  (Executables containing this object code plus
+     portions of the Library will still fall under Section 6.)
+
+     Otherwise, if the work is a derivative of the Library, you may
+     distribute the object code for the work under the terms of Section
+     6.  Any executables containing that work also fall under Section 6,
+     whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or link
+     a "work that uses the Library" with the Library to produce a work
+     containing portions of the Library, and distribute that work under
+     terms of your choice, provided that the terms permit modification
+     of the work for the customer's own use and reverse engineering for
+     debugging such modifications.
+
+     You must give prominent notice with each copy of the work that the
+     Library is used in it and that the Library and its use are covered
+     by this License.  You must supply a copy of this License.  If the
+     work during execution displays copyright notices, you must include
+     the copyright notice for the Library among them, as well as a
+     reference directing the user to the copy of this License.  Also,
+     you must do one of these things:
+
+       a. Accompany the work with the complete corresponding
+          machine-readable source code for the Library including
+          whatever changes were used in the work (which must be
+          distributed under Sections 1 and 2 above); and, if the work is
+          an executable linked with the Library, with the complete
+          machine-readable "work that uses the Library", as object code
+          and/or source code, so that the user can modify the Library
+          and then relink to produce a modified executable containing
+          the modified Library.  (It is understood that the user who
+          changes the contents of definitions files in the Library will
+          not necessarily be able to recompile the application to use
+          the modified definitions.)
+
+       b. Use a suitable shared library mechanism for linking with the
+          Library.  A suitable mechanism is one that (1) uses at run
+          time a copy of the library already present on the user's
+          computer system, rather than copying library functions into
+          the executable, and (2) will operate properly with a modified
+          version of the library, if the user installs one, as long as
+          the modified version is interface-compatible with the version
+          that the work was made with.
+
+       c. Accompany the work with a written offer, valid for at least
+          three years, to give the same user the materials specified in
+          Subsection 6a, above, for a charge no more than the cost of
+          performing this distribution.
+
+       d. If distribution of the work is made by offering access to copy
+          from a designated place, offer equivalent access to copy the
+          above specified materials from the same place.
+
+       e. Verify that the user has already received a copy of these
+          materials or that you have already sent this user a copy.
+
+     For an executable, the required form of the "work that uses the
+     Library" must include any data and utility programs needed for
+     reproducing the executable from it.  However, as a special
+     exception, the materials to be distributed need not include
+     anything that is normally distributed (in either source or binary
+     form) with the major components (compiler, kernel, and so on) of
+     the operating system on which the executable runs, unless that
+     component itself accompanies the executable.
+
+     It may happen that this requirement contradicts the license
+     restrictions of other proprietary libraries that do not normally
+     accompany the operating system.  Such a contradiction means you
+     cannot use both them and the Library together in an executable that
+     you distribute.
+
+  7. You may place library facilities that are a work based on the
+     Library side-by-side in a single library together with other
+     library facilities not covered by this License, and distribute such
+     a combined library, provided that the separate distribution of the
+     work based on the Library and of the other library facilities is
+     otherwise permitted, and provided that you do these two things:
+
+       a. Accompany the combined library with a copy of the same work
+          based on the Library, uncombined with any other library
+          facilities.  This must be distributed under the terms of the
+          Sections above.
+
+       b. Give prominent notice with the combined library of the fact
+          that part of it is a work based on the Library, and explaining
+          where to find the accompanying uncombined form of the same
+          work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute the
+     Library except as expressly provided under this License.  Any
+     attempt otherwise to copy, modify, sublicense, link with, or
+     distribute the Library is void, and will automatically terminate
+     your rights under this License.  However, parties who have received
+     copies, or rights, from you under this License will not have their
+     licenses terminated so long as such parties remain in full
+     compliance.
+
+  9. You are not required to accept this License, since you have not
+     signed it.  However, nothing else grants you permission to modify
+     or distribute the Library or its derivative works.  These actions
+     are prohibited by law if you do not accept this License.
+     Therefore, by modifying or distributing the Library (or any work
+     based on the Library), you indicate your acceptance of this License
+     to do so, and all its terms and conditions for copying,
+     distributing or modifying the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+     Library), the recipient automatically receives a license from the
+     original licensor to copy, distribute, link with or modify the
+     Library subject to these terms and conditions.  You may not impose
+     any further restrictions on the recipients' exercise of the rights
+     granted herein.  You are not responsible for enforcing compliance
+     by third parties with this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+     infringement or for any other reason (not limited to patent
+     issues), conditions are imposed on you (whether by court order,
+     agreement or otherwise) that contradict the conditions of this
+     License, they do not excuse you from the conditions of this
+     License.  If you cannot distribute so as to satisfy simultaneously
+     your obligations under this License and any other pertinent
+     obligations, then as a consequence you may not distribute the
+     Library at all.  For example, if a patent license would not permit
+     royalty-free redistribution of the Library by all those who receive
+     copies directly or indirectly through you, then the only way you
+     could satisfy both it and this License would be to refrain entirely
+     from distribution of the Library.
+
+     If any portion of this section is held invalid or unenforceable
+     under any particular circumstance, the balance of the section is
+     intended to apply, and the section as a whole is intended to apply
+     in other circumstances.
+
+     It is not the purpose of this section to induce you to infringe any
+     patents or other property right claims or to contest validity of
+     any such claims; this section has the sole purpose of protecting
+     the integrity of the free software distribution system which is
+     implemented by public license practices.  Many people have made
+     generous contributions to the wide range of software distributed
+     through that system in reliance on consistent application of that
+     system; it is up to the author/donor to decide if he or she is
+     willing to distribute software through any other system and a
+     licensee cannot impose that choice.
+
+     This section is intended to make thoroughly clear what is believed
+     to be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+     certain countries either by patents or by copyrighted interfaces,
+     the original copyright holder who places the Library under this
+     License may add an explicit geographical distribution limitation
+     excluding those countries, so that distribution is permitted only
+     in or among countries not thus excluded.  In such case, this
+     License incorporates the limitation as if written in the body of
+     this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+     versions of the Lesser General Public License from time to time.
+     Such new versions will be similar in spirit to the present version,
+     but may differ in detail to address new problems or concerns.
+
+     Each version is given a distinguishing version number.  If the
+     Library specifies a version number of this License which applies to
+     it and "any later version", you have the option of following the
+     terms and conditions either of that version or of any later version
+     published by the Free Software Foundation.  If the Library does not
+     specify a license version number, you may choose any version ever
+     published by the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+     programs whose distribution conditions are incompatible with these,
+     write to the author to ask for permission.  For software which is
+     copyrighted by the Free Software Foundation, write to the Free
+     Software Foundation; we sometimes make exceptions for this.  Our
+     decision will be guided by the two goals of preserving the free
+     status of all derivatives of our free software and of promoting the
+     sharing and reuse of software generally.
+
+                              NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+     WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE
+     LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS
+     AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY
+     OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
+     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+     FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
+     PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE
+     DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR
+     OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+     WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY
+     MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE
+     LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
+     INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
+     INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF
+     DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU
+     OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY
+     OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN
+     ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+                      END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Libraries
+==============================================
+
+If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of
+the ordinary General Public License).
+
+   To apply these terms, attach the following notices to the library.
+It is safest to attach them to the start of each source file to most
+effectively convey the exclusion of warranty; and each file should have
+at least the "copyright" line and a pointer to where the full notice is
+found.
+
+     ONE LINE TO GIVE THE LIBRARY'S NAME AND AN IDEA OF WHAT IT DOES.
+     Copyright (C) YEAR  NAME OF AUTHOR
+
+     This library is free software; you can redistribute it and/or modify it
+     under the terms of the GNU Lesser General Public License as published by
+     the Free Software Foundation; either version 2.1 of the License, or (at
+     your option) any later version.
+
+     This library is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Lesser General Public License for more details.
+
+     You should have received a copy of the GNU Lesser General Public
+     License along with this library; if not, write to the Free Software
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
+     USA.
+
+   Also add information on how to contact you by electronic and paper
+mail.
+
+   You should also get your employer (if you work as a programmer) or
+your school, if any, to sign a "copyright disclaimer" for the library,
+if necessary.  Here is a sample; alter the names:
+
+     Yoyodyne, Inc., hereby disclaims all copyright interest in the library
+     `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+     SIGNATURE OF TY COON, 1 April 1990
+     Ty Coon, President of Vice
+
+   That's all there is to it!
+
+\1f
+File: gcrypt.info,  Node: Copying,  Next: Figures and Tables,  Prev: Library Copying,  Up: Top
+
+GNU General Public License
+**************************
+
+                         Version 2, June 1991
+
+     Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+     Everyone is permitted to copy and distribute verbatim copies
+     of this license document, but changing it is not allowed.
+
+Preamble
+========
+
+The licenses for most software are designed to take away your freedom to
+share and change it.  By contrast, the GNU General Public License is
+intended to guarantee your freedom to share and change free software--to
+make sure the software is free for all its users.  This General Public
+License applies to most of the Free Software Foundation's software and
+to any other program whose authors commit to using it.  (Some other Free
+Software Foundation software is covered by the GNU Library General
+Public License instead.)  You can apply it to your programs, too.
+
+   When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it if
+you want it, that you can change the software or use pieces of it in new
+free programs; and that you know you can do these things.
+
+   To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+   For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+   We protect your rights with two steps: (1) copyright the software,
+and (2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+   Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+   Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+   The precise terms and conditions for copying, distribution and
+modification follow.
+
+    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  1. This License applies to any program or other work which contains a
+     notice placed by the copyright holder saying it may be distributed
+     under the terms of this General Public License.  The "Program",
+     below, refers to any such program or work, and a "work based on the
+     Program" means either the Program or any derivative work under
+     copyright law: that is to say, a work containing the Program or a
+     portion of it, either verbatim or with modifications and/or
+     translated into another language.  (Hereinafter, translation is
+     included without limitation in the term "modification".)  Each
+     licensee is addressed as "you".
+
+     Activities other than copying, distribution and modification are
+     not covered by this License; they are outside its scope.  The act
+     of running the Program is not restricted, and the output from the
+     Program is covered only if its contents constitute a work based on
+     the Program (independent of having been made by running the
+     Program).  Whether that is true depends on what the Program does.
+
+  2. You may copy and distribute verbatim copies of the Program's source
+     code as you receive it, in any medium, provided that you
+     conspicuously and appropriately publish on each copy an appropriate
+     copyright notice and disclaimer of warranty; keep intact all the
+     notices that refer to this License and to the absence of any
+     warranty; and give any other recipients of the Program a copy of
+     this License along with the Program.
+
+     You may charge a fee for the physical act of transferring a copy,
+     and you may at your option offer warranty protection in exchange
+     for a fee.
+
+  3. You may modify your copy or copies of the Program or any portion of
+     it, thus forming a work based on the Program, and copy and
+     distribute such modifications or work under the terms of Section 1
+     above, provided that you also meet all of these conditions:
+
+       a. You must cause the modified files to carry prominent notices
+          stating that you changed the files and the date of any change.
+
+       b. You must cause any work that you distribute or publish, that
+          in whole or in part contains or is derived from the Program or
+          any part thereof, to be licensed as a whole at no charge to
+          all third parties under the terms of this License.
+
+       c. If the modified program normally reads commands interactively
+          when run, you must cause it, when started running for such
+          interactive use in the most ordinary way, to print or display
+          an announcement including an appropriate copyright notice and
+          a notice that there is no warranty (or else, saying that you
+          provide a warranty) and that users may redistribute the
+          program under these conditions, and telling the user how to
+          view a copy of this License.  (Exception: if the Program
+          itself is interactive but does not normally print such an
+          announcement, your work based on the Program is not required
+          to print an announcement.)
+
+     These requirements apply to the modified work as a whole.  If
+     identifiable sections of that work are not derived from the
+     Program, and can be reasonably considered independent and separate
+     works in themselves, then this License, and its terms, do not apply
+     to those sections when you distribute them as separate works.  But
+     when you distribute the same sections as part of a whole which is a
+     work based on the Program, the distribution of the whole must be on
+     the terms of this License, whose permissions for other licensees
+     extend to the entire whole, and thus to each and every part
+     regardless of who wrote it.
+
+     Thus, it is not the intent of this section to claim rights or
+     contest your rights to work written entirely by you; rather, the
+     intent is to exercise the right to control the distribution of
+     derivative or collective works based on the Program.
+
+     In addition, mere aggregation of another work not based on the
+     Program with the Program (or with a work based on the Program) on a
+     volume of a storage or distribution medium does not bring the other
+     work under the scope of this License.
+
+  4. You may copy and distribute the Program (or a work based on it,
+     under Section 2) in object code or executable form under the terms
+     of Sections 1 and 2 above provided that you also do one of the
+     following:
+
+       a. Accompany it with the complete corresponding machine-readable
+          source code, which must be distributed under the terms of
+          Sections 1 and 2 above on a medium customarily used for
+          software interchange; or,
+
+       b. Accompany it with a written offer, valid for at least three
+          years, to give any third party, for a charge no more than your
+          cost of physically performing source distribution, a complete
+          machine-readable copy of the corresponding source code, to be
+          distributed under the terms of Sections 1 and 2 above on a
+          medium customarily used for software interchange; or,
+
+       c. Accompany it with the information you received as to the offer
+          to distribute corresponding source code.  (This alternative is
+          allowed only for noncommercial distribution and only if you
+          received the program in object code or executable form with
+          such an offer, in accord with Subsection b above.)
+
+     The source code for a work means the preferred form of the work for
+     making modifications to it.  For an executable work, complete
+     source code means all the source code for all modules it contains,
+     plus any associated interface definition files, plus the scripts
+     used to control compilation and installation of the executable.
+     However, as a special exception, the source code distributed need
+     not include anything that is normally distributed (in either source
+     or binary form) with the major components (compiler, kernel, and so
+     on) of the operating system on which the executable runs, unless
+     that component itself accompanies the executable.
+
+     If distribution of executable or object code is made by offering
+     access to copy from a designated place, then offering equivalent
+     access to copy the source code from the same place counts as
+     distribution of the source code, even though third parties are not
+     compelled to copy the source along with the object code.
+
+  5. You may not copy, modify, sublicense, or distribute the Program
+     except as expressly provided under this License.  Any attempt
+     otherwise to copy, modify, sublicense or distribute the Program is
+     void, and will automatically terminate your rights under this
+     License.  However, parties who have received copies, or rights,
+     from you under this License will not have their licenses terminated
+     so long as such parties remain in full compliance.
+
+  6. You are not required to accept this License, since you have not
+     signed it.  However, nothing else grants you permission to modify
+     or distribute the Program or its derivative works.  These actions
+     are prohibited by law if you do not accept this License.
+     Therefore, by modifying or distributing the Program (or any work
+     based on the Program), you indicate your acceptance of this License
+     to do so, and all its terms and conditions for copying,
+     distributing or modifying the Program or works based on it.
+
+  7. Each time you redistribute the Program (or any work based on the
+     Program), the recipient automatically receives a license from the
+     original licensor to copy, distribute or modify the Program subject
+     to these terms and conditions.  You may not impose any further
+     restrictions on the recipients' exercise of the rights granted
+     herein.  You are not responsible for enforcing compliance by third
+     parties to this License.
+
+  8. If, as a consequence of a court judgment or allegation of patent
+     infringement or for any other reason (not limited to patent
+     issues), conditions are imposed on you (whether by court order,
+     agreement or otherwise) that contradict the conditions of this
+     License, they do not excuse you from the conditions of this
+     License.  If you cannot distribute so as to satisfy simultaneously
+     your obligations under this License and any other pertinent
+     obligations, then as a consequence you may not distribute the
+     Program at all.  For example, if a patent license would not permit
+     royalty-free redistribution of the Program by all those who receive
+     copies directly or indirectly through you, then the only way you
+     could satisfy both it and this License would be to refrain entirely
+     from distribution of the Program.
+
+     If any portion of this section is held invalid or unenforceable
+     under any particular circumstance, the balance of the section is
+     intended to apply and the section as a whole is intended to apply
+     in other circumstances.
+
+     It is not the purpose of this section to induce you to infringe any
+     patents or other property right claims or to contest validity of
+     any such claims; this section has the sole purpose of protecting
+     the integrity of the free software distribution system, which is
+     implemented by public license practices.  Many people have made
+     generous contributions to the wide range of software distributed
+     through that system in reliance on consistent application of that
+     system; it is up to the author/donor to decide if he or she is
+     willing to distribute software through any other system and a
+     licensee cannot impose that choice.
+
+     This section is intended to make thoroughly clear what is believed
+     to be a consequence of the rest of this License.
+
+  9. If the distribution and/or use of the Program is restricted in
+     certain countries either by patents or by copyrighted interfaces,
+     the original copyright holder who places the Program under this
+     License may add an explicit geographical distribution limitation
+     excluding those countries, so that distribution is permitted only
+     in or among countries not thus excluded.  In such case, this
+     License incorporates the limitation as if written in the body of
+     this License.
+
+  10. The Free Software Foundation may publish revised and/or new
+     versions of the General Public License from time to time.  Such new
+     versions will be similar in spirit to the present version, but may
+     differ in detail to address new problems or concerns.
+
+     Each version is given a distinguishing version number.  If the
+     Program specifies a version number of this License which applies to
+     it and "any later version", you have the option of following the
+     terms and conditions either of that version or of any later version
+     published by the Free Software Foundation.  If the Program does not
+     specify a version number of this License, you may choose any
+     version ever published by the Free Software Foundation.
+
+  11. If you wish to incorporate parts of the Program into other free
+     programs whose distribution conditions are different, write to the
+     author to ask for permission.  For software which is copyrighted by
+     the Free Software Foundation, write to the Free Software
+     Foundation; we sometimes make exceptions for this.  Our decision
+     will be guided by the two goals of preserving the free status of
+     all derivatives of our free software and of promoting the sharing
+     and reuse of software generally.
+
+                              NO WARRANTY
+
+  12. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO
+     WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE
+     LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS
+     AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+     OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
+     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+     FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
+     PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
+     DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR
+     OR CORRECTION.
+
+  13. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+     WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY
+     MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE
+     LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
+     INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
+     INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+     DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU
+     OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY
+     OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN
+     ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+                      END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Programs
+=============================================
+
+If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these
+terms.
+
+   To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+     ONE LINE TO GIVE THE PROGRAM'S NAME AND AN IDEA OF WHAT IT DOES.
+     Copyright (C) 19YY  NAME OF AUTHOR
+
+     This program is free software; you can redistribute it and/or
+     modify it under the terms of the GNU General Public License
+     as published by the Free Software Foundation; either version 2
+     of the License, or (at your option) any later version.
+
+     This program is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+     GNU General Public License for more details.
+
+     You should have received a copy of the GNU General Public License along
+     with this program; if not, write to the Free Software Foundation, Inc.,
+     59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+
+   Also add information on how to contact you by electronic and paper
+mail.
+
+   If the program is interactive, make it output a short notice like
+this when it starts in an interactive mode:
+
+     Gnomovision version 69, Copyright (C) 19YY NAME OF AUTHOR
+     Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
+     type `show w'.  This is free software, and you are welcome
+     to redistribute it under certain conditions; type `show c'
+     for details.
+
+   The hypothetical commands 'show w' and 'show c' should show the
+appropriate parts of the General Public License.  Of course, the
+commands you use may be called something other than 'show w' and 'show
+c'; they could even be mouse-clicks or menu items--whatever suits your
+program.
+
+   You should also get your employer (if you work as a programmer) or
+your school, if any, to sign a "copyright disclaimer" for the program,
+if necessary.  Here is a sample; alter the names:
+
+     Yoyodyne, Inc., hereby disclaims all copyright
+     interest in the program `Gnomovision'
+     (which makes passes at compilers) written
+     by James Hacker.
+
+     SIGNATURE OF TY COON, 1 April 1989
+     Ty Coon, President of Vice
+
+   This General Public License does not permit incorporating your
+program into proprietary programs.  If your program is a subroutine
+library, you may consider it more useful to permit linking proprietary
+applications with the library.  If this is what you want to do, use the
+GNU Library General Public License instead of this License.
+
+\1f
+File: gcrypt.info,  Node: Figures and Tables,  Next: Concept Index,  Prev: Copying,  Up: Top
+
+List of Figures and Tables
+**************************
+
+* Menu:
+
+* Figure 17.1: fig:subsystems.           Libgcrypt subsystems
+* Figure B.1: fig:fips-fsm.              FIPS mode state diagram
+
+* Menu:
+
+* Table B.1: tbl:fips-states.            FIPS mode states
+* Table B.2: tbl:fips-state-transitions. FIPS mode state transitions
+
+\1f
+File: gcrypt.info,  Node: Concept Index,  Next: Function and Data Index,  Prev: Figures and Tables,  Up: Top
+
+Concept Index
+*************
+
+\0\b[index\0\b]
+* Menu:
+
+* /etc/gcrypt/fips_enabled:              Configuration.        (line 48)
+* /etc/gcrypt/hwf.deny:                  Configuration.        (line 43)
+* /proc/cpuinfo:                         Configuration.        (line 53)
+* /proc/self/auxv:                       Configuration.        (line 53)
+* 3DES:                                  Available ciphers.    (line 14)
+* Advanced Encryption Standard:          Available ciphers.    (line 35)
+* AES:                                   Available ciphers.    (line 35)
+* AES-Wrap mode:                         Available cipher modes.
+                                                               (line 35)
+* Arcfour:                               Available ciphers.    (line 52)
+* Blowfish:                              Available ciphers.    (line 22)
+* bug emulation:                         Working with hash algorithms.
+                                                               (line 38)
+* Camellia:                              Available ciphers.    (line 77)
+* CAST5:                                 Available ciphers.    (line 19)
+* CBC, Cipher Block Chaining mode:       Available cipher modes.
+                                                               (line 23)
+* CBC-MAC:                               Working with cipher handles.
+                                                               (line 56)
+* CCM, Counter with CBC-MAC mode:        Available cipher modes.
+                                                               (line 48)
+* CFB, Cipher Feedback mode:             Available cipher modes.
+                                                               (line 17)
+* ChaCha20:                              Available ciphers.    (line 92)
+* cipher text stealing:                  Working with cipher handles.
+                                                               (line 50)
+* comp:                                  Cryptographic Functions.
+                                                               (line 13)
+* CRC32:                                 Available hash algorithms.
+                                                               (line  6)
+* CTR, Counter mode:                     Available cipher modes.
+                                                               (line 32)
+* DES:                                   Available ciphers.    (line 57)
+* DES-EDE:                               Available ciphers.    (line 14)
+* Digital Encryption Standard:           Available ciphers.    (line 14)
+* ECB, Electronic Codebook mode:         Available cipher modes.
+                                                               (line 13)
+* EdDSA:                                 Cryptographic Functions.
+                                                               (line 33)
+* Enforced FIPS mode:                    Enabling FIPS mode.   (line 29)
+* error codes:                           Error Values.         (line  6)
+* error codes, list of:                  Error Sources.        (line  6)
+* error codes, list of <1>:              Error Codes.          (line  6)
+* error codes, printing of:              Error Strings.        (line  6)
+* error sources:                         Error Values.         (line  6)
+* error sources, printing of:            Error Strings.        (line  6)
+* error strings:                         Error Strings.        (line  6)
+* error values:                          Error Values.         (line  6)
+* error values, printing of:             Error Strings.        (line  6)
+* FIPS 140:                              Enabling FIPS mode.   (line  6)
+* FIPS 186:                              Cryptographic Functions.
+                                                               (line 72)
+* FIPS 186 <1>:                          Public-Key Subsystem Architecture.
+                                                               (line 50)
+* FIPS 186-2:                            Cryptographic Functions.
+                                                               (line 80)
+* FIPS mode:                             Enabling FIPS mode.   (line  6)
+* fips_enabled:                          Configuration.        (line 48)
+* GCM, Galois/Counter Mode:              Available cipher modes.
+                                                               (line 53)
+* GCRYPT_BARRETT:                        Configuration.        (line 12)
+* GCRYPT_RNDUNIX_DBG:                    Configuration.        (line 17)
+* GCRYPT_RNDUNIX_DBGALL:                 Configuration.        (line 17)
+* GCRYPT_RNDW32_NOPERF:                  Configuration.        (line 25)
+* GOST 28147-89:                         Available ciphers.    (line 88)
+* GPL, GNU General Public License:       Copying.              (line  6)
+* hardware features:                     Hardware features.    (line  6)
+* HAVAL:                                 Available hash algorithms.
+                                                               (line  6)
+* HMAC:                                  Working with hash algorithms.
+                                                               (line 28)
+* HMAC-GOSTR-3411-94:                    Available MAC algorithms.
+                                                               (line  6)
+* HMAC-MD2, HMAC-MD4, HMAC-MD5:          Available MAC algorithms.
+                                                               (line  6)
+* HMAC-RIPE-MD-160:                      Available MAC algorithms.
+                                                               (line  6)
+* HMAC-SHA-1:                            Available MAC algorithms.
+                                                               (line  6)
+* HMAC-SHA-224, HMAC-SHA-256, HMAC-SHA-384, HMAC-SHA-512: Available MAC algorithms.
+                                                               (line  6)
+* HMAC-SHA3-224, HMAC-SHA3-256, HMAC-SHA3-384, HMAC-SHA3-512: Available MAC algorithms.
+                                                               (line  6)
+* HMAC-Stribog-256, HMAC-Stribog-512:    Available MAC algorithms.
+                                                               (line  6)
+* HMAC-TIGER1:                           Available MAC algorithms.
+                                                               (line  6)
+* HMAC-Whirlpool:                        Available MAC algorithms.
+                                                               (line  6)
+* HOME:                                  Configuration.        (line 32)
+* IDEA:                                  Available ciphers.    (line 11)
+* LGPL, GNU Lesser General Public License: Library Copying.    (line  6)
+* MD2, MD4, MD5:                         Available hash algorithms.
+                                                               (line  6)
+* no-blinding:                           Cryptographic Functions.
+                                                               (line 41)
+* no-keytest:                            Cryptographic Functions.
+                                                               (line 59)
+* nocomp:                                Cryptographic Functions.
+                                                               (line 13)
+* OAEP:                                  Cryptographic Functions.
+                                                               (line 27)
+* OCB, OCB3:                             Available cipher modes.
+                                                               (line 63)
+* OFB, Output Feedback mode:             Available cipher modes.
+                                                               (line 29)
+* param:                                 Cryptographic Functions.
+                                                               (line 47)
+* PKCS1:                                 Cryptographic Functions.
+                                                               (line 23)
+* Poly1305 based AEAD mode with ChaCha20: Available cipher modes.
+                                                               (line 58)
+* PSS:                                   Cryptographic Functions.
+                                                               (line 30)
+* RC2:                                   Available ciphers.    (line 69)
+* RC4:                                   Available ciphers.    (line 52)
+* rfc-2268:                              Available ciphers.    (line 69)
+* RFC6979:                               Cryptographic Functions.
+                                                               (line 38)
+* Rijndael:                              Available ciphers.    (line 35)
+* RIPE-MD-160:                           Available hash algorithms.
+                                                               (line  6)
+* Salsa20:                               Available ciphers.    (line 81)
+* Salsa20/12:                            Available ciphers.    (line 84)
+* Seed (cipher):                         Available ciphers.    (line 72)
+* Serpent:                               Available ciphers.    (line 65)
+* SHA-1:                                 Available hash algorithms.
+                                                               (line  6)
+* SHA-224, SHA-256, SHA-384, SHA-512:    Available hash algorithms.
+                                                               (line  6)
+* SHA3-224, SHA3-256, SHA3-384, SHA3-512, SHAKE128, SHAKE256: Available hash algorithms.
+                                                               (line  6)
+* sync mode (OpenPGP):                   Working with cipher handles.
+                                                               (line 46)
+* TIGER, TIGER1, TIGER2:                 Available hash algorithms.
+                                                               (line  6)
+* transient-key:                         Cryptographic Functions.
+                                                               (line 52)
+* Triple-DES:                            Available ciphers.    (line 14)
+* Twofish:                               Available ciphers.    (line 46)
+* Whirlpool:                             Available hash algorithms.
+                                                               (line  6)
+* X9.31:                                 Cryptographic Functions.
+                                                               (line 65)
+* X9.31 <1>:                             Public-Key Subsystem Architecture.
+                                                               (line 50)
+
+\1f
+File: gcrypt.info,  Node: Function and Data Index,  Prev: Concept Index,  Up: Top
+
+Function and Data Index
+***********************
+
+\0\b[index\0\b]
+* Menu:
+
+* AM_PATH_LIBGCRYPT:                     Building sources using Automake.
+                                                              (line  11)
+* gcry_buffer_t:                         Buffer description.  (line   9)
+* gcry_calloc:                           Memory allocation.   (line  15)
+* gcry_calloc_secure:                    Memory allocation.   (line  22)
+* gcry_check_version:                    Initializing the library.
+                                                              (line  15)
+* gcry_cipher_algo_info:                 General cipher functions.
+                                                              (line  10)
+* gcry_cipher_algo_name:                 General cipher functions.
+                                                              (line  59)
+* gcry_cipher_authenticate:              Working with cipher handles.
+                                                              (line 119)
+* gcry_cipher_checktag:                  Working with cipher handles.
+                                                              (line 136)
+* gcry_cipher_close:                     Working with cipher handles.
+                                                              (line  62)
+* gcry_cipher_ctl:                       Working with cipher handles.
+                                                              (line 224)
+* gcry_cipher_decrypt:                   Working with cipher handles.
+                                                              (line 177)
+* gcry_cipher_encrypt:                   Working with cipher handles.
+                                                              (line 154)
+* gcry_cipher_final:                     Working with cipher handles.
+                                                              (line 203)
+* gcry_cipher_gettag:                    Working with cipher handles.
+                                                              (line 125)
+* gcry_cipher_get_algo_blklen:           General cipher functions.
+                                                              (line  51)
+* gcry_cipher_get_algo_keylen:           General cipher functions.
+                                                              (line  41)
+* gcry_cipher_info:                      Working with cipher handles.
+                                                              (line 234)
+* gcry_cipher_map_name:                  General cipher functions.
+                                                              (line  66)
+* gcry_cipher_mode_from_oid:             General cipher functions.
+                                                              (line  72)
+* gcry_cipher_open:                      Working with cipher handles.
+                                                              (line   9)
+* gcry_cipher_reset:                     Working with cipher handles.
+                                                              (line 107)
+* gcry_cipher_setctr:                    Working with cipher handles.
+                                                              (line  98)
+* gcry_cipher_setiv:                     Working with cipher handles.
+                                                              (line  86)
+* gcry_cipher_setkey:                    Working with cipher handles.
+                                                              (line  71)
+* gcry_cipher_sync:                      Working with cipher handles.
+                                                              (line 214)
+* gcry_control:                          Controlling the library.
+                                                              (line   6)
+* gcry_create_nonce:                     Retrieving random numbers.
+                                                              (line  27)
+* gcry_ctx_release:                      Context management.  (line  13)
+* gcry_ctx_t:                            Context management.  (line  10)
+* gcry_error:                            Error Values.        (line  63)
+* gcry_error_from_errno:                 Error Values.        (line  85)
+* gcry_error_t:                          Error Values.        (line  24)
+* gcry_err_code:                         Error Values.        (line  42)
+* gcry_err_code_from_errno:              Error Values.        (line  94)
+* gcry_err_code_t:                       Error Values.        (line   6)
+* gcry_err_code_to_errno:                Error Values.        (line  99)
+* gcry_err_make:                         Error Values.        (line  55)
+* gcry_err_make_from_errno:              Error Values.        (line  79)
+* gcry_err_source:                       Error Values.        (line  48)
+* gcry_err_source_t:                     Error Values.        (line  13)
+* gcry_fips_mode_active:                 Controlling the library.
+                                                              (line 247)
+* gcry_free:                             Memory allocation.   (line  33)
+* gcry_handler_alloc_t:                  Allocation handler.  (line  10)
+* gcry_handler_error_t:                  Error handler.       (line  25)
+* gcry_handler_free_t:                   Allocation handler.  (line  19)
+* gcry_handler_log_t:                    Logging handler.     (line   6)
+* gcry_handler_no_mem_t:                 Error handler.       (line  10)
+* gcry_handler_progress_t:               Progress handler.    (line   9)
+* gcry_handler_realloc_t:                Allocation handler.  (line  16)
+* gcry_handler_secure_check_t:           Allocation handler.  (line  13)
+* gcry_kdf_derive:                       Key Derivation.      (line   9)
+* gcry_mac_algo_name:                    Working with MAC algorithms.
+                                                              (line 114)
+* gcry_mac_close:                        Working with MAC algorithms.
+                                                              (line  48)
+* gcry_mac_get_algo:                     Working with MAC algorithms.
+                                                              (line 105)
+* gcry_mac_get_algo_keylen:              Working with MAC algorithms.
+                                                              (line 143)
+* gcry_mac_get_algo_maclen:              Working with MAC algorithms.
+                                                              (line 137)
+* gcry_mac_map_name:                     Working with MAC algorithms.
+                                                              (line 121)
+* gcry_mac_open:                         Working with MAC algorithms.
+                                                              (line   9)
+* gcry_mac_read:                         Working with MAC algorithms.
+                                                              (line  82)
+* gcry_mac_reset:                        Working with MAC algorithms.
+                                                              (line  59)
+* gcry_mac_setiv:                        Working with MAC algorithms.
+                                                              (line  40)
+* gcry_mac_setkey:                       Working with MAC algorithms.
+                                                              (line  29)
+* gcry_mac_test_algo:                    Working with MAC algorithms.
+                                                              (line 130)
+* gcry_mac_verify:                       Working with MAC algorithms.
+                                                              (line  93)
+* gcry_mac_write:                        Working with MAC algorithms.
+                                                              (line  70)
+* gcry_malloc:                           Memory allocation.   (line   6)
+* gcry_malloc_secure:                    Memory allocation.   (line  12)
+* gcry_md_algo_name:                     Working with hash algorithms.
+                                                              (line 225)
+* gcry_md_close:                         Working with hash algorithms.
+                                                              (line  76)
+* gcry_md_copy:                          Working with hash algorithms.
+                                                              (line  99)
+* gcry_md_debug:                         Working with hash algorithms.
+                                                              (line 296)
+* gcry_md_enable:                        Working with hash algorithms.
+                                                              (line  57)
+* gcry_md_extract:                       Working with hash algorithms.
+                                                              (line 165)
+* gcry_md_final:                         Working with hash algorithms.
+                                                              (line 135)
+* gcry_md_get_algo:                      Working with hash algorithms.
+                                                              (line 273)
+* gcry_md_get_algo_dlen:                 Working with hash algorithms.
+                                                              (line 263)
+* gcry_md_get_asnoid:                    Working with hash algorithms.
+                                                              (line 242)
+* gcry_md_hash_buffer:                   Working with hash algorithms.
+                                                              (line 206)
+* gcry_md_hash_buffers:                  Working with hash algorithms.
+                                                              (line 180)
+* gcry_md_is_enabled:                    Working with hash algorithms.
+                                                              (line 286)
+* gcry_md_is_secure:                     Working with hash algorithms.
+                                                              (line 280)
+* gcry_md_map_name:                      Working with hash algorithms.
+                                                              (line 232)
+* gcry_md_open:                          Working with hash algorithms.
+                                                              (line   9)
+* gcry_md_putc:                          Working with hash algorithms.
+                                                              (line 124)
+* gcry_md_read:                          Working with hash algorithms.
+                                                              (line 149)
+* gcry_md_reset:                         Working with hash algorithms.
+                                                              (line  87)
+* gcry_md_setkey:                        Working with hash algorithms.
+                                                              (line  66)
+* gcry_md_test_algo:                     Working with hash algorithms.
+                                                              (line 256)
+* gcry_md_write:                         Working with hash algorithms.
+                                                              (line 113)
+* gcry_mpi_abs:                          Basic functions.     (line  63)
+* gcry_mpi_add:                          Calculations.        (line   8)
+* gcry_mpi_addm:                         Calculations.        (line  18)
+* gcry_mpi_add_ui:                       Calculations.        (line  13)
+* gcry_mpi_aprint:                       MPI formats.         (line  59)
+* gcry_mpi_clear_bit:                    Bit manipulations.   (line  21)
+* gcry_mpi_clear_flag:                   Miscellaneous.       (line  75)
+* gcry_mpi_clear_highbit:                Bit manipulations.   (line  29)
+* gcry_mpi_cmp:                          Comparisons.         (line   8)
+* gcry_mpi_cmp_ui:                       Comparisons.         (line  17)
+* gcry_mpi_copy:                         Basic functions.     (line  24)
+* gcry_mpi_div:                          Calculations.        (line  58)
+* gcry_mpi_dump:                         MPI formats.         (line  74)
+* gcry_mpi_ec_add:                       EC functions.        (line 156)
+* gcry_mpi_ec_curve_point:               EC functions.        (line 175)
+* gcry_mpi_ec_decode_point:              EC functions.        (line 127)
+* gcry_mpi_ec_dup:                       EC functions.        (line 150)
+* gcry_mpi_ec_get_affine:                EC functions.        (line 137)
+* gcry_mpi_ec_get_mpi:                   EC functions.        (line  82)
+* gcry_mpi_ec_get_point:                 EC functions.        (line 100)
+* gcry_mpi_ec_mul:                       EC functions.        (line 169)
+* gcry_mpi_ec_new:                       EC functions.        (line  60)
+* gcry_mpi_ec_set_mpi:                   EC functions.        (line 113)
+* gcry_mpi_ec_set_point:                 EC functions.        (line 120)
+* gcry_mpi_ec_sub:                       EC functions.        (line 162)
+* gcry_mpi_gcd:                          Calculations.        (line  74)
+* gcry_mpi_get_flag:                     Miscellaneous.       (line  83)
+* gcry_mpi_get_nbits:                    Bit manipulations.   (line   9)
+* gcry_mpi_get_opaque:                   Miscellaneous.       (line  31)
+* gcry_mpi_invm:                         Calculations.        (line  80)
+* gcry_mpi_is_neg:                       Comparisons.         (line  23)
+* gcry_mpi_lshift:                       Bit manipulations.   (line  39)
+* gcry_mpi_mod:                          Calculations.        (line  64)
+* gcry_mpi_mul:                          Calculations.        (line  38)
+* gcry_mpi_mulm:                         Calculations.        (line  48)
+* gcry_mpi_mul_2exp:                     Calculations.        (line  53)
+* gcry_mpi_mul_ui:                       Calculations.        (line  43)
+* gcry_mpi_neg:                          Basic functions.     (line  59)
+* gcry_mpi_new:                          Basic functions.     (line   9)
+* gcry_mpi_point_get:                    EC functions.        (line  23)
+* gcry_mpi_point_new:                    EC functions.        (line  10)
+* gcry_mpi_point_release:                EC functions.        (line  18)
+* gcry_mpi_point_set:                    EC functions.        (line  39)
+* gcry_mpi_point_snatch_get:             EC functions.        (line  30)
+* gcry_mpi_point_snatch_set:             EC functions.        (line  48)
+* gcry_mpi_point_t:                      Data types.          (line   9)
+* gcry_mpi_powm:                         Calculations.        (line  69)
+* gcry_mpi_print:                        MPI formats.         (line  49)
+* gcry_mpi_randomize:                    Miscellaneous.       (line  91)
+* gcry_mpi_release:                      Basic functions.     (line  29)
+* gcry_mpi_rshift:                       Bit manipulations.   (line  33)
+* gcry_mpi_scan:                         MPI formats.         (line   9)
+* gcry_mpi_set:                          Basic functions.     (line  37)
+* gcry_mpi_set_bit:                      Bit manipulations.   (line  17)
+* gcry_mpi_set_flag:                     Miscellaneous.       (line  68)
+* gcry_mpi_set_highbit:                  Bit manipulations.   (line  25)
+* gcry_mpi_set_opaque:                   Miscellaneous.       (line   9)
+* gcry_mpi_set_opaque_copy:              Miscellaneous.       (line  25)
+* gcry_mpi_set_ui:                       Basic functions.     (line  42)
+* gcry_mpi_snatch:                       Basic functions.     (line  54)
+* gcry_mpi_snew:                         Basic functions.     (line  17)
+* gcry_mpi_sub:                          Calculations.        (line  23)
+* gcry_mpi_subm:                         Calculations.        (line  33)
+* gcry_mpi_sub_ui:                       Calculations.        (line  28)
+* gcry_mpi_swap:                         Basic functions.     (line  50)
+* gcry_mpi_t:                            Data types.          (line   6)
+* gcry_mpi_test_bit:                     Bit manipulations.   (line  13)
+* gcry_pk_algo_info:                     General public-key related Functions.
+                                                              (line  49)
+* gcry_pk_algo_name:                     General public-key related Functions.
+                                                              (line   9)
+* gcry_pk_ctl:                           General public-key related Functions.
+                                                              (line 100)
+* gcry_pk_decrypt:                       Cryptographic Functions.
+                                                              (line 149)
+* gcry_pk_encrypt:                       Cryptographic Functions.
+                                                              (line  91)
+* gcry_pk_genkey:                        General public-key related Functions.
+                                                              (line 117)
+* gcry_pk_get_keygrip:                   General public-key related Functions.
+                                                              (line  31)
+* gcry_pk_get_nbits:                     General public-key related Functions.
+                                                              (line  26)
+* gcry_pk_map_name:                      General public-key related Functions.
+                                                              (line  16)
+* gcry_pk_sign:                          Cryptographic Functions.
+                                                              (line 189)
+* gcry_pk_testkey:                       General public-key related Functions.
+                                                              (line  43)
+* gcry_pk_test_algo:                     General public-key related Functions.
+                                                              (line  21)
+* gcry_pk_verify:                        Cryptographic Functions.
+                                                              (line 281)
+* gcry_prime_check:                      Checking.            (line   6)
+* gcry_prime_generate:                   Generation.          (line   6)
+* gcry_prime_group_generator:            Generation.          (line  18)
+* gcry_prime_release_factors:            Generation.          (line  26)
+* gcry_pubkey_get_sexp:                  General public-key related Functions.
+                                                              (line 309)
+* gcry_randomize:                        Retrieving random numbers.
+                                                              (line   6)
+* gcry_random_bytes:                     Retrieving random numbers.
+                                                              (line  12)
+* gcry_random_bytes_secure:              Retrieving random numbers.
+                                                              (line  19)
+* gcry_random_level_t:                   Quality of random numbers.
+                                                              (line   8)
+* gcry_realloc:                          Memory allocation.   (line  25)
+* gcry_set_allocation_handler:           Allocation handler.  (line  25)
+* gcry_set_fatalerror_handler:           Error handler.       (line  29)
+* gcry_set_log_handler:                  Logging handler.     (line  10)
+* gcry_set_outofcore_handler:            Error handler.       (line  13)
+* gcry_set_progress_handler:             Progress handler.    (line  19)
+* gcry_sexp_build:                       Working with S-expressions.
+                                                              (line  44)
+* gcry_sexp_canon_len:                   Working with S-expressions.
+                                                              (line 132)
+* gcry_sexp_car:                         Working with S-expressions.
+                                                              (line 165)
+* gcry_sexp_cdr:                         Working with S-expressions.
+                                                              (line 172)
+* gcry_sexp_create:                      Working with S-expressions.
+                                                              (line  24)
+* gcry_sexp_dump:                        Working with S-expressions.
+                                                              (line 123)
+* gcry_sexp_extract_param:               Working with S-expressions.
+                                                              (line 240)
+* gcry_sexp_find_token:                  Working with S-expressions.
+                                                              (line 144)
+* gcry_sexp_length:                      Working with S-expressions.
+                                                              (line 153)
+* gcry_sexp_new:                         Working with S-expressions.
+                                                              (line  11)
+* gcry_sexp_nth:                         Working with S-expressions.
+                                                              (line 158)
+* gcry_sexp_nth_buffer:                  Working with S-expressions.
+                                                              (line 199)
+* gcry_sexp_nth_data:                    Working with S-expressions.
+                                                              (line 180)
+* gcry_sexp_nth_mpi:                     Working with S-expressions.
+                                                              (line 228)
+* gcry_sexp_nth_string:                  Working with S-expressions.
+                                                              (line 220)
+* gcry_sexp_release:                     Working with S-expressions.
+                                                              (line  87)
+* gcry_sexp_sprint:                      Working with S-expressions.
+                                                              (line  98)
+* gcry_sexp_sscan:                       Working with S-expressions.
+                                                              (line  37)
+* gcry_sexp_t:                           Data types for S-expressions.
+                                                              (line   6)
+* gcry_strerror:                         Error Strings.       (line   6)
+* gcry_strsource:                        Error Strings.       (line  12)
+
+
 \1f
 Tag Table:
-(Indirect)
-Node: Top\7f876
-Node: Introduction\7f3310
-Node: Getting Started\7f3682
-Node: Features\7f4563
-Node: Overview\7f5347
-Node: Preparation\7f5978
-Node: Header\7f6901
-Node: Building sources\7f7972
-Node: Building sources using Automake\7f9886
-Node: Initializing the library\7f11068
-Ref: sample-use-suspend-secmem\7f14244
-Ref: sample-use-resume-secmem\7f14865
-Node: Multi-Threading\7f15761
-Ref: Multi-Threading-Footnote-1\7f20389
-Node: Enabling FIPS mode\7f20797
-Node: Hardware features\7f22789
-Ref: Hardware features-Footnote-1\7f24017
-Node: Generalities\7f24178
-Node: Controlling the library\7f24437
-Node: Error Handling\7f41155
-Node: Error Values\7f43694
-Node: Error Sources\7f48634
-Node: Error Codes\7f50905
-Node: Error Strings\7f54390
-Node: Handler Functions\7f55574
-Node: Progress handler\7f56133
-Node: Allocation handler\7f58278
-Node: Error handler\7f59829
-Node: Logging handler\7f61396
-Node: Symmetric cryptography\7f61988
-Node: Available ciphers\7f62728
-Node: Available cipher modes\7f65345
-Node: Working with cipher handles\7f67438
-Node: General cipher functions\7f77416
-Node: Public Key cryptography\7f80934
-Node: Available algorithms\7f81700
-Node: Used S-expressions\7f82049
-Node: RSA key parameters\7f83166
-Node: DSA key parameters\7f84441
-Node: ECC key parameters\7f85099
-Ref: ecc_keyparam\7f85250
-Node: Cryptographic Functions\7f87126
-Node: General public-key related Functions\7f98662
-Node: Hashing\7f112173
-Node: Available hash algorithms\7f112906
-Node: Working with hash algorithms\7f116798
-Node: Message Authentication Codes\7f129412
-Node: Available MAC algorithms\7f130080
-Node: Working with MAC algorithms\7f134003
-Node: Key Derivation\7f139365
-Node: Random Numbers\7f141759
-Node: Quality of random numbers\7f142042
-Node: Retrieving random numbers\7f142728
-Node: S-expressions\7f144214
-Node: Data types for S-expressions\7f144858
-Node: Working with S-expressions\7f145184
-Node: MPI library\7f158584
-Node: Data types\7f159608
-Node: Basic functions\7f159917
-Node: MPI formats\7f162371
-Node: Calculations\7f165756
-Node: Comparisons\7f168010
-Node: Bit manipulations\7f169009
-Node: EC functions\7f170323
-Ref: gcry_mpi_ec_new\7f173021
-Node: Miscellaneous\7f177782
-Node: Prime numbers\7f181925
-Node: Generation\7f182195
-Node: Checking\7f183479
-Node: Utilities\7f183893
-Node: Memory allocation\7f184205
-Node: Context management\7f185559
-Ref: gcry_ctx_release\7f185996
-Node: Buffer description\7f186157
-Node: Tools\7f186919
-Node: hmac256\7f187085
-Node: Architecture\7f188092
-Ref: fig:subsystems\7f189608
-Ref: Architecture-Footnote-1\7f190693
-Ref: Architecture-Footnote-2\7f190755
-Node: Public-Key Subsystem Architecture\7f190839
-Node: Symmetric Encryption Subsystem Architecture\7f193114
-Node: Hashing and MACing Subsystem Architecture\7f194561
-Node: Multi-Precision-Integer Subsystem Architecture\7f196485
-Node: Prime-Number-Generator Subsystem Architecture\7f197926
-Ref: Prime-Number-Generator Subsystem Architecture-Footnote-1\7f199857
-Node: Random-Number Subsystem Architecture\7f200145
-Node: CSPRNG Description\7f202634
-Ref: CSPRNG Description-Footnote-1\7f204196
-Node: FIPS PRNG Description\7f204319
-Node: Self-Tests\7f206452
-Node: FIPS Mode\7f217962
-Ref: fig:fips-fsm\7f221769
-Ref: tbl:fips-states\7f221871
-Ref: tbl:fips-state-transitions\7f223124
-Node: Library Copying\7f226747
-Node: Copying\7f254866
-Node: Figures and Tables\7f274041
-Node: Concept Index\7f274451
-Node: Function and Data Index\7f283506
+Node: Top\7f829
+Node: Introduction\7f3348
+Node: Getting Started\7f3720
+Node: Features\7f4600
+Node: Overview\7f5384
+Node: Preparation\7f6007
+Node: Header\7f6930
+Node: Building sources\7f8001
+Node: Building sources using Automake\7f9918
+Node: Initializing the library\7f11846
+Ref: sample-use-suspend-secmem\7f14914
+Ref: sample-use-resume-secmem\7f15537
+Node: Multi-Threading\7f16440
+Ref: Multi-Threading-Footnote-1\7f17619
+Node: Enabling FIPS mode\7f18028
+Ref: enabling fips mode\7f18209
+Node: Hardware features\7f20021
+Ref: hardware features\7f20188
+Ref: Hardware features-Footnote-1\7f21255
+Node: Generalities\7f21416
+Node: Controlling the library\7f21675
+Node: Error Handling\7f38376
+Node: Error Values\7f40915
+Node: Error Sources\7f45855
+Node: Error Codes\7f48123
+Node: Error Strings\7f51599
+Node: Handler Functions\7f52783
+Node: Progress handler\7f53342
+Node: Allocation handler\7f55491
+Node: Error handler\7f57037
+Node: Logging handler\7f58603
+Node: Symmetric cryptography\7f59195
+Node: Available ciphers\7f59935
+Node: Available cipher modes\7f62616
+Node: Working with cipher handles\7f65619
+Node: General cipher functions\7f77088
+Node: Public Key cryptography\7f80614
+Node: Available algorithms\7f81380
+Node: Used S-expressions\7f81729
+Node: RSA key parameters\7f82846
+Node: DSA key parameters\7f84121
+Node: ECC key parameters\7f84775
+Ref: ecc_keyparam\7f84926
+Node: Cryptographic Functions\7f86797
+Node: General public-key related Functions\7f98616
+Node: Hashing\7f112136
+Node: Available hash algorithms\7f112869
+Node: Working with hash algorithms\7f117656
+Node: Message Authentication Codes\7f131609
+Node: Available MAC algorithms\7f132277
+Node: Working with MAC algorithms\7f137439
+Node: Key Derivation\7f143427
+Node: Random Numbers\7f145829
+Node: Quality of random numbers\7f146112
+Node: Retrieving random numbers\7f146795
+Node: S-expressions\7f148284
+Node: Data types for S-expressions\7f148929
+Node: Working with S-expressions\7f149255
+Node: MPI library\7f162920
+Node: Data types\7f163942
+Node: Basic functions\7f164251
+Node: MPI formats\7f166715
+Node: Calculations\7f170239
+Node: Comparisons\7f172508
+Node: Bit manipulations\7f173511
+Node: EC functions\7f174833
+Ref: gcry_mpi_ec_new\7f177538
+Node: Miscellaneous\7f183097
+Node: Prime numbers\7f187241
+Node: Generation\7f187511
+Node: Checking\7f188798
+Node: Utilities\7f189208
+Node: Memory allocation\7f189520
+Node: Context management\7f190876
+Ref: gcry_ctx_release\7f191314
+Node: Buffer description\7f191475
+Node: Tools\7f192237
+Node: hmac256\7f192404
+Node: Configuration\7f193410
+Node: Architecture\7f195596
+Ref: fig:subsystems\7f197120
+Ref: Architecture-Footnote-1\7f198206
+Ref: Architecture-Footnote-2\7f198268
+Node: Public-Key Subsystem Architecture\7f198352
+Node: Symmetric Encryption Subsystem Architecture\7f200630
+Node: Hashing and MACing Subsystem Architecture\7f202076
+Node: Multi-Precision-Integer Subsystem Architecture\7f203999
+Node: Prime-Number-Generator Subsystem Architecture\7f205437
+Ref: Prime-Number-Generator Subsystem Architecture-Footnote-1\7f207368
+Node: Random-Number Subsystem Architecture\7f207659
+Node: CSPRNG Description\7f210183
+Ref: CSPRNG Description-Footnote-1\7f211739
+Node: FIPS PRNG Description\7f211862
+Node: Self-Tests\7f213996
+Node: FIPS Mode\7f225455
+Ref: fig:fips-fsm\7f229281
+Ref: tbl:fips-states\7f229384
+Ref: tbl:fips-state-transitions\7f230636
+Node: Library Copying\7f234257
+Node: Copying\7f262363
+Node: Figures and Tables\7f281539
+Node: Concept Index\7f281964
+Node: Function and Data Index\7f292561
 \1f
 End Tag Table
diff --git a/doc/gcrypt.info-1 b/doc/gcrypt.info-1
deleted file mode 100644 (file)
index 7008afa..0000000
+++ /dev/null
@@ -1,6685 +0,0 @@
-This is /home/wk/s/libgcrypt/doc/gcrypt.info, produced by makeinfo
-version 4.13 from /home/wk/s/libgcrypt/doc/gcrypt.texi.
-
-This manual is for Libgcrypt (version 1.6.2, 21 August 2014), which is
-GNU's library of cryptographic building blocks.
-
-Copyright (C) 2000, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2011,
-2012 Free Software Foundation, Inc.
-Copyright (C) 2012, 2013 g10 Code GmbH
-
-     Permission is granted to copy, distribute and/or modify this
-     document under the terms of the GNU General Public License as
-     published by the Free Software Foundation; either version 2 of the
-     License, or (at your option) any later version. The text of the
-     license can be found in the section entitled "GNU General Public
-     License".
-
-INFO-DIR-SECTION GNU Libraries
-START-INFO-DIR-ENTRY
-* libgcrypt: (gcrypt).  Cryptographic function library.
-END-INFO-DIR-ENTRY
-
-\1f
-File: gcrypt.info,  Node: Top,  Next: Introduction,  Up: (dir)
-
-The Libgcrypt Library
-*********************
-
-This manual is for Libgcrypt (version 1.6.2, 21 August 2014), which is
-GNU's library of cryptographic building blocks.
-
-Copyright (C) 2000, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2011,
-2012 Free Software Foundation, Inc.
-Copyright (C) 2012, 2013 g10 Code GmbH
-
-     Permission is granted to copy, distribute and/or modify this
-     document under the terms of the GNU General Public License as
-     published by the Free Software Foundation; either version 2 of the
-     License, or (at your option) any later version. The text of the
-     license can be found in the section entitled "GNU General Public
-     License".
-
-* Menu:
-
-* Introduction::                 What is Libgcrypt.
-* Preparation::                  What you should do before using the library.
-* Generalities::                 General library functions and data types.
-* Handler Functions::            Working with handler functions.
-* Symmetric cryptography::       How to use symmetric cryptography.
-* Public Key cryptography::      How to use public key cryptography.
-* Hashing::                      How to use hash algorithms.
-* Message Authentication Codes:: How to use MAC algorithms.
-* Key Derivation::               How to derive keys from strings
-* Random Numbers::               How to work with random numbers.
-* S-expressions::                How to manage S-expressions.
-* MPI library::                  How to work with multi-precision-integers.
-* Prime numbers::                How to use the Prime number related functions.
-* Utilities::                    Utility functions.
-* Tools::                        Utility tools
-* Architecture::                 How Libgcrypt works internally.
-
-Appendices
-
-* Self-Tests::                  Description of the self-tests.
-* FIPS Mode::                   Description of the FIPS mode.
-* Library Copying::             The GNU Lesser General Public License
-                                says how you can copy and share Libgcrypt.
-* Copying::                     The GNU General Public License says how you
-                                can copy and share some parts of Libgcrypt.
-
-Indices
-
-* Figures and Tables::          Index of figures and tables.
-* Concept Index::               Index of concepts and programs.
-* Function and Data Index::     Index of functions, variables and data types.
-
-\1f
-File: gcrypt.info,  Node: Introduction,  Next: Preparation,  Prev: Top,  Up: Top
-
-1 Introduction
-**************
-
-Libgcrypt is a library providing cryptographic building blocks.
-
-* Menu:
-
-* Getting Started::             How to use this manual.
-* Features::                    A glance at Libgcrypt's features.
-* Overview::                    Overview about the library.
-
-\1f
-File: gcrypt.info,  Node: Getting Started,  Next: Features,  Up: Introduction
-
-1.1 Getting Started
-===================
-
-This manual documents the Libgcrypt library application programming
-interface (API).  All functions and data types provided by the library
-are explained.
-
-The reader is assumed to possess basic knowledge about applied
-cryptography.
-
-   This manual can be used in several ways.  If read from the beginning
-to the end, it gives a good introduction into the library and how it
-can be used in an application.  Forward references are included where
-necessary.  Later on, the manual can be used as a reference manual to
-get just the information needed about any particular interface of the
-library.  Experienced programmers might want to start looking at the
-examples at the end of the manual, and then only read up those parts of
-the interface which are unclear.
-
-\1f
-File: gcrypt.info,  Node: Features,  Next: Overview,  Prev: Getting Started,  Up: Introduction
-
-1.2 Features
-============
-
-Libgcrypt might have a couple of advantages over other libraries doing
-a similar job.
-
-It's Free Software
-     Anybody can use, modify, and redistribute it under the terms of
-     the GNU Lesser General Public License (*note Library Copying::).
-     Note, that some parts (which are in general not needed by
-     applications) are subject to the terms of the GNU General Public
-     License (*note Copying::); please see the README file of the
-     distribution for of list of these parts.
-
-It encapsulates the low level cryptography
-     Libgcrypt provides a high level interface to cryptographic
-     building blocks using an extensible and flexible API.
-
-
-\1f
-File: gcrypt.info,  Node: Overview,  Prev: Features,  Up: Introduction
-
-1.3 Overview
-============
-
-The Libgcrypt library is fully thread-safe, where it makes sense to be
-thread-safe.  Not thread-safe are some cryptographic functions that
-modify a certain context stored in handles.  If the user really intents
-to use such functions from different threads on the same handle, he has
-to take care of the serialization of such functions himself.  If not
-described otherwise, every function is thread-safe.
-
-   Libgcrypt depends on the library `libgpg-error', which contains
-common error handling related code for GnuPG components.
-
-\1f
-File: gcrypt.info,  Node: Preparation,  Next: Generalities,  Prev: Introduction,  Up: Top
-
-2 Preparation
-*************
-
-To use Libgcrypt, you have to perform some changes to your sources and
-the build system.  The necessary changes are small and explained in the
-following sections.  At the end of this chapter, it is described how
-the library is initialized, and how the requirements of the library are
-verified.
-
-* Menu:
-
-* Header::                      What header file you need to include.
-* Building sources::            How to build sources using the library.
-* Building sources using Automake::  How to build sources with the help of Automake.
-* Initializing the library::    How to initialize the library.
-* Multi-Threading::             How Libgcrypt can be used in a MT environment.
-* Enabling FIPS mode::          How to enable the FIPS mode.
-* Hardware features::           How to disable hardware features.
-
-\1f
-File: gcrypt.info,  Node: Header,  Next: Building sources,  Up: Preparation
-
-2.1 Header
-==========
-
-All interfaces (data types and functions) of the library are defined in
-the header file `gcrypt.h'.  You must include this in all source files
-using the library, either directly or through some other header file,
-like this:
-
-     #include <gcrypt.h>
-
-   The name space of Libgcrypt is `gcry_*' for function and type names
-and `GCRY*' for other symbols.  In addition the same name prefixes with
-one prepended underscore are reserved for internal use and should never
-be used by an application.  Note that Libgcrypt uses libgpg-error,
-which uses `gpg_*' as name space for function and type names and
-`GPG_*' for other symbols, including all the error codes.
-
-Certain parts of gcrypt.h may be excluded by defining these macros:
-
-`GCRYPT_NO_MPI_MACROS'
-     Do not define the shorthand macros `mpi_*' for `gcry_mpi_*'.
-
-`GCRYPT_NO_DEPRECATED'
-     Do not include definitions for deprecated features.  This is
-     useful to make sure that no deprecated features are used.
-
-\1f
-File: gcrypt.info,  Node: Building sources,  Next: Building sources using Automake,  Prev: Header,  Up: Preparation
-
-2.2 Building sources
-====================
-
-If you want to compile a source file including the `gcrypt.h' header
-file, you must make sure that the compiler can find it in the directory
-hierarchy.  This is accomplished by adding the path to the directory in
-which the header file is located to the compilers include file search
-path (via the `-I' option).
-
-   However, the path to the include file is determined at the time the
-source is configured.  To solve this problem, Libgcrypt ships with a
-small helper program `libgcrypt-config' that knows the path to the
-include file and other configuration options.  The options that need to
-be added to the compiler invocation at compile time are output by the
-`--cflags' option to `libgcrypt-config'.  The following example shows
-how it can be used at the command line:
-
-     gcc -c foo.c `libgcrypt-config --cflags`
-
-   Adding the output of `libgcrypt-config --cflags' to the compilers
-command line will ensure that the compiler can find the Libgcrypt header
-file.
-
-   A similar problem occurs when linking the program with the library.
-Again, the compiler has to find the library files.  For this to work,
-the path to the library files has to be added to the library search path
-(via the `-L' option).  For this, the option `--libs' to
-`libgcrypt-config' can be used.  For convenience, this option also
-outputs all other options that are required to link the program with
-the Libgcrypt libraries (in particular, the `-lgcrypt' option).  The
-example shows how to link `foo.o' with the Libgcrypt library to a
-program `foo'.
-
-     gcc -o foo foo.o `libgcrypt-config --libs`
-
-   Of course you can also combine both examples to a single command by
-specifying both options to `libgcrypt-config':
-
-     gcc -o foo foo.c `libgcrypt-config --cflags --libs`
-
-\1f
-File: gcrypt.info,  Node: Building sources using Automake,  Next: Initializing the library,  Prev: Building sources,  Up: Preparation
-
-2.3 Building sources using Automake
-===================================
-
-It is much easier if you use GNU Automake instead of writing your own
-Makefiles.  If you do that, you do not have to worry about finding and
-invoking the `libgcrypt-config' script at all.  Libgcrypt provides an
-extension to Automake that does all the work for you.
-
- -- Macro: AM_PATH_LIBGCRYPT ([MINIMUM-VERSION], [ACTION-IF-FOUND],
-          [ACTION-IF-NOT-FOUND])
-     Check whether Libgcrypt (at least version MINIMUM-VERSION, if
-     given) exists on the host system.  If it is found, execute
-     ACTION-IF-FOUND, otherwise do ACTION-IF-NOT-FOUND, if given.
-
-     Additionally, the function defines `LIBGCRYPT_CFLAGS' to the flags
-     needed for compilation of the program to find the `gcrypt.h'
-     header file, and `LIBGCRYPT_LIBS' to the linker flags needed to
-     link the program to the Libgcrypt library.
-
-   You can use the defined Autoconf variables like this in your
-`Makefile.am':
-
-     AM_CPPFLAGS = $(LIBGCRYPT_CFLAGS)
-     LDADD = $(LIBGCRYPT_LIBS)
-
-\1f
-File: gcrypt.info,  Node: Initializing the library,  Next: Multi-Threading,  Prev: Building sources using Automake,  Up: Preparation
-
-2.4 Initializing the library
-============================
-
-Before the library can be used, it must initialize itself.  This is
-achieved by invoking the function `gcry_check_version' described below.
-
-   Also, it is often desirable to check that the version of Libgcrypt
-used is indeed one which fits all requirements.  Even with binary
-compatibility, new features may have been introduced, but due to
-problem with the dynamic linker an old version may actually be used.
-So you may want to check that the version is okay right after program
-startup.
-
- -- Function: const char * gcry_check_version (const char *REQ_VERSION)
-     The function `gcry_check_version' initializes some subsystems used
-     by Libgcrypt and must be invoked before any other function in the
-     library, with the exception of the `GCRYCTL_SET_THREAD_CBS' command
-     (called via the `gcry_control' function).  *Note Multi-Threading::.
-
-     Furthermore, this function returns the version number of the
-     library.  It can also verify that the version number is higher
-     than a certain required version number REQ_VERSION, if this value
-     is not a null pointer.
-
-   Libgcrypt uses a concept known as secure memory, which is a region of
-memory set aside for storing sensitive data.  Because such memory is a
-scarce resource, it needs to be setup in advanced to a fixed size.
-Further, most operating systems have special requirements on how that
-secure memory can be used.  For example, it might be required to install
-an application as "setuid(root)" to allow allocating such memory.
-Libgcrypt requires a sequence of initialization steps to make sure that
-this works correctly.  The following examples show the necessary steps.
-
-   If you don't have a need for secure memory, for example if your
-application does not use secret keys or other confidential data or it
-runs in a controlled environment where key material floating around in
-memory is not a problem, you should initialize Libgcrypt this way:
-
-       /* Version check should be the very first call because it
-          makes sure that important subsystems are intialized. */
-       if (!gcry_check_version (GCRYPT_VERSION))
-         {
-           fputs ("libgcrypt version mismatch\n", stderr);
-           exit (2);
-         }
-
-       /* Disable secure memory.  */
-       gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
-
-       /* ... If required, other initialization goes here.  */
-
-       /* Tell Libgcrypt that initialization has completed. */
-       gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
-
-   If you have to protect your keys or other information in memory
-against being swapped out to disk and to enable an automatic overwrite
-of used and freed memory, you need to initialize Libgcrypt this way:
-
-       /* Version check should be the very first call because it
-          makes sure that important subsystems are initialized. */
-       if (!gcry_check_version (GCRYPT_VERSION))
-         {
-           fputs ("libgcrypt version mismatch\n", stderr);
-           exit (2);
-         }
-
-     /* We don't want to see any warnings, e.g. because we have not yet
-          parsed program options which might be used to suppress such
-          warnings. */
-       gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
-
-       /* ... If required, other initialization goes here.  Note that the
-          process might still be running with increased privileges and that
-          the secure memory has not been initialized.  */
-
-       /* Allocate a pool of 16k secure memory.  This make the secure memory
-          available and also drops privileges where needed.  */
-       gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
-
-     /* It is now okay to let Libgcrypt complain when there was/is
-          a problem with the secure memory. */
-       gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
-
-       /* ... If required, other initialization goes here.  */
-
-       /* Tell Libgcrypt that initialization has completed. */
-       gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
-
-   It is important that these initialization steps are not done by a
-library but by the actual application.  A library using Libgcrypt might
-want to check for finished initialization using:
-
-       if (!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P))
-         {
-           fputs ("libgcrypt has not been initialized\n", stderr);
-           abort ();
-         }
-
-   Instead of terminating the process, the library may instead print a
-warning and try to initialize Libgcrypt itself.  See also the section on
-multi-threading below for more pitfalls.
-
-\1f
-File: gcrypt.info,  Node: Multi-Threading,  Next: Enabling FIPS mode,  Prev: Initializing the library,  Up: Preparation
-
-2.5 Multi-Threading
-===================
-
-As mentioned earlier, the Libgcrypt library is thread-safe if you
-adhere to the following requirements:
-
-   * If your application is multi-threaded, you must set the thread
-     support callbacks with the `GCRYCTL_SET_THREAD_CBS' command
-     *before* any other function in the library.
-
-     This is easy enough if you are indeed writing an application using
-     Libgcrypt.  It is rather problematic if you are writing a library
-     instead.  Here are some tips what to do if you are writing a
-     library:
-
-     If your library requires a certain thread package, just initialize
-     Libgcrypt to use this thread package.  If your library supports
-     multiple thread packages, but needs to be configured, you will
-     have to implement a way to determine which thread package the
-     application wants to use with your library anyway.  Then configure
-     Libgcrypt to use this thread package.
-
-     If your library is fully reentrant without any special support by a
-     thread package, then you are lucky indeed.  Unfortunately, this
-     does not relieve you from doing either of the two above, or use a
-     third option.  The third option is to let the application
-     initialize Libgcrypt for you.  Then you are not using Libgcrypt
-     transparently, though.
-
-     As if this was not difficult enough, a conflict may arise if two
-     libraries try to initialize Libgcrypt independently of each
-     others, and both such libraries are then linked into the same
-     application.  To make it a bit simpler for you, this will probably
-     work, but only if both libraries have the same requirement for the
-     thread package.  This is currently only supported for the
-     non-threaded case, GNU Pth and pthread.
-
-     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.
-
-     Note that future versions of Libgcrypt will drop this flexible
-     thread support and instead only support the platforms standard
-     thread implementation.
-
-   * The function `gcry_check_version' must be called before any other
-     function in the library, except the `GCRYCTL_SET_THREAD_CBS'
-     command (called via the `gcry_control' function), because it
-     initializes the thread support subsystem in Libgcrypt.  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.
-
-
-   Libgcrypt contains convenient macros, which define the necessary
-thread callbacks for PThread and for GNU Pth:
-
-`GCRY_THREAD_OPTION_PTH_IMPL'
-     This macro defines the following (static) symbols:
-     `gcry_pth_init', `gcry_pth_mutex_init', `gcry_pth_mutex_destroy',
-     `gcry_pth_mutex_lock', `gcry_pth_mutex_unlock', `gcry_pth_read',
-     `gcry_pth_write', `gcry_pth_select', `gcry_pth_waitpid',
-     `gcry_pth_accept', `gcry_pth_connect', `gcry_threads_pth'.
-
-     After including this macro, `gcry_control()' shall be used with a
-     command of `GCRYCTL_SET_THREAD_CBS' in order to register the
-     thread callback structure named "gcry_threads_pth".  Example:
-
-            ret = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth);
-
-`GCRY_THREAD_OPTION_PTHREAD_IMPL'
-     This macro defines the following (static) symbols:
-     `gcry_pthread_mutex_init', `gcry_pthread_mutex_destroy',
-     `gcry_pthread_mutex_lock', `gcry_pthread_mutex_unlock',
-     `gcry_threads_pthread'.
-
-     After including this macro, `gcry_control()' shall be used with a
-     command of `GCRYCTL_SET_THREAD_CBS' in order to register the
-     thread callback structure named "gcry_threads_pthread".  Example:
-
-            ret = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
-
-
-   Note that these macros need to be terminated with a semicolon.  Keep
-in mind that these are convenient macros for C programmers; C++
-programmers might have to wrap these macros in an "extern C" body.
-
-   ---------- Footnotes ----------
-
-   (1) At least this is true for POSIX threads, as `pthread_create' is
-a function that synchronizes memory with respects to other threads.
-There are many functions which have this property, a complete list can
-be found in POSIX, IEEE Std 1003.1-2003, Base Definitions, Issue 6, in
-the definition of the term "Memory Synchronization".  For other thread
-packages, more relaxed or more strict rules may apply.
-
-\1f
-File: gcrypt.info,  Node: Enabling FIPS mode,  Next: Hardware features,  Prev: Multi-Threading,  Up: Preparation
-
-2.6 How to enable the FIPS mode
-===============================
-
-Libgcrypt may be used in a FIPS 140-2 mode.  Note, that this does not
-necessary mean that Libcgrypt is an appoved FIPS 140-2 module.  Check
-the NIST database at `http://csrc.nist.gov/groups/STM/cmvp/' to see what
-versions of Libgcrypt are approved.
-
-   Because FIPS 140 has certain restrictions on the use of cryptography
-which are not always wanted, Libgcrypt needs to be put into FIPS mode
-explicitly.  Three alternative mechanisms are provided to switch
-Libgcrypt into this mode:
-
-   * If the file `/proc/sys/crypto/fips_enabled' exists and contains a
-     numeric value other than `0', Libgcrypt is put into FIPS mode at
-     initialization time.  Obviously this works only on systems with a
-     `proc' file system (i.e. GNU/Linux).
-
-   * If the file `/etc/gcrypt/fips_enabled' exists, Libgcrypt is put
-     into FIPS mode at initialization time.  Note that this filename is
-     hardwired and does not depend on any configuration options.
-
-   * If the application requests FIPS mode using the control command
-     `GCRYCTL_FORCE_FIPS_MODE'.  This must be done prior to any
-     initialization (i.e. before `gcry_check_version').
-
-
-   In addition to the standard FIPS mode, Libgcrypt may also be put into
-an Enforced FIPS mode by writing a non-zero value into the file
-`/etc/gcrypt/fips_enabled' or by using the control command
-`GCRYCTL_SET_ENFORCED_FIPS_FLAG' before any other calls to libgcrypt.
-The Enforced FIPS mode helps to detect applications which don't fulfill
-all requirements for using Libgcrypt in FIPS mode (*note FIPS Mode::).
-
-   Once Libgcrypt has been put into FIPS mode, it is not possible to
-switch back to standard mode without terminating the process first.  If
-the logging verbosity level of Libgcrypt has been set to at least 2,
-the state transitions and the self-tests are logged.
-
-\1f
-File: gcrypt.info,  Node: Hardware features,  Prev: Enabling FIPS mode,  Up: Preparation
-
-2.7 How to disable hardware features
-====================================
-
-Libgcrypt makes use of certain hardware features.  If the use of a
-feature is not desired it may be either be disabled by a program or
-globally using a configuration file.  The currently supported features
-are
-
-`padlock-rng'
-
-`padlock-aes'
-
-`padlock-sha'
-
-`padlock-mmul'
-
-`intel-cpu'
-
-`intel-bmi2'
-
-`intel-ssse3'
-
-`intel-pclmul'
-
-`intel-aesni'
-
-`intel-rdrand'
-
-`intel-avx'
-
-`intel-avx2'
-
-`arm-neon'
-
-   To disable a feature for all processes using Libgcrypt 1.6 or newer,
-create the file `/etc/gcrypt/hwf.deny' and put each feature not to be
-used on a single line.  Empty lines, white space, and lines prefixed
-with a hash mark are ignored.  The file should be world readable.
-
-   To disable a feature specifically for a program that program must
-tell it Libgcrypt before before calling `gcry_check_version'.
-Example:(1)
-
-       gcry_control (GCRYCTL_DISABLE_HWF, "intel-rdrand", NULL);
-
-To print the list of active features you may use this command:
-
-       mpicalc --print-config | grep ^hwflist: | tr : '\n' | tail -n +2
-
-   ---------- Footnotes ----------
-
-   (1) NB. Libgcrypt uses the RDRAND feature only as one source of
-entropy.  A CPU with a broken RDRAND will thus not compromise of the
-random number generator
-
-\1f
-File: gcrypt.info,  Node: Generalities,  Next: Handler Functions,  Prev: Preparation,  Up: Top
-
-3 Generalities
-**************
-
-* Menu:
-
-* Controlling the library::     Controlling Libgcrypt's behavior.
-* Error Handling::              Error codes and such.
-
-\1f
-File: gcrypt.info,  Node: Controlling the library,  Next: Error Handling,  Up: Generalities
-
-3.1 Controlling the library
-===========================
-
- -- Function: gcry_error_t gcry_control (enum gcry_ctl_cmds CMD, ...)
-     This function can be used to influence the general behavior of
-     Libgcrypt in several ways.  Depending on CMD, more arguments can
-     or have to be provided.
-
-    `GCRYCTL_ENABLE_M_GUARD; Arguments: none'
-          This command enables the built-in memory guard.  It must not
-          be used to activate the memory guard after the memory
-          management has already been used; therefore it can ONLY be
-          used before `gcry_check_version'.  Note that the memory guard
-          is NOT used when the user of the library has set his own
-          memory management callbacks.
-
-    `GCRYCTL_ENABLE_QUICK_RANDOM; Arguments: none'
-          This command inhibits the use the very secure random quality
-          level (`GCRY_VERY_STRONG_RANDOM') and degrades all request
-          down to `GCRY_STRONG_RANDOM'.  In general this is not
-          recommended.  However, for some applications the extra
-          quality random Libgcrypt tries to create is not justified and
-          this option may help to get better performance.  Please check
-          with a crypto expert whether this option can be used for your
-          application.
-
-          This option can only be used at initialization time.
-
-    `GCRYCTL_DUMP_RANDOM_STATS; Arguments: none'
-          This command dumps random number generator related statistics
-          to the library's logging stream.
-
-    `GCRYCTL_DUMP_MEMORY_STATS; Arguments: none'
-          This command dumps memory management related statistics to
-          the library's logging stream.
-
-    `GCRYCTL_DUMP_SECMEM_STATS; Arguments: none'
-          This command dumps secure memory management related
-          statistics to the library's logging stream.
-
-    `GCRYCTL_DROP_PRIVS; Arguments: none'
-          This command disables the use of secure memory and drops the
-          privileges of the current process.  This command has not much
-          use; the suggested way to disable secure memory is to use
-          `GCRYCTL_DISABLE_SECMEM' right after initialization.
-
-    `GCRYCTL_DISABLE_SECMEM; Arguments: none'
-          This command disables the use of secure memory.  If this
-          command is used in FIPS mode, FIPS mode will be disabled and
-          the function `gcry_fips_mode_active' returns false.  However,
-          in Enforced FIPS mode this command has no effect at all.
-
-          Many applications do not require secure memory, so they
-          should disable it right away.  This command should be
-          executed right after `gcry_check_version'.
-
-    `GCRYCTL_DISABLE_LOCKED_SECMEM; Arguments: none'
-          This command disables the use of the mlock call for secure
-          memory.  Disabling the use of mlock may for example be done
-          if an encrypted swap space is in use.  This command should be
-          executed right after `gcry_check_version'.
-
-    `GCRYCTL_DISABLE_PRIV_DROP; Arguments: none'
-          This command sets a global flag to tell the secure memory
-          subsystem that it shall not drop privileges after secure
-          memory has been allocated.  This command is commonly used
-          right after `gcry_check_version' but may also be used right
-          away at program startup.  It won't have an effect after the
-          secure memory pool has been initialized.  WARNING: A process
-          running setuid(root) is a severe security risk.  Processes
-          making use of Libgcrypt or other complex code should drop
-          these extra privileges as soon as possible.  If this command
-          has been used the caller is responsible for dropping the
-          privileges.
-
-    `GCRYCTL_INIT_SECMEM; Arguments: int nbytes'
-          This command is used to allocate a pool of secure memory and
-          thus enabling the use of secure memory.  It also drops all
-          extra privileges the process has (i.e. if it is run as setuid
-          (root)).  If the argument NBYTES is 0, secure memory will be
-          disabled.  The minimum amount of secure memory allocated is
-          currently 16384 bytes; you may thus use a value of 1 to
-          request that default size.
-
-    `GCRYCTL_TERM_SECMEM; Arguments: none'
-          This command zeroises the secure memory and destroys the
-          handler.  The secure memory pool may not be used anymore
-          after running this command.  If the secure memory pool as
-          already been destroyed, this command has no effect.
-          Applications might want to run this command from their exit
-          handler to make sure that the secure memory gets properly
-          destroyed.  This command is not necessarily thread-safe but
-          that should not be needed in cleanup code.  It may be called
-          from a signal handler.
-
-    `GCRYCTL_DISABLE_SECMEM_WARN; Arguments: none'
-          Disable warning messages about problems with the secure memory
-          subsystem. This command should be run right after
-          `gcry_check_version'.
-
-    `GCRYCTL_SUSPEND_SECMEM_WARN; Arguments: none'
-          Postpone warning messages from the secure memory subsystem.
-          *Note the initialization example: sample-use-suspend-secmem,
-          on how to use it.
-
-    `GCRYCTL_RESUME_SECMEM_WARN; Arguments: none'
-          Resume warning messages from the secure memory subsystem.
-          *Note the initialization example: sample-use-resume-secmem,
-          on how to use it.
-
-    `GCRYCTL_USE_SECURE_RNDPOOL; Arguments: none'
-          This command tells the PRNG to store random numbers in secure
-          memory.  This command should be run right after
-          `gcry_check_version' and not later than the command
-          GCRYCTL_INIT_SECMEM.  Note that in FIPS mode the secure
-          memory is always used.
-
-    `GCRYCTL_SET_RANDOM_SEED_FILE; Arguments: const char *filename'
-          This command specifies the file, which is to be used as seed
-          file for the PRNG.  If the seed file is registered prior to
-          initialization of the PRNG, the seed file's content (if it
-          exists and seems to be valid) is fed into the PRNG pool.
-          After the seed file has been registered, the PRNG can be
-          signalled to write out the PRNG pool's content into the seed
-          file with the following command.
-
-    `GCRYCTL_UPDATE_RANDOM_SEED_FILE; Arguments: none'
-          Write out the PRNG pool's content into the registered seed
-          file.
-
-          Multiple instances of the applications sharing the same
-          random seed file can be started in parallel, in which case
-          they will read out the same pool and then race for updating
-          it (the last update overwrites earlier updates).  They will
-          differentiate only by the weak entropy that is added in
-          read_seed_file based on the PID and clock, and up to 16 bytes
-          of weak random non-blockingly.  The consequence is that the
-          output of these different instances is correlated to some
-          extent.  In a perfect attack scenario, the attacker can
-          control (or at least guess) the PID and clock of the
-          application, and drain the system's entropy pool to reduce
-          the "up to 16 bytes" above to 0.  Then the dependencies of the
-          initial states of the pools are completely known.  Note that
-          this is not an issue if random of `GCRY_VERY_STRONG_RANDOM'
-          quality is requested as in this case enough extra entropy
-          gets mixed.  It is also not an issue when using Linux
-          (rndlinux driver), because this one guarantees to read full
-          16 bytes from /dev/urandom and thus there is no way for an
-          attacker without kernel access to control these 16 bytes.
-
-    `GCRYCTL_CLOSE_RANDOM_DEVICE; Arguments: none'
-          Try to close the random device.  If on Unix system you call
-          fork(), the child process does no call exec(), and you do not
-          intend to use Libgcrypt in the child, it might be useful to
-          use this control code to close the inherited file descriptors
-          of the random device.  If Libgcrypt is later used again by
-          the child, the device will be re-opened.  On non-Unix systems
-          this control code is ignored.
-
-    `GCRYCTL_SET_VERBOSITY; Arguments: int level'
-          This command sets the verbosity of the logging.  A level of 0
-          disables all extra logging whereas positive numbers enable
-          more verbose logging.  The level may be changed at any time
-          but be aware that no memory synchronization is done so the
-          effect of this command might not immediately show up in other
-          threads.  This command may even be used prior to
-          `gcry_check_version'.
-
-    `GCRYCTL_SET_DEBUG_FLAGS; Arguments: unsigned int flags'
-          Set the debug flag bits as given by the argument.  Be aware
-          that that no memory synchronization is done so the effect of
-          this command might not immediately show up in other threads.
-          The debug flags are not considered part of the API and thus
-          may change without notice.  As of now bit 0 enables debugging
-          of cipher functions and bit 1 debugging of
-          multi-precision-integers.  This command may even be used
-          prior to `gcry_check_version'.
-
-    `GCRYCTL_CLEAR_DEBUG_FLAGS; Arguments: unsigned int flags'
-          Set the debug flag bits as given by the argument.  Be aware
-          that that no memory synchronization is done so the effect of
-          this command might not immediately show up in other threads.
-          This command may even be used prior to `gcry_check_version'.
-
-    `GCRYCTL_DISABLE_INTERNAL_LOCKING; Arguments: none'
-          This command does nothing.  It exists only for backward
-          compatibility.
-
-    `GCRYCTL_ANY_INITIALIZATION_P; Arguments: none'
-          This command returns true if the library has been basically
-          initialized.  Such a basic initialization happens implicitly
-          with many commands to get certain internal subsystems
-          running.  The common and suggested way to do this basic
-          initialization is by calling gcry_check_version.
-
-    `GCRYCTL_INITIALIZATION_FINISHED; Arguments: none'
-          This command tells the library that the application has
-          finished the initialization.
-
-    `GCRYCTL_INITIALIZATION_FINISHED_P; Arguments: none'
-          This command returns true if the command
-          GCRYCTL_INITIALIZATION_FINISHED has already been run.
-
-    `GCRYCTL_SET_THREAD_CBS; Arguments: struct ath_ops *ath_ops'
-          This command registers a thread-callback structure.  *Note
-          Multi-Threading::.
-
-    `GCRYCTL_FAST_POLL; Arguments: none'
-          Run a fast random poll.
-
-    `GCRYCTL_SET_RNDEGD_SOCKET; Arguments: const char *filename'
-          This command may be used to override the default name of the
-          EGD socket to connect to.  It may be used only during
-          initialization as it is not thread safe.  Changing the socket
-          name again is not supported.  The function may return an
-          error if the given filename is too long for a local socket
-          name.
-
-          EGD is an alternative random gatherer, used only on systems
-          lacking a proper random device.
-
-    `GCRYCTL_PRINT_CONFIG; Arguments: FILE *stream'
-          This command dumps information pertaining to the
-          configuration of the library to the given stream.  If NULL is
-          given for STREAM, the log system is used.  This command may
-          be used before the initialization has been finished but not
-          before a `gcry_check_version'.
-
-    `GCRYCTL_OPERATIONAL_P; Arguments: none'
-          This command returns true if the library is in an operational
-          state.  This information makes only sense in FIPS mode.  In
-          contrast to other functions, this is a pure test function and
-          won't put the library into FIPS mode or change the internal
-          state.  This command may be used before the initialization
-          has been finished but not before a `gcry_check_version'.
-
-    `GCRYCTL_FIPS_MODE_P; Arguments: none'
-          This command returns true if the library is in FIPS mode.
-          Note, that this is no indication about the current state of
-          the library.  This command may be used before the
-          initialization has been finished but not before a
-          `gcry_check_version'.  An application may use this command or
-          the convenience macro below to check whether FIPS mode is
-          actually active.
-
-           -- Function: int gcry_fips_mode_active (void)
-               Returns true if the FIPS mode is active.  Note that this
-               is implemented as a macro.
-
-    `GCRYCTL_FORCE_FIPS_MODE; Arguments: none'
-          Running this command puts the library into FIPS mode.  If the
-          library is already in FIPS mode, a self-test is triggered and
-          thus the library will be put into operational state.  This
-          command may be used before a call to `gcry_check_version' and
-          that is actually the recommended way to let an application
-          switch the library into FIPS mode.  Note that Libgcrypt will
-          reject an attempt to switch to fips mode during or after the
-          initialization.
-
-    `GCRYCTL_SET_ENFORCED_FIPS_FLAG; Arguments: none'
-          Running this command sets the internal flag that puts the
-          library into the enforced FIPS mode during the FIPS mode
-          initialization.  This command does not affect the library if
-          the library is not put into the FIPS mode and it must be used
-          before any other libgcrypt library calls that initialize the
-          library such as `gcry_check_version'. Note that Libgcrypt will
-          reject an attempt to switch to the enforced fips mode during
-          or after the initialization.
-
-    `GCRYCTL_SET_PREFERRED_RNG_TYPE; Arguments: int'
-          These are advisory commands to select a certain random number
-          generator.  They are only advisory because libraries may not
-          know what an application actually wants or vice versa.  Thus
-          Libgcrypt employs a priority check to select the actually
-          used RNG.  If an applications selects a lower priority RNG
-          but a library requests a higher priority RNG Libgcrypt will
-          switch to the higher priority RNG.  Applications and
-          libraries should use these control codes before
-          `gcry_check_version'.  The available generators are:
-         `GCRY_RNG_TYPE_STANDARD'
-               A conservative standard generator based on the
-               "Continuously Seeded Pseudo Random Number Generator"
-               designed by Peter Gutmann.
-
-         `GCRY_RNG_TYPE_FIPS'
-               A deterministic random number generator conforming to he
-               document "NIST-Recommended Random Number Generator Based
-               on ANSI X9.31 Appendix A.2.4 Using the 3-Key Triple DES
-               and AES Algorithms" (2005-01-31).  This implementation
-               uses the AES variant.
-
-         `GCRY_RNG_TYPE_SYSTEM'
-               A wrapper around the system's native RNG.  On Unix
-               system these are usually the /dev/random and
-               /dev/urandom devices.
-          The default is `GCRY_RNG_TYPE_STANDARD' unless FIPS mode as
-          been enabled; in which case `GCRY_RNG_TYPE_FIPS' is used and
-          locked against further changes.
-
-    `GCRYCTL_GETT_CURRENT_RNG_TYPE; Arguments: int *'
-          This command stores the type of the currently used RNG as an
-          integer value at the provided address.
-
-    `GCRYCTL_SELFTEST; Arguments: none'
-          This may be used at anytime to have the library run all
-          implemented self-tests.  It works in standard and in FIPS
-          mode.  Returns 0 on success or an error code on failure.
-
-    `GCRYCTL_DISABLE_HWF; Arguments: const char *name'
-          Libgcrypt detects certain features of the CPU at startup
-          time.  For performance tests it is sometimes required not to
-          use such a feature.  This option may be used to disable a
-          certain feature; i.e. Libgcrypt behaves as if this feature
-          has not been detected.  Note that the detection code might be
-          run if the feature has been disabled.  This command must be
-          used at initialization time; i.e. before calling
-          `gcry_check_version'.
-
-
-
-\1f
-File: gcrypt.info,  Node: Error Handling,  Prev: Controlling the library,  Up: Generalities
-
-3.2 Error Handling
-==================
-
-Many functions in Libgcrypt can return an error if they fail.  For this
-reason, the application should always catch the error condition and
-take appropriate measures, for example by releasing the resources and
-passing the error up to the caller, or by displaying a descriptive
-message to the user and cancelling the operation.
-
-   Some error values do not indicate a system error or an error in the
-operation, but the result of an operation that failed properly.  For
-example, if you try to decrypt a tempered message, the decryption will
-fail.  Another error value actually means that the end of a data buffer
-or list has been reached.  The following descriptions explain for many
-error codes what they mean usually.  Some error values have specific
-meanings if returned by a certain functions.  Such cases are described
-in the documentation of those functions.
-
-   Libgcrypt uses the `libgpg-error' library.  This allows to share the
-error codes with other components of the GnuPG system, and to pass
-error values transparently from the crypto engine, or some helper
-application of the crypto engine, to the user.  This way no information
-is lost.  As a consequence, Libgcrypt does not use its own identifiers
-for error codes, but uses those provided by `libgpg-error'.  They
-usually start with `GPG_ERR_'.
-
-   However, Libgcrypt does provide aliases for the functions defined in
-libgpg-error, which might be preferred for name space consistency.
-
-   Most functions in Libgcrypt return an error code in the case of
-failure.  For this reason, the application should always catch the
-error condition and take appropriate measures, for example by releasing
-the resources and passing the error up to the caller, or by displaying
-a descriptive message to the user and canceling the operation.
-
-   Some error values do not indicate a system error or an error in the
-operation, but the result of an operation that failed properly.
-
-   GnuPG components, including Libgcrypt, use an extra library named
-libgpg-error to provide a common error handling scheme.  For more
-information on libgpg-error, see the according manual.
-
-* Menu:
-
-* Error Values::                The error value and what it means.
-* Error Sources::               A list of important error sources.
-* Error Codes::                 A list of important error codes.
-* Error Strings::               How to get a descriptive string from a value.
-
-\1f
-File: gcrypt.info,  Node: Error Values,  Next: Error Sources,  Up: Error Handling
-
-3.2.1 Error Values
-------------------
-
- -- Data type: gcry_err_code_t
-     The `gcry_err_code_t' type is an alias for the `libgpg-error' type
-     `gpg_err_code_t'.  The error code indicates the type of an error,
-     or the reason why an operation failed.
-
-     A list of important error codes can be found in the next section.
-
- -- Data type: gcry_err_source_t
-     The `gcry_err_source_t' type is an alias for the `libgpg-error'
-     type `gpg_err_source_t'.  The error source has not a precisely
-     defined meaning.  Sometimes it is the place where the error
-     happened, sometimes it is the place where an error was encoded
-     into an error value.  Usually the error source will give an
-     indication to where to look for the problem.  This is not always
-     true, but it is attempted to achieve this goal.
-
-     A list of important error sources can be found in the next section.
-
- -- Data type: gcry_error_t
-     The `gcry_error_t' type is an alias for the `libgpg-error' type
-     `gpg_error_t'.  An error value like this has always two
-     components, an error code and an error source.  Both together form
-     the error value.
-
-     Thus, the error value can not be directly compared against an error
-     code, but the accessor functions described below must be used.
-     However, it is guaranteed that only 0 is used to indicate success
-     (`GPG_ERR_NO_ERROR'), and that in this case all other parts of the
-     error value are set to 0, too.
-
-     Note that in Libgcrypt, the error source is used purely for
-     diagnostic purposes.  Only the error code should be checked to test
-     for a certain outcome of a function.  The manual only documents the
-     error code part of an error value.  The error source is left
-     unspecified and might be anything.
-
- -- Function: gcry_err_code_t gcry_err_code (gcry_error_t ERR)
-     The static inline function `gcry_err_code' returns the
-     `gcry_err_code_t' component of the error value ERR.  This function
-     must be used to extract the error code from an error value in
-     order to compare it with the `GPG_ERR_*' error code macros.
-
- -- Function: gcry_err_source_t gcry_err_source (gcry_error_t ERR)
-     The static inline function `gcry_err_source' returns the
-     `gcry_err_source_t' component of the error value ERR.  This
-     function must be used to extract the error source from an error
-     value in order to compare it with the `GPG_ERR_SOURCE_*' error
-     source macros.
-
- -- Function: gcry_error_t gcry_err_make (gcry_err_source_t SOURCE,
-          gcry_err_code_t CODE)
-     The static inline function `gcry_err_make' returns the error value
-     consisting of the error source SOURCE and the error code CODE.
-
-     This function can be used in callback functions to construct an
-     error value to return it to the library.
-
- -- Function: gcry_error_t gcry_error (gcry_err_code_t CODE)
-     The static inline function `gcry_error' returns the error value
-     consisting of the default error source and the error code CODE.
-
-     For GCRY applications, the default error source is
-     `GPG_ERR_SOURCE_USER_1'.  You can define `GCRY_ERR_SOURCE_DEFAULT'
-     before including `gcrypt.h' to change this default.
-
-     This function can be used in callback functions to construct an
-     error value to return it to the library.
-
-   The `libgpg-error' library provides error codes for all system error
-numbers it knows about.  If ERR is an unknown error number, the error
-code `GPG_ERR_UNKNOWN_ERRNO' is used.  The following functions can be
-used to construct error values from system errno numbers.
-
- -- Function: gcry_error_t gcry_err_make_from_errno
-          (gcry_err_source_t SOURCE, int ERR)
-     The function `gcry_err_make_from_errno' is like `gcry_err_make',
-     but it takes a system error like `errno' instead of a
-     `gcry_err_code_t' error code.
-
- -- Function: gcry_error_t gcry_error_from_errno (int ERR)
-     The function `gcry_error_from_errno' is like `gcry_error', but it
-     takes a system error like `errno' instead of a `gcry_err_code_t'
-     error code.
-
-   Sometimes you might want to map system error numbers to error codes
-directly, or map an error code representing a system error back to the
-system error number.  The following functions can be used to do that.
-
- -- Function: gcry_err_code_t gcry_err_code_from_errno (int ERR)
-     The function `gcry_err_code_from_errno' returns the error code for
-     the system error ERR.  If ERR is not a known system error, the
-     function returns `GPG_ERR_UNKNOWN_ERRNO'.
-
- -- Function: int gcry_err_code_to_errno (gcry_err_code_t ERR)
-     The function `gcry_err_code_to_errno' returns the system error for
-     the error code ERR.  If ERR is not an error code representing a
-     system error, or if this system error is not defined on this
-     system, the function returns `0'.
-
-\1f
-File: gcrypt.info,  Node: Error Sources,  Next: Error Codes,  Prev: Error Values,  Up: Error Handling
-
-3.2.2 Error Sources
--------------------
-
-The library `libgpg-error' defines an error source for every component
-of the GnuPG system.  The error source part of an error value is not
-well defined.  As such it is mainly useful to improve the diagnostic
-error message for the user.
-
-   If the error code part of an error value is `0', the whole error
-value will be `0'.  In this case the error source part is of course
-`GPG_ERR_SOURCE_UNKNOWN'.
-
-   The list of error sources that might occur in applications using
-Libgcrypt is:
-
-`GPG_ERR_SOURCE_UNKNOWN'
-     The error source is not known.  The value of this error source is
-     `0'.
-
-`GPG_ERR_SOURCE_GPGME'
-     The error source is GPGME itself.
-
-`GPG_ERR_SOURCE_GPG'
-     The error source is GnuPG, which is the crypto engine used for the
-     OpenPGP protocol.
-
-`GPG_ERR_SOURCE_GPGSM'
-     The error source is GPGSM, which is the crypto engine used for the
-     OpenPGP protocol.
-
-`GPG_ERR_SOURCE_GCRYPT'
-     The error source is `libgcrypt', which is used by crypto engines
-     to perform cryptographic operations.
-
-`GPG_ERR_SOURCE_GPGAGENT'
-     The error source is `gpg-agent', which is used by crypto engines
-     to perform operations with the secret key.
-
-`GPG_ERR_SOURCE_PINENTRY'
-     The error source is `pinentry', which is used by `gpg-agent' to
-     query the passphrase to unlock a secret key.
-
-`GPG_ERR_SOURCE_SCD'
-     The error source is the SmartCard Daemon, which is used by
-     `gpg-agent' to delegate operations with the secret key to a
-     SmartCard.
-
-`GPG_ERR_SOURCE_KEYBOX'
-     The error source is `libkbx', a library used by the crypto engines
-     to manage local keyrings.
-
-`GPG_ERR_SOURCE_USER_1'
-
-`GPG_ERR_SOURCE_USER_2'
-
-`GPG_ERR_SOURCE_USER_3'
-
-`GPG_ERR_SOURCE_USER_4'
-     These error sources are not used by any GnuPG component and can be
-     used by other software.  For example, applications using Libgcrypt
-     can use them to mark error values coming from callback handlers.
-     Thus `GPG_ERR_SOURCE_USER_1' is the default for errors created
-     with `gcry_error' and `gcry_error_from_errno', unless you define
-     `GCRY_ERR_SOURCE_DEFAULT' before including `gcrypt.h'.
-
-\1f
-File: gcrypt.info,  Node: Error Codes,  Next: Error Strings,  Prev: Error Sources,  Up: Error Handling
-
-3.2.3 Error Codes
------------------
-
-The library `libgpg-error' defines many error values.  The following
-list includes the most important error codes.
-
-`GPG_ERR_EOF'
-     This value indicates the end of a list, buffer or file.
-
-`GPG_ERR_NO_ERROR'
-     This value indicates success.  The value of this error code is
-     `0'.  Also, it is guaranteed that an error value made from the
-     error code `0' will be `0' itself (as a whole).  This means that
-     the error source information is lost for this error code, however,
-     as this error code indicates that no error occurred, this is
-     generally not a problem.
-
-`GPG_ERR_GENERAL'
-     This value means that something went wrong, but either there is not
-     enough information about the problem to return a more useful error
-     value, or there is no separate error value for this type of
-     problem.
-
-`GPG_ERR_ENOMEM'
-     This value means that an out-of-memory condition occurred.
-
-`GPG_ERR_E...'
-     System errors are mapped to GPG_ERR_EFOO where FOO is the symbol
-     for the system error.
-
-`GPG_ERR_INV_VALUE'
-     This value means that some user provided data was out of range.
-
-`GPG_ERR_UNUSABLE_PUBKEY'
-     This value means that some recipients for a message were invalid.
-
-`GPG_ERR_UNUSABLE_SECKEY'
-     This value means that some signers were invalid.
-
-`GPG_ERR_NO_DATA'
-     This value means that data was expected where no data was found.
-
-`GPG_ERR_CONFLICT'
-     This value means that a conflict of some sort occurred.
-
-`GPG_ERR_NOT_IMPLEMENTED'
-     This value indicates that the specific function (or operation) is
-     not implemented.  This error should never happen.  It can only
-     occur if you use certain values or configuration options which do
-     not work, but for which we think that they should work at some
-     later time.
-
-`GPG_ERR_DECRYPT_FAILED'
-     This value indicates that a decryption operation was unsuccessful.
-
-`GPG_ERR_WRONG_KEY_USAGE'
-     This value indicates that a key is not used appropriately.
-
-`GPG_ERR_NO_SECKEY'
-     This value indicates that no secret key for the user ID is
-     available.
-
-`GPG_ERR_UNSUPPORTED_ALGORITHM'
-     This value means a verification failed because the cryptographic
-     algorithm is not supported by the crypto backend.
-
-`GPG_ERR_BAD_SIGNATURE'
-     This value means a verification failed because the signature is
-     bad.
-
-`GPG_ERR_NO_PUBKEY'
-     This value means a verification failed because the public key is
-     not available.
-
-`GPG_ERR_NOT_OPERATIONAL'
-     This value means that the library is not yet in state which allows
-     to use this function.  This error code is in particular returned if
-     Libgcrypt is operated in FIPS mode and the internal state of the
-     library does not yet or not anymore allow the use of a service.
-
-     This error code is only available with newer libgpg-error
-     versions, thus you might see "invalid error code" when passing
-     this to `gpg_strerror'.  The numeric value of this error code is
-     176.
-
-`GPG_ERR_USER_1'
-
-`GPG_ERR_USER_2'
-
-`...'
-
-`GPG_ERR_USER_16'
-     These error codes are not used by any GnuPG component and can be
-     freely used by other software.  Applications using Libgcrypt might
-     use them to mark specific errors returned by callback handlers if
-     no suitable error codes (including the system errors) for these
-     errors exist already.
-
-\1f
-File: gcrypt.info,  Node: Error Strings,  Prev: Error Codes,  Up: Error Handling
-
-3.2.4 Error Strings
--------------------
-
- -- Function: const char * gcry_strerror (gcry_error_t ERR)
-     The function `gcry_strerror' returns a pointer to a statically
-     allocated string containing a description of the error code
-     contained in the error value ERR.  This string can be used to
-     output a diagnostic message to the user.
-
- -- Function: const char * gcry_strsource (gcry_error_t ERR)
-     The function `gcry_strsource' returns a pointer to a statically
-     allocated string containing a description of the error source
-     contained in the error value ERR.  This string can be used to
-     output a diagnostic message to the user.
-
-   The following example illustrates the use of the functions described
-above:
-
-     {
-       gcry_cipher_hd_t handle;
-       gcry_error_t err = 0;
-
-       err = gcry_cipher_open (&handle, GCRY_CIPHER_AES,
-                               GCRY_CIPHER_MODE_CBC, 0);
-       if (err)
-         {
-           fprintf (stderr, "Failure: %s/%s\n",
-                    gcry_strsource (err),
-                    gcry_strerror (err));
-         }
-     }
-
-\1f
-File: gcrypt.info,  Node: Handler Functions,  Next: Symmetric cryptography,  Prev: Generalities,  Up: Top
-
-4 Handler Functions
-*******************
-
-Libgcrypt makes it possible to install so called `handler functions',
-which get called by Libgcrypt in case of certain events.
-
-* Menu:
-
-* Progress handler::            Using a progress handler function.
-* Allocation handler::          Using special memory allocation functions.
-* Error handler::               Using error handler functions.
-* Logging handler::             Using a special logging function.
-
-\1f
-File: gcrypt.info,  Node: Progress handler,  Next: Allocation handler,  Up: Handler Functions
-
-4.1 Progress handler
-====================
-
-It is often useful to retrieve some feedback while long running
-operations are performed.
-
- -- Data type: gcry_handler_progress_t
-     Progress handler functions have to be of the type
-     `gcry_handler_progress_t', which is defined as:
-
-     `void (*gcry_handler_progress_t) (void *, const char *, int, int,
-     int)'
-
-   The following function may be used to register a handler function for
-this purpose.
-
- -- Function: void gcry_set_progress_handler (gcry_handler_progress_t
-          CB, void *CB_DATA)
-     This function installs CB as the `Progress handler' function.  It
-     may be used only during initialization.  CB must be defined as
-     follows:
-
-          void
-          my_progress_handler (void *CB_DATA, const char *WHAT,
-                               int PRINTCHAR, int CURRENT, int TOTAL)
-          {
-            /* Do something.  */
-          }
-
-     A description of the arguments of the progress handler function
-     follows.
-
-    CB_DATA
-          The argument provided in the call to
-          `gcry_set_progress_handler'.
-
-    WHAT
-          A string identifying the type of the progress output.  The
-          following values for WHAT are defined:
-
-         `need_entropy'
-               Not enough entropy is available.  TOTAL holds the number
-               of required bytes.
-
-         `wait_dev_random'
-               Waiting to re-open a random device.  TOTAL gives the
-               number of seconds until the next try.
-
-         `primegen'
-               Values for PRINTCHAR:
-              `\n'
-                    Prime generated.
-
-              `!'
-                    Need to refresh the pool of prime numbers.
-
-              `<, >'
-                    Number of bits adjusted.
-
-              `^'
-                    Searching for a generator.
-
-              `.'
-                    Fermat test on 10 candidates failed.
-
-              `:'
-                    Restart with a new random value.
-
-              `+'
-                    Rabin Miller test passed.
-
-
-
-\1f
-File: gcrypt.info,  Node: Allocation handler,  Next: Error handler,  Prev: Progress handler,  Up: Handler Functions
-
-4.2 Allocation handler
-======================
-
-It is possible to make Libgcrypt use special memory allocation
-functions instead of the built-in ones.
-
-   Memory allocation functions are of the following types:
-
- -- Data type: gcry_handler_alloc_t
-     This type is defined as: `void *(*gcry_handler_alloc_t) (size_t
-     n)'.
-
- -- Data type: gcry_handler_secure_check_t
-     This type is defined as: `int *(*gcry_handler_secure_check_t)
-     (const void *)'.
-
- -- Data type: gcry_handler_realloc_t
-     This type is defined as: `void *(*gcry_handler_realloc_t) (void
-     *p, size_t n)'.
-
- -- Data type: gcry_handler_free_t
-     This type is defined as: `void *(*gcry_handler_free_t) (void *)'.
-
-   Special memory allocation functions can be installed with the
-following function:
-
- -- Function: void gcry_set_allocation_handler (gcry_handler_alloc_t
-          FUNC_ALLOC, gcry_handler_alloc_t FUNC_ALLOC_SECURE,
-          gcry_handler_secure_check_t FUNC_SECURE_CHECK,
-          gcry_handler_realloc_t FUNC_REALLOC, gcry_handler_free_t
-          FUNC_FREE)
-     Install the provided functions and use them instead of the built-in
-     functions for doing memory allocation.  Using this function is in
-     general not recommended because the standard Libgcrypt allocation
-     functions are guaranteed to zeroize memory if needed.
-
-     This function may be used only during initialization and may not be
-     used in fips mode.
-
-
-\1f
-File: gcrypt.info,  Node: Error handler,  Next: Logging handler,  Prev: Allocation handler,  Up: Handler Functions
-
-4.3 Error handler
-=================
-
-The following functions may be used to register handler functions that
-are called by Libgcrypt in case certain error conditions occur.  They
-may and should be registered prior to calling `gcry_check_version'.
-
- -- Data type: gcry_handler_no_mem_t
-     This type is defined as: `int (*gcry_handler_no_mem_t) (void *,
-     size_t, unsigned int)'
-
- -- Function: void gcry_set_outofcore_handler (gcry_handler_no_mem_t
-          FUNC_NO_MEM, void *CB_DATA)
-     This function registers FUNC_NO_MEM as `out-of-core handler',
-     which means that it will be called in the case of not having enough
-     memory available.  The handler is called with 3 arguments: The
-     first one is the pointer CB_DATA as set with this function, the
-     second is the requested memory size and the last being a flag.  If
-     bit 0 of the flag is set, secure memory has been requested.  The
-     handler should either return true to indicate that Libgcrypt
-     should try again allocating memory or return false to let
-     Libgcrypt use its default fatal error handler.
-
- -- Data type: gcry_handler_error_t
-     This type is defined as: `void (*gcry_handler_error_t) (void *,
-     int, const char *)'
-
- -- Function: void gcry_set_fatalerror_handler (gcry_handler_error_t
-          FUNC_ERROR, void *CB_DATA)
-     This function registers FUNC_ERROR as `error handler', which means
-     that it will be called in error conditions.
-
-\1f
-File: gcrypt.info,  Node: Logging handler,  Prev: Error handler,  Up: Handler Functions
-
-4.4 Logging handler
-===================
-
- -- Data type: gcry_handler_log_t
-     This type is defined as: `void (*gcry_handler_log_t) (void *, int,
-     const char *, va_list)'
-
- -- Function: void gcry_set_log_handler (gcry_handler_log_t FUNC_LOG,
-          void *CB_DATA)
-     This function registers FUNC_LOG as `logging handler', which means
-     that it will be called in case Libgcrypt wants to log a message.
-     This function may and should be used prior to calling
-     `gcry_check_version'.
-
-\1f
-File: gcrypt.info,  Node: Symmetric cryptography,  Next: Public Key cryptography,  Prev: Handler Functions,  Up: Top
-
-5 Symmetric cryptography
-************************
-
-The cipher functions are used for symmetrical cryptography, i.e.
-cryptography using a shared key.  The programming model follows an
-open/process/close paradigm and is in that similar to other building
-blocks provided by Libgcrypt.
-
-* Menu:
-
-* Available ciphers::           List of ciphers supported by the library.
-* Available cipher modes::      List of cipher modes supported by the library.
-* Working with cipher handles::  How to perform operations related to cipher handles.
-* General cipher functions::    General cipher functions independent of cipher handles.
-
-\1f
-File: gcrypt.info,  Node: Available ciphers,  Next: Available cipher modes,  Up: Symmetric cryptography
-
-5.1 Available ciphers
-=====================
-
-`GCRY_CIPHER_NONE'
-     This is not a real algorithm but used by some functions as error
-     return.  The value always evaluates to false.
-
-`GCRY_CIPHER_IDEA'
-     This is the IDEA algorithm.
-
-`GCRY_CIPHER_3DES'
-     Triple-DES with 3 Keys as EDE.  The key size of this algorithm is
-     168 but you have to pass 192 bits because the most significant
-     bits of each byte are ignored.
-
-`GCRY_CIPHER_CAST5'
-     CAST128-5 block cipher algorithm.  The key size is 128 bits.
-
-`GCRY_CIPHER_BLOWFISH'
-     The blowfish algorithm. The current implementation allows only for
-     a key size of 128 bits.
-
-`GCRY_CIPHER_SAFER_SK128'
-     Reserved and not currently implemented.
-
-`GCRY_CIPHER_DES_SK'
-     Reserved and not currently implemented.
-
-`GCRY_CIPHER_AES'
-`GCRY_CIPHER_AES128'
-`GCRY_CIPHER_RIJNDAEL'
-`GCRY_CIPHER_RIJNDAEL128'
-     AES (Rijndael) with a 128 bit key.
-
-`GCRY_CIPHER_AES192'
-`GCRY_CIPHER_RIJNDAEL192'
-     AES (Rijndael) with a 192 bit key.
-
-`GCRY_CIPHER_AES256'
-`GCRY_CIPHER_RIJNDAEL256'
-     AES (Rijndael) with a 256 bit key.
-
-`GCRY_CIPHER_TWOFISH'
-     The Twofish algorithm with a 256 bit key.
-
-`GCRY_CIPHER_TWOFISH128'
-     The Twofish algorithm with a 128 bit key.
-
-`GCRY_CIPHER_ARCFOUR'
-     An algorithm which is 100% compatible with RSA Inc.'s RC4
-     algorithm.  Note that this is a stream cipher and must be used
-     very carefully to avoid a couple of weaknesses.
-
-`GCRY_CIPHER_DES'
-     Standard DES with a 56 bit key. You need to pass 64 bit but the
-     high bits of each byte are ignored.  Note, that this is a weak
-     algorithm which can be broken in reasonable time using a brute
-     force approach.
-
-`GCRY_CIPHER_SERPENT128'
-`GCRY_CIPHER_SERPENT192'
-`GCRY_CIPHER_SERPENT256'
-     The Serpent cipher from the AES contest.
-
-`GCRY_CIPHER_RFC2268_40'
-`GCRY_CIPHER_RFC2268_128'
-     Ron's Cipher 2 in the 40 and 128 bit variants.
-
-`GCRY_CIPHER_SEED'
-     A 128 bit cipher as described by RFC4269.
-
-`GCRY_CIPHER_CAMELLIA128'
-`GCRY_CIPHER_CAMELLIA192'
-`GCRY_CIPHER_CAMELLIA256'
-     The Camellia cipher by NTT.  See
-     `http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html'.
-
-`GCRY_CIPHER_SALSA20'
-     This is the Salsa20 stream cipher.
-
-`GCRY_CIPHER_SALSA20R12'
-     This is the Salsa20/12 - reduced round version of Salsa20 stream
-     cipher.
-
-`GCRY_CIPHER_GOST28147'
-     The GOST 28147-89 cipher, defined in the respective GOST standard.
-     Translation of this GOST into English is provided in the RFC-5830.
-
-
-\1f
-File: gcrypt.info,  Node: Available cipher modes,  Next: Working with cipher handles,  Prev: Available ciphers,  Up: Symmetric cryptography
-
-5.2 Available cipher modes
-==========================
-
-`GCRY_CIPHER_MODE_NONE'
-     No mode specified.  This should not be used.  The only exception
-     is that if Libgcrypt is not used in FIPS mode and if any debug
-     flag has been set, this mode may be used to bypass the actual
-     encryption.
-
-`GCRY_CIPHER_MODE_ECB'
-     Electronic Codebook mode.
-
-`GCRY_CIPHER_MODE_CFB'
-     Cipher Feedback mode.  The shift size equals the block size of the
-     cipher (e.g. for AES it is CFB-128).
-
-`GCRY_CIPHER_MODE_CBC'
-     Cipher Block Chaining mode.
-
-`GCRY_CIPHER_MODE_STREAM'
-     Stream mode, only to be used with stream cipher algorithms.
-
-`GCRY_CIPHER_MODE_OFB'
-     Output Feedback mode.
-
-`GCRY_CIPHER_MODE_CTR'
-     Counter mode.
-
-`GCRY_CIPHER_MODE_AESWRAP'
-     This mode is used to implement the AES-Wrap algorithm according to
-     RFC-3394.  It may be used with any 128 bit block length algorithm,
-     however the specs require one of the 3 AES algorithms.  These
-     special conditions apply: If `gcry_cipher_setiv' has not been used
-     the standard IV is used; if it has been used the lower 64 bit of
-     the IV are used as the Alternative Initial Value.  On encryption
-     the provided output buffer must be 64 bit (8 byte) larger than the
-     input buffer; in-place encryption is still allowed.  On decryption
-     the output buffer may be specified 64 bit (8 byte) shorter than
-     then input buffer.  As per specs the input length must be at least
-     128 bits and the length must be a multiple of 64 bits.
-
-`GCRY_CIPHER_MODE_CCM'
-     Counter with CBC-MAC mode is an Authenticated Encryption with
-     Associated Data (AEAD) block cipher mode, which is specified in
-     'NIST Special Publication 800-38C' and RFC 3610.
-
-`GCRY_CIPHER_MODE_GCM'
-     Galois/Counter Mode (GCM) is an Authenticated Encryption with
-     Associated Data (AEAD) block cipher mode, which is specified in
-     'NIST Special Publication 800-38D'.
-
-
-\1f
-File: gcrypt.info,  Node: Working with cipher handles,  Next: General cipher functions,  Prev: Available cipher modes,  Up: Symmetric cryptography
-
-5.3 Working with cipher handles
-===============================
-
-To use a cipher algorithm, you must first allocate an according handle.
-This is to be done using the open function:
-
- -- Function: gcry_error_t gcry_cipher_open (gcry_cipher_hd_t *HD, int
-          ALGO, int MODE, unsigned int FLAGS)
-     This function creates the context handle required for most of the
-     other cipher functions and returns a handle to it in `hd'.  In
-     case of an error, an according error code is returned.
-
-     The ID of algorithm to use must be specified via ALGO.  See *Note
-     Available ciphers::, for a list of supported ciphers and the
-     according constants.
-
-     Besides using the constants directly, the function
-     `gcry_cipher_map_name' may be used to convert the textual name of
-     an algorithm into the according numeric ID.
-
-     The cipher mode to use must be specified via MODE.  See *Note
-     Available cipher modes::, for a list of supported cipher modes and
-     the according constants.  Note that some modes are incompatible
-     with some algorithms - in particular, stream mode
-     (`GCRY_CIPHER_MODE_STREAM') only works with stream ciphers. The
-     block cipher modes (`GCRY_CIPHER_MODE_ECB',
-     `GCRY_CIPHER_MODE_CBC', `GCRY_CIPHER_MODE_CFB',
-     `GCRY_CIPHER_MODE_OFB' and `GCRY_CIPHER_MODE_CTR') will work with
-     any block cipher algorithm. `GCRY_CIPHER_MODE_CCM' and
-     `GCRY_CIPHER_MODE_GCM' modes will only work with block cipher
-     algorithms which have the block size of 16 bytes.
-
-     The third argument FLAGS can either be passed as `0' or as the
-     bit-wise OR of the following constants.
-
-    `GCRY_CIPHER_SECURE'
-          Make sure that all operations are allocated in secure memory.
-          This is useful when the key material is highly confidential.
-
-    `GCRY_CIPHER_ENABLE_SYNC'
-          This flag enables the CFB sync mode, which is a special
-          feature of Libgcrypt's CFB mode implementation to allow for
-          OpenPGP's CFB variant.  See `gcry_cipher_sync'.
-
-    `GCRY_CIPHER_CBC_CTS'
-          Enable cipher text stealing (CTS) for the CBC mode.  Cannot
-          be used simultaneous as GCRY_CIPHER_CBC_MAC.  CTS mode makes
-          it possible to transform data of almost arbitrary size (only
-          limitation is that it must be greater than the algorithm's
-          block size).
-
-    `GCRY_CIPHER_CBC_MAC'
-          Compute CBC-MAC keyed checksums.  This is the same as CBC
-          mode, but only output the last block.  Cannot be used
-          simultaneous as GCRY_CIPHER_CBC_CTS.
-
-   Use the following function to release an existing handle:
-
- -- Function: void gcry_cipher_close (gcry_cipher_hd_t H)
-     This function releases the context created by `gcry_cipher_open'.
-     It also zeroises all sensitive information associated with this
-     cipher handle.
-
-   In order to use a handle for performing cryptographic operations, a
-`key' has to be set first:
-
- -- Function: gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t H,
-          const void *K, size_t L)
-     Set the key K used for encryption or decryption in the context
-     denoted by the handle H.  The length L (in bytes) of the key K
-     must match the required length of the algorithm set for this
-     context or be in the allowed range for algorithms with variable
-     key size.  The function checks this and returns an error if there
-     is a problem.  A caller should always check for an error.
-
-
-   Most crypto modes requires an initialization vector (IV), which
-usually is a non-secret random string acting as a kind of salt value.
-The CTR mode requires a counter, which is also similar to a salt value.
-To set the IV or CTR, use these functions:
-
- -- Function: gcry_error_t gcry_cipher_setiv (gcry_cipher_hd_t H, const
-          void *K, size_t L)
-     Set the initialization vector used for encryption or decryption.
-     The vector is passed as the buffer K of length L bytes and copied
-     to internal data structures.  The function checks that the IV
-     matches the requirement of the selected algorithm and mode.
-
-     This function is also used with the Salsa20 stream cipher to set or
-     update the required nonce.  In this case it needs to be called
-     after setting the key.
-
-     This function is also used with the AEAD cipher modes to set or
-     update the required nonce.
-
-
- -- Function: gcry_error_t gcry_cipher_setctr (gcry_cipher_hd_t H,
-          const void *C, size_t L)
-     Set the counter vector used for encryption or decryption. The
-     counter is passed as the buffer C of length L bytes and copied to
-     internal data structures.  The function checks that the counter
-     matches the requirement of the selected algorithm (i.e., it must be
-     the same size as the block size).
-
- -- Function: gcry_error_t gcry_cipher_reset (gcry_cipher_hd_t H)
-     Set the given handle's context back to the state it had after the
-     last call to gcry_cipher_setkey and clear the initialization
-     vector.
-
-     Note that gcry_cipher_reset is implemented as a macro.
-
-   Authenticated Encryption with Associated Data (AEAD) block cipher
-modes require the handling of the authentication tag and the additional
-authenticated data, which can be done by using the following functions:
-
- -- Function: gcry_error_t gcry_cipher_authenticate (gcry_cipher_hd_t
-          H, const void *ABUF, size_t ABUFLEN)
-     Process the buffer ABUF of length ABUFLEN as the additional
-     authenticated data (AAD) for AEAD cipher modes.
-
-
- -- Function: gcry_error_t gcry_cipher_gettag (gcry_cipher_hd_t H, void
-          *TAG, size_t TAGLEN)
-     This function is used to read the authentication tag after
-     encryption.  The function finalizes and outputs the authentication
-     tag to the buffer TAG of length TAGLEN bytes.
-
-
- -- Function: gcry_error_t gcry_cipher_checktag (gcry_cipher_hd_t H,
-          const void *TAG, size_t TAGLEN)
-     Check the authentication tag after decryption. The authentication
-     tag is passed as the buffer TAG of length TAGLEN bytes and
-     compared to internal authentication tag computed during
-     decryption.  Error code `GPG_ERR_CHECKSUM' is returned if the
-     authentication tag in the buffer TAG does not match the
-     authentication tag calculated during decryption.
-
-
-   The actual encryption and decryption is done by using one of the
-following functions.  They may be used as often as required to process
-all the data.
-
- -- Function: gcry_error_t gcry_cipher_encrypt (gcry_cipher_hd_t H,
-          unsigned char *out, size_t OUTSIZE, const unsigned char *IN,
-          size_t INLEN)
-     `gcry_cipher_encrypt' is used to encrypt the data.  This function
-     can either work in place or with two buffers.  It uses the cipher
-     context already setup and described by the handle H.  There are 2
-     ways to use the function: If IN is passed as `NULL' and INLEN is
-     `0', in-place encryption of the data in OUT or length OUTSIZE
-     takes place.  With IN being not `NULL', INLEN bytes are encrypted
-     to the buffer OUT which must have at least a size of INLEN.
-     OUTSIZE must be set to the allocated size of OUT, so that the
-     function can check that there is sufficient space. Note that
-     overlapping buffers are not allowed.
-
-     Depending on the selected algorithms and encryption mode, the
-     length of the buffers must be a multiple of the block size.
-
-     The function returns `0' on success or an error code.
-
- -- Function: gcry_error_t gcry_cipher_decrypt (gcry_cipher_hd_t H,
-          unsigned char *out, size_t OUTSIZE, const unsigned char *IN,
-          size_t INLEN)
-     `gcry_cipher_decrypt' is used to decrypt the data.  This function
-     can either work in place or with two buffers.  It uses the cipher
-     context already setup and described by the handle H.  There are 2
-     ways to use the function: If IN is passed as `NULL' and INLEN is
-     `0', in-place decryption of the data in OUT or length OUTSIZE
-     takes place.  With IN being not `NULL', INLEN bytes are decrypted
-     to the buffer OUT which must have at least a size of INLEN.
-     OUTSIZE must be set to the allocated size of OUT, so that the
-     function can check that there is sufficient space.  Note that
-     overlapping buffers are not allowed.
-
-     Depending on the selected algorithms and encryption mode, the
-     length of the buffers must be a multiple of the block size.
-
-     The function returns `0' on success or an error code.
-
-   OpenPGP (as defined in RFC-2440) requires a special sync operation in
-some places.  The following function is used for this:
-
- -- Function: gcry_error_t gcry_cipher_sync (gcry_cipher_hd_t H)
-     Perform the OpenPGP sync operation on context H.  Note that this
-     is a no-op unless the context was created with the flag
-     `GCRY_CIPHER_ENABLE_SYNC'
-
-   Some of the described functions are implemented as macros utilizing a
-catch-all control function.  This control function is rarely used
-directly but there is nothing which would inhibit it:
-
- -- Function: gcry_error_t gcry_cipher_ctl (gcry_cipher_hd_t H, int
-          CMD, void *BUFFER, size_t BUFLEN)
-     `gcry_cipher_ctl' controls various aspects of the cipher module and
-     specific cipher contexts.  Usually some more specialized functions
-     or macros are used for this purpose.  The semantics of the
-     function and its parameters depends on the the command CMD and the
-     passed context handle H.  Please see the comments in the source
-     code (`src/global.c') for details.
-
- -- Function: gcry_error_t gcry_cipher_info (gcry_cipher_hd_t H, int
-          WHAT, void *BUFFER, size_t *NBYTES)
-     `gcry_cipher_info' is used to retrieve various information about a
-     cipher context or the cipher module in general.
-
-     Currently no information is available.
-
-\1f
-File: gcrypt.info,  Node: General cipher functions,  Prev: Working with cipher handles,  Up: Symmetric cryptography
-
-5.4 General cipher functions
-============================
-
-To work with the algorithms, several functions are available to map
-algorithm names to the internal identifiers, as well as ways to
-retrieve information about an algorithm or the current cipher context.
-
- -- Function: gcry_error_t gcry_cipher_algo_info (int ALGO, int WHAT,
-          void *BUFFER, size_t *NBYTES)
-     This function is used to retrieve information on a specific
-     algorithm.  You pass the cipher algorithm ID as ALGO and the type
-     of information requested as WHAT. The result is either returned as
-     the return code of the function or copied to the provided BUFFER
-     whose allocated length must be available in an integer variable
-     with the address passed in NBYTES.  This variable will also
-     receive the actual used length of the buffer.
-
-     Here is a list of supported codes for WHAT:
-
-    `GCRYCTL_GET_KEYLEN:'
-          Return the length of the key. If the algorithm supports
-          multiple key lengths, the maximum supported value is
-          returned.  The length is returned as number of octets (bytes)
-          and not as number of bits in NBYTES; BUFFER must be zero.
-          Note that it is usually better to use the convenience function
-          `gcry_cipher_get_algo_keylen'.
-
-    `GCRYCTL_GET_BLKLEN:'
-          Return the block length of the algorithm.  The length is
-          returned as a number of octets in NBYTES; BUFFER must be
-          zero.  Note that it is usually better to use the convenience
-          function `gcry_cipher_get_algo_blklen'.
-
-    `GCRYCTL_TEST_ALGO:'
-          Returns `0' when the specified algorithm is available for use.
-          BUFFER and NBYTES must be zero.
-
-
-
- -- Function: size_t gcry_cipher_get_algo_keylen (ALGO)
-     This function returns length of the key for algorithm ALGO.  If
-     the algorithm supports multiple key lengths, the maximum supported
-     key length is returned.  On error `0' is returned.  The key length
-     is returned as number of octets.
-
-     This is a convenience functions which should be preferred over
-     `gcry_cipher_algo_info' because it allows for proper type checking.
-
- -- Function: size_t gcry_cipher_get_algo_blklen (int ALGO)
-     This functions returns the block-length of the algorithm ALGO
-     counted in octets.  On error `0' is returned.
-
-     This is a convenience functions which should be preferred over
-     `gcry_cipher_algo_info' because it allows for proper type checking.
-
- -- Function: const char * gcry_cipher_algo_name (int ALGO)
-     `gcry_cipher_algo_name' returns a string with the name of the
-     cipher algorithm ALGO.  If the algorithm is not known or another
-     error occurred, the string `"?"' is returned.  This function should
-     not be used to test for the availability of an algorithm.
-
- -- Function: int gcry_cipher_map_name (const char *NAME)
-     `gcry_cipher_map_name' returns the algorithm identifier for the
-     cipher algorithm described by the string NAME.  If this algorithm
-     is not available `0' is returned.
-
- -- Function: int gcry_cipher_mode_from_oid (const char *STRING)
-     Return the cipher mode associated with an ASN.1 object identifier.
-     The object identifier is expected to be in the IETF-style dotted
-     decimal notation.  The function returns `0' for an unknown object
-     identifier or when no mode is associated with it.
-
-\1f
-File: gcrypt.info,  Node: Public Key cryptography,  Next: Hashing,  Prev: Symmetric cryptography,  Up: Top
-
-6 Public Key cryptography
-*************************
-
-Public key cryptography, also known as asymmetric cryptography, is an
-easy way for key management and to provide digital signatures.
-Libgcrypt provides two completely different interfaces to public key
-cryptography, this chapter explains the one based on S-expressions.
-
-* Menu:
-
-* Available algorithms::        Algorithms supported by the library.
-* Used S-expressions::          Introduction into the used S-expression.
-* Cryptographic Functions::     Functions for performing the cryptographic actions.
-* General public-key related Functions::  General functions, not implementing any cryptography.
-
-\1f
-File: gcrypt.info,  Node: Available algorithms,  Next: Used S-expressions,  Up: Public Key cryptography
-
-6.1 Available algorithms
-========================
-
-Libgcrypt supports the RSA (Rivest-Shamir-Adleman) algorithms as well
-as DSA (Digital Signature Algorithm) and Elgamal.  The versatile
-interface allows to add more algorithms in the future.
-
-\1f
-File: gcrypt.info,  Node: Used S-expressions,  Next: Cryptographic Functions,  Prev: Available algorithms,  Up: Public Key cryptography
-
-6.2 Used S-expressions
-======================
-
-Libgcrypt's API for asymmetric cryptography is based on data structures
-called S-expressions (see
-`http://people.csail.mit.edu/rivest/sexp.html') and does not work with
-contexts as most of the other building blocks of Libgcrypt do.
-
-The following information are stored in S-expressions:
-
-   * keys
-
-   * plain text data
-
-   * encrypted data
-
-   * signatures
-
-
-To describe how Libgcrypt expect keys, we use examples. Note that words
-in uppercase indicate parameters whereas lowercase words are literals.
-
-   Note that all MPI (multi-precision-integers) values are expected to
-be in `GCRYMPI_FMT_USG' format.  An easy way to create S-expressions is
-by using `gcry_sexp_build' which allows to pass a string with
-printf-like escapes to insert MPI values.
-
-* Menu:
-
-* RSA key parameters::  Parameters used with an RSA key.
-* DSA key parameters::  Parameters used with a DSA key.
-* ECC key parameters::  Parameters used with ECC keys.
-
-\1f
-File: gcrypt.info,  Node: RSA key parameters,  Next: DSA key parameters,  Up: Used S-expressions
-
-6.2.1 RSA key parameters
-------------------------
-
-An RSA private key is described by this S-expression:
-
-     (private-key
-       (rsa
-         (n N-MPI)
-         (e E-MPI)
-         (d D-MPI)
-         (p P-MPI)
-         (q Q-MPI)
-         (u U-MPI)))
-
-An RSA public key is described by this S-expression:
-
-     (public-key
-       (rsa
-         (n N-MPI)
-         (e E-MPI)))
-
-N-MPI
-     RSA public modulus n.
-
-E-MPI
-     RSA public exponent e.
-
-D-MPI
-     RSA secret exponent d = e^-1 \bmod (p-1)(q-1).
-
-P-MPI
-     RSA secret prime p.
-
-Q-MPI
-     RSA secret prime q with p < q.
-
-U-MPI
-     Multiplicative inverse u = p^-1 \bmod q.
-
-   For signing and decryption the parameters (p, q, u) are optional but
-greatly improve the performance.  Either all of these optional
-parameters must be given or none of them.  They are mandatory for
-gcry_pk_testkey.
-
-   Note that OpenSSL uses slighly different parameters: q < p and  u =
-q^-1 \bmod p.  To use these parameters you will need to swap the values
-and recompute u.  Here is example code to do this:
-
-       if (gcry_mpi_cmp (p, q) > 0)
-         {
-           gcry_mpi_swap (p, q);
-           gcry_mpi_invm (u, p, q);
-         }
-
-\1f
-File: gcrypt.info,  Node: DSA key parameters,  Next: ECC key parameters,  Prev: RSA key parameters,  Up: Used S-expressions
-
-6.2.2 DSA key parameters
-------------------------
-
-A DSA private key is described by this S-expression:
-
-     (private-key
-       (dsa
-         (p P-MPI)
-         (q Q-MPI)
-         (g G-MPI)
-         (y Y-MPI)
-         (x X-MPI)))
-
-P-MPI
-     DSA prime p.
-
-Q-MPI
-     DSA group order q (which is a prime divisor of p-1).
-
-G-MPI
-     DSA group generator g.
-
-Y-MPI
-     DSA public key value y = g^x \bmod p.
-
-X-MPI
-     DSA secret exponent x.
-
-   The public key is similar with "private-key" replaced by "public-key"
-and no X-MPI.
-
-\1f
-File: gcrypt.info,  Node: ECC key parameters,  Prev: DSA key parameters,  Up: Used S-expressions
-
-6.2.3 ECC key parameters
-------------------------
-
-An ECC private key is described by this S-expression:
-
-     (private-key
-       (ecc
-         (p P-MPI)
-         (a A-MPI)
-         (b B-MPI)
-         (g G-POINT)
-         (n N-MPI)
-         (q Q-POINT)
-         (d D-MPI)))
-
-P-MPI
-     Prime specifying the field GF(p).
-
-A-MPI
-B-MPI
-     The two coefficients of the Weierstrass equation y^2 = x^3 + ax + b
-
-G-POINT
-     Base point g.
-
-N-MPI
-     Order of g
-
-Q-POINT
-     The point representing the public key Q = dG.
-
-D-MPI
-     The private key d
-
-   All point values are encoded in standard format; Libgcrypt does in
-general only support uncompressed points, thus the first byte needs to
-be `0x04'.  However "EdDSA" describes its own compression scheme which
-is used by default; the non-standard first byte `0x40' may optionally
-be used to explicit flag the use of the algorithm’s native
-compression method.
-
-   The public key is similar with "private-key" replaced by "public-key"
-and no D-MPI.
-
-   If the domain parameters are well-known, the name of this curve may
-be used.  For example
-
-     (private-key
-       (ecc
-         (curve "NIST P-192")
-         (q Q-POINT)
-         (d D-MPI)))
-
-   Note that Q-POINT is optional for a private key.  The `curve'
-parameter may be given in any case and is used to replace missing
-parameters.
-
-Currently implemented curves are:
-`NIST P-192'
-`1.2.840.10045.3.1.1'
-`prime192v1'
-`secp192r1'
-     The NIST 192 bit curve, its OID, X9.62 and SECP aliases.
-
-`NIST P-224'
-`secp224r1'
-     The NIST 224 bit curve and its SECP alias.
-
-`NIST P-256'
-`1.2.840.10045.3.1.7'
-`prime256v1'
-`secp256r1'
-     The NIST 256 bit curve, its OID, X9.62 and SECP aliases.
-
-`NIST P-384'
-`secp384r1'
-     The NIST 384 bit curve and its SECP alias.
-
-`NIST P-521'
-`secp521r1'
-     The NIST 521 bit curve and its SECP alias.
-
-   As usual the OIDs may optionally be prefixed with the string `OID.'
-or `oid.'.
-
-\1f
-File: gcrypt.info,  Node: Cryptographic Functions,  Next: General public-key related Functions,  Prev: Used S-expressions,  Up: Public Key cryptography
-
-6.3 Cryptographic Functions
-===========================
-
-Some functions operating on S-expressions support `flags' to influence
-the operation.  These flags have to be listed in a sub-S-expression
-named `flags'.  Flag names are case-sensitive.  The following flags are
-known:
-
-`comp'
-`nocomp'
-     If supported by the algorithm and curve the `comp' flag requests
-     that points are returned in compact (compressed) representation.
-     The `nocomp' flag requests that points are returned with full
-     coordinates.  The default depends on the the algorithm and curve.
-     The compact representation requires a small overhead before a
-     point can be used but halves the size of a to be conveyed public
-     key.  If `comp' is used with the "EdDSA" algorithm the key
-     generation prefix the public key with a `0x40' byte.
-
-`pkcs1'
-     Use PKCS#1 block type 2 padding for encryption, block type 1
-     padding for signing.
-
-`oaep'
-     Use RSA-OAEP padding for encryption.
-
-`pss'
-     Use RSA-PSS padding for signing.
-
-`eddsa'
-     Use the EdDSA scheme signing instead of the default ECDSA
-     algorithm.  Note that the EdDSA uses a special form of the public
-     key.
-
-`rfc6979'
-     For DSA and ECDSA use a deterministic scheme for the k parameter.
-
-`no-blinding'
-     Do not use a technique called `blinding', which is used by default
-     in order to prevent leaking of secret information.  Blinding is
-     only implemented by RSA, but it might be implemented by other
-     algorithms in the future as well, when necessary.
-
-`param'
-     For ECC key generation also return the domain parameters.  For ECC
-     signing and verification override default parameters by provided
-     domain parameters of the public or private key.
-
-`transient-key'
-     This flag is only meaningful for RSA, DSA, and ECC key generation.
-     If given the key is created using a faster and a somewhat less
-     secure random number generator.  This flag may be used for keys
-     which are only used for a short time or per-message and do not
-     require full cryptographic strength.
-
-`use-x931'
-     Force the use of the ANSI X9.31 key generation algorithm instead of
-     the default algorithm. This flag is only meaningful for RSA key
-     generation and usually not required.  Note that this algorithm is
-     implicitly used if either `derive-parms' is given or Libgcrypt is
-     in FIPS mode.
-
-`use-fips186'
-     Force the use of the FIPS 186 key generation algorithm instead of
-     the default algorithm.  This flag is only meaningful for DSA and
-     usually not required.  Note that this algorithm is implicitly used
-     if either `derive-parms' is given or Libgcrypt is in FIPS mode.
-     As of now FIPS 186-2 is implemented; after the approval of FIPS
-     186-3 the code will be changed to implement 186-3.
-
-`use-fips186-2'
-     Force the use of the FIPS 186-2 key generation algorithm instead of
-     the default algorithm.  This algorithm is slightly different from
-     FIPS 186-3 and allows only 1024 bit keys.  This flag is only
-     meaningful for DSA and only required for FIPS testing backward
-     compatibility.
-
-
-Now that we know the key basics, we can carry on and explain how to
-encrypt and decrypt data.  In almost all cases the data is a random
-session key which is in turn used for the actual encryption of the real
-data.  There are 2 functions to do this:
-
- -- Function: gcry_error_t gcry_pk_encrypt (gcry_sexp_t *R_CIPH,
-          gcry_sexp_t DATA, gcry_sexp_t PKEY)
-     Obviously a public key must be provided for encryption.  It is
-     expected as an appropriate S-expression (see above) in PKEY.  The
-     data to be encrypted can either be in the simple old format, which
-     is a very simple S-expression consisting only of one MPI, or it
-     may be a more complex S-expression which also allows to specify
-     flags for operation, like e.g. padding rules.
-
-     If you don't want to let Libgcrypt handle the padding, you must
-     pass an appropriate MPI using this expression for DATA:
-
-          (data
-            (flags raw)
-            (value MPI))
-
-     This has the same semantics as the old style MPI only way.  MPI is
-     the actual data, already padded appropriate for your protocol.
-     Most RSA based systems however use PKCS#1 padding and so you can
-     use this S-expression for DATA:
-
-          (data
-            (flags pkcs1)
-            (value BLOCK))
-
-     Here, the "flags" list has the "pkcs1" flag which let the function
-     know that it should provide PKCS#1 block type 2 padding.  The
-     actual data to be encrypted is passed as a string of octets in
-     BLOCK.  The function checks that this data actually can be used
-     with the given key, does the padding and encrypts it.
-
-     If the function could successfully perform the encryption, the
-     return value will be 0 and a new S-expression with the encrypted
-     result is allocated and assigned to the variable at the address of
-     R_CIPH.  The caller is responsible to release this value using
-     `gcry_sexp_release'.  In case of an error, an error code is
-     returned and R_CIPH will be set to `NULL'.
-
-     The returned S-expression has this format when used with RSA:
-
-          (enc-val
-            (rsa
-              (a A-MPI)))
-
-     Where A-MPI is an MPI with the result of the RSA operation.  When
-     using the Elgamal algorithm, the return value will have this
-     format:
-
-          (enc-val
-            (elg
-              (a A-MPI)
-              (b B-MPI)))
-
-     Where A-MPI and B-MPI are MPIs with the result of the Elgamal
-     encryption operation.
-
- -- Function: gcry_error_t gcry_pk_decrypt (gcry_sexp_t *R_PLAIN,
-          gcry_sexp_t DATA, gcry_sexp_t SKEY)
-     Obviously a private key must be provided for decryption.  It is
-     expected as an appropriate S-expression (see above) in SKEY.  The
-     data to be decrypted must match the format of the result as
-     returned by `gcry_pk_encrypt', but should be enlarged with a
-     `flags' element:
-
-          (enc-val
-            (flags)
-            (elg
-              (a A-MPI)
-              (b B-MPI)))
-
-     This function does not remove padding from the data by default.  To
-     let Libgcrypt remove padding, give a hint in `flags' telling which
-     padding method was used when encrypting:
-
-          (flags PADDING-METHOD)
-
-     Currently PADDING-METHOD is either `pkcs1' for PKCS#1 block type 2
-     padding, or `oaep' for RSA-OAEP padding.
-
-     The function returns 0 on success or an error code.  The variable
-     at the address of R_PLAIN will be set to NULL on error or receive
-     the decrypted value on success.  The format of R_PLAIN is a simple
-     S-expression part (i.e. not a valid one) with just one MPI if
-     there was no `flags' element in DATA; if at least an empty `flags'
-     is passed in DATA, the format is:
-
-          (value PLAINTEXT)
-
-   Another operation commonly performed using public key cryptography is
-signing data.  In some sense this is even more important than
-encryption because digital signatures are an important instrument for
-key management.  Libgcrypt supports digital signatures using 2
-functions, similar to the encryption functions:
-
- -- Function: gcry_error_t gcry_pk_sign (gcry_sexp_t *R_SIG,
-          gcry_sexp_t DATA, gcry_sexp_t SKEY)
-     This function creates a digital signature for DATA using the
-     private key SKEY and place it into the variable at the address of
-     R_SIG.  DATA may either be the simple old style S-expression with
-     just one MPI or a modern and more versatile S-expression which
-     allows to let Libgcrypt handle padding:
-
-           (data
-            (flags pkcs1)
-            (hash HASH-ALGO BLOCK))
-
-     This example requests to sign the data in BLOCK after applying
-     PKCS#1 block type 1 style padding.  HASH-ALGO is a string with the
-     hash algorithm to be encoded into the signature, this may be any
-     hash algorithm name as supported by Libgcrypt.  Most likely, this
-     will be "sha256" or "sha1".  It is obvious that the length of
-     BLOCK must match the size of that message digests; the function
-     checks that this and other constraints are valid.
-
-     If PKCS#1 padding is not required (because the caller does already
-     provide a padded value), either the old format or better the
-     following format should be used:
-
-          (data
-            (flags raw)
-            (value MPI))
-
-     Here, the data to be signed is directly given as an MPI.
-
-     For DSA the input data is expected in this format:
-
-          (data
-            (flags raw)
-            (value MPI))
-
-     Here, the data to be signed is directly given as an MPI.  It is
-     expect that this MPI is the the hash value.  For the standard DSA
-     using a MPI is not a problem in regard to leading zeroes because
-     the hash value is directly used as an MPI.  For better standard
-     conformance it would be better to explicit use a memory string
-     (like with pkcs1) but that is currently not supported.  However,
-     for deterministic DSA as specified in RFC6979 this can't be used.
-     Instead the following input is expected.
-
-          (data
-            (flags rfc6979)
-            (hash HASH-ALGO BLOCK))
-
-     Note that the provided hash-algo is used for the internal HMAC; it
-     should match the hash-algo used to create BLOCK.
-
-     The signature is returned as a newly allocated S-expression in
-     R_SIG using this format for RSA:
-
-          (sig-val
-            (rsa
-              (s S-MPI)))
-
-     Where S-MPI is the result of the RSA sign operation.  For DSA the
-     S-expression returned is:
-
-          (sig-val
-            (dsa
-              (r R-MPI)
-              (s S-MPI)))
-
-     Where R-MPI and S-MPI are the result of the DSA sign operation.
-
-     For Elgamal signing (which is slow, yields large numbers and
-     probably is not as secure as the other algorithms), the same
-     format is used with "elg" replacing "dsa"; for ECDSA signing, the
-     same format is used with "ecdsa" replacing "dsa".
-
-     For the EdDSA algorithm (cf. Ed25515) the required input
-     parameters are:
-
-          (data
-            (flags eddsa)
-            (hash-algo sha512)
-            (value MESSAGE))
-
-     Note that the MESSAGE may be of any length; hashing is part of the
-     algorithm.  Using a large data block for MESSAGE is not suggested;
-     in that case the used protocol should better require that a hash
-     of the message is used as input to the EdDSA algorithm.
-
-
-The operation most commonly used is definitely the verification of a
-signature.  Libgcrypt provides this function:
-
- -- Function: gcry_error_t gcry_pk_verify (gcry_sexp_t SIG,
-          gcry_sexp_t DATA, gcry_sexp_t PKEY)
-     This is used to check whether the signature SIG matches the DATA.
-     The public key PKEY must be provided to perform this verification.
-     This function is similar in its parameters to `gcry_pk_sign' with
-     the exceptions that the public key is used instead of the private
-     key and that no signature is created but a signature, in a format
-     as created by `gcry_pk_sign', is passed to the function in SIG.
-
-     The result is 0 for success (i.e. the data matches the signature),
-     or an error code where the most relevant code is
-     `GCRY_ERR_BAD_SIGNATURE' to indicate that the signature does not
-     match the provided data.
-
-
-\1f
-File: gcrypt.info,  Node: General public-key related Functions,  Prev: Cryptographic Functions,  Up: Public Key cryptography
-
-6.4 General public-key related Functions
-========================================
-
-A couple of utility functions are available to retrieve the length of
-the key, map algorithm identifiers and perform sanity checks:
-
- -- Function: const char * gcry_pk_algo_name (int ALGO)
-     Map the public key algorithm id ALGO to a string representation of
-     the algorithm name.  For unknown algorithms this functions returns
-     the string `"?"'.  This function should not be used to test for the
-     availability of an algorithm.
-
- -- Function: int gcry_pk_map_name (const char *NAME)
-     Map the algorithm NAME to a public key algorithm Id.  Returns 0 if
-     the algorithm name is not known.
-
- -- Function: int gcry_pk_test_algo (int ALGO)
-     Return 0 if the public key algorithm ALGO is available for use.
-     Note that this is implemented as a macro.
-
- -- Function: unsigned int gcry_pk_get_nbits (gcry_sexp_t KEY)
-     Return what is commonly referred as the key length for the given
-     public or private in KEY.
-
- -- Function: unsigned char * gcry_pk_get_keygrip (gcry_sexp_t KEY,
-          unsigned char *ARRAY)
-     Return the so called "keygrip" which is the SHA-1 hash of the
-     public key parameters expressed in a way depended on the
-     algorithm.  ARRAY must either provide space for 20 bytes or be
-     `NULL'. In the latter case a newly allocated array of that size is
-     returned.  On success a pointer to the newly allocated space or to
-     ARRAY is returned.  `NULL' is returned to indicate an error which
-     is most likely an unknown algorithm or one where a "keygrip" has
-     not yet been defined.  The function accepts public or secret keys
-     in KEY.
-
- -- Function: gcry_error_t gcry_pk_testkey (gcry_sexp_t KEY)
-     Return zero if the private key KEY is `sane', an error code
-     otherwise.  Note that it is not possible to check the `saneness'
-     of a public key.
-
-
- -- Function: gcry_error_t gcry_pk_algo_info (int ALGO, int WHAT,
-          void *BUFFER, size_t *NBYTES)
-     Depending on the value of WHAT return various information about
-     the public key algorithm with the id ALGO.  Note that the function
-     returns `-1' on error and the actual error code must be retrieved
-     using the function `gcry_errno'.  The currently defined values for
-     WHAT are:
-
-    `GCRYCTL_TEST_ALGO:'
-          Return 0 if the specified algorithm is available for use.
-          BUFFER must be `NULL', NBYTES may be passed as `NULL' or
-          point to a variable with the required usage of the algorithm.
-          This may be 0 for "don't care" or the bit-wise OR of these
-          flags:
-
-         `GCRY_PK_USAGE_SIGN'
-               Algorithm is usable for signing.
-
-         `GCRY_PK_USAGE_ENCR'
-               Algorithm is usable for encryption.
-
-          Unless you need to test for the allowed usage, it is in
-          general better to use the macro gcry_pk_test_algo instead.
-
-    `GCRYCTL_GET_ALGO_USAGE:'
-          Return the usage flags for the given algorithm.  An invalid
-          algorithm return 0.  Disabled algorithms are ignored here
-          because we want to know whether the algorithm is at all
-          capable of a certain usage.
-
-    `GCRYCTL_GET_ALGO_NPKEY'
-          Return the number of elements the public key for algorithm
-          ALGO consist of.  Return 0 for an unknown algorithm.
-
-    `GCRYCTL_GET_ALGO_NSKEY'
-          Return the number of elements the private key for algorithm
-          ALGO consist of.  Note that this value is always larger than
-          that of the public key.  Return 0 for an unknown algorithm.
-
-    `GCRYCTL_GET_ALGO_NSIGN'
-          Return the number of elements a signature created with the
-          algorithm ALGO consists of.  Return 0 for an unknown
-          algorithm or for an algorithm not capable of creating
-          signatures.
-
-    `GCRYCTL_GET_ALGO_NENC'
-          Return the number of elements a encrypted message created
-          with the algorithm ALGO consists of.  Return 0 for an unknown
-          algorithm or for an algorithm not capable of encryption.
-
-     Please note that parameters not required should be passed as
-     `NULL'.
-
- -- Function: gcry_error_t gcry_pk_ctl (int CMD, void *BUFFER,
-          size_t BUFLEN)
-     This is a general purpose function to perform certain control
-     operations.  CMD controls what is to be done. The return value is
-     0 for success or an error code.  Currently supported values for
-     CMD are:
-
-    `GCRYCTL_DISABLE_ALGO'
-          Disable the algorithm given as an algorithm id in BUFFER.
-          BUFFER must point to an `int' variable with the algorithm id
-          and BUFLEN must have the value `sizeof (int)'.  This fucntion
-          is not thread safe and should thus be used before any other
-          threads are started.
-
-
-Libgcrypt also provides a function to generate public key pairs:
-
- -- Function: gcry_error_t gcry_pk_genkey (gcry_sexp_t *R_KEY,
-          gcry_sexp_t PARMS)
-     This function create a new public key pair using information given
-     in the S-expression PARMS and stores the private and the public key
-     in one new S-expression at the address given by R_KEY.  In case of
-     an error, R_KEY is set to `NULL'.  The return code is 0 for
-     success or an error code otherwise.
-
-     Here is an example for PARMS to create an 2048 bit RSA key:
-
-          (genkey
-            (rsa
-              (nbits 4:2048)))
-
-     To create an Elgamal key, substitute "elg" for "rsa" and to create
-     a DSA key use "dsa".  Valid ranges for the key length depend on the
-     algorithms; all commonly used key lengths are supported.  Currently
-     supported parameters are:
-
-    `nbits'
-          This is always required to specify the length of the key.  The
-          argument is a string with a number in C-notation.  The value
-          should be a multiple of 8.  Note that the S-expression syntax
-          requires that a number is prefixed with its string length;
-          thus the `4:' in the above example.
-
-    `curve NAME'
-          For ECC a named curve may be used instead of giving the
-          number of requested bits.  This allows to request a specific
-          curve to override a default selection Libgcrypt would have
-          taken if `nbits' has been given.  The available names are
-          listed with the description of the ECC public key parameters.
-
-    `rsa-use-e VALUE'
-          This is only used with RSA to give a hint for the public
-          exponent. The VALUE will be used as a base to test for a
-          usable exponent. Some values are special:
-
-         `0'
-               Use a secure and fast value.  This is currently the
-               number 41.
-
-         `1'
-               Use a value as required by some crypto policies.  This
-               is currently the number 65537.
-
-         `2'
-               Reserved
-
-         `> 2'
-               Use the given value.
-
-          If this parameter is not used, Libgcrypt uses for historic
-          reasons 65537.
-
-    `qbits N'
-          This is only meanigful for DSA keys.  If it is given the DSA
-          key is generated with a Q parameyer of size N bits.  If it is
-          not given or zero Q is deduced from NBITS in this way:
-         `512 <= N <= 1024'
-               Q = 160
-
-         `N = 2048'
-               Q = 224
-
-         `N = 3072'
-               Q = 256
-
-         `N = 7680'
-               Q = 384
-
-         `N = 15360'
-               Q = 512
-          Note that in this case only the values for N, as given in the
-          table, are allowed.  When specifying Q all values of N in the
-          range 512 to 15680 are valid as long as they are multiples of
-          8.
-
-    `domain LIST'
-          This is only meaningful for DLP algorithms.  If specified
-          keys are generated with domain parameters taken from this
-          list.  The exact format of this parameter depends on the
-          actual algorithm.  It is currently only implemented for DSA
-          using this format:
-
-               (genkey
-                 (dsa
-                   (domain
-                     (p P-MPI)
-                     (q Q-MPI)
-                     (g Q-MPI))))
-
-          `nbits' and `qbits' may not be specified because they are
-          derived from the domain parameters.
-
-    `derive-parms LIST'
-          This is currently only implemented for RSA and DSA keys.  It
-          is not allowed to use this together with a `domain'
-          specification.  If given, it is used to derive the keys using
-          the given parameters.
-
-          If given for an RSA key the X9.31 key generation algorithm is
-          used even if libgcrypt is not in FIPS mode.  If given for a
-          DSA key, the FIPS 186 algorithm is used even if libgcrypt is
-          not in FIPS mode.
-
-               (genkey
-                 (rsa
-                   (nbits 4:1024)
-                   (rsa-use-e 1:3)
-                   (derive-parms
-                     (Xp1 #1A1916DDB29B4EB7EB6732E128#)
-                     (Xp2 #192E8AAC41C576C822D93EA433#)
-                     (Xp  #D8CD81F035EC57EFE822955149D3BFF70C53520D
-                           769D6D76646C7A792E16EBD89FE6FC5B605A6493
-                           39DFC925A86A4C6D150B71B9EEA02D68885F5009
-                           B98BD984#)
-                     (Xq1 #1A5CF72EE770DE50CB09ACCEA9#)
-                     (Xq2 #134E4CAA16D2350A21D775C404#)
-                     (Xq  #CC1092495D867E64065DEE3E7955F2EBC7D47A2D
-                           7C9953388F97DDDC3E1CA19C35CA659EDC2FC325
-                           6D29C2627479C086A699A49C4C9CEE7EF7BD1B34
-                           321DE34A#))))
-
-               (genkey
-                 (dsa
-                   (nbits 4:1024)
-                   (derive-parms
-                     (seed SEED-MPI))))
-
-    `flags FLAGLIST'
-          This is preferred way to define flags.  FLAGLIST may contain
-          any number of flags.  See above for a specification of these
-          flags.
-
-          Here is an example on how to create a key using curve Ed25519
-          with the ECDSA signature algorithm.  Note that the use of
-          ECDSA with that curve is in general not recommended.
-               (genkey
-                 (ecc
-                   (flags transient-key)))
-
-    `transient-key'
-    `use-x931'
-    `use-fips186'
-    `use-fips186-2'
-          These are deprecated ways to set a flag with that name; see
-          above for a description of each flag.
-
-
-     The key pair is returned in a format depending on the algorithm.
-     Both private and public keys are returned in one container and may
-     be accompanied by some miscellaneous information.
-
-     Here are two examples; the first for Elgamal and the second for
-     elliptic curve key generation:
-
-          (key-data
-            (public-key
-              (elg
-                (p P-MPI)
-                (g G-MPI)
-                (y Y-MPI)))
-            (private-key
-              (elg
-                (p P-MPI)
-                (g G-MPI)
-                (y Y-MPI)
-                (x X-MPI)))
-            (misc-key-info
-              (pm1-factors N1 N2 ... NN))
-
-          (key-data
-            (public-key
-              (ecc
-                (curve Ed25519)
-                (flags eddsa)
-                (q Q-VALUE)))
-            (private-key
-              (ecc
-                (curve Ed25519)
-                (flags eddsa)
-                (q Q-VALUE)
-                (d D-VALUE))))
-
-     As you can see, some of the information is duplicated, but this
-     provides an easy way to extract either the public or the private
-     key.  Note that the order of the elements is not defined, e.g. the
-     private key may be stored before the public key. N1 N2 ... NN is a
-     list of prime numbers used to composite P-MPI; this is in general
-     not a very useful information and only available if the key
-     generation algorithm provides them.
-
-Future versions of Libgcrypt will have extended versions of the public
-key interfaced which will take an additional context to allow for
-pre-computations, special operations, and other optimization.  As a
-first step a new function is introduced to help using the ECC
-algorithms in new ways:
-
- -- Function: gcry_error_t gcry_pubkey_get_sexp (gcry_sexp_t *R_SEXP,
-          int MODE, gcry_ctx_t CTX)
-     Return an S-expression representing the context CTX.  Depending on
-     the state of that context, the S-expression may either be a public
-     key, a private key or any other object used with public key
-     operations.  On success 0 is returned and a new S-expression is
-     stored at R_SEXP; on error an error code is returned and NULL is
-     stored at R_SEXP.  MODE must be one of:
-
-    `0'
-          Decide what to return depending on the context.  For example
-          if the private key parameter is available a private key is
-          returned, if not a public key is returned.
-
-    `GCRY_PK_GET_PUBKEY'
-          Return the public key even if the context has the private key
-          parameter.
-
-    `GCRY_PK_GET_SECKEY'
-          Return the private key or the error `GPG_ERR_NO_SECKEY' if it
-          is not possible.
-
-     As of now this function supports only certain ECC operations
-     because a context object is right now only defined for ECC.  Over
-     time this function will be extended to cover more algorithms.
-
-
-\1f
-File: gcrypt.info,  Node: Hashing,  Next: Message Authentication Codes,  Prev: Public Key cryptography,  Up: Top
-
-7 Hashing
-*********
-
-Libgcrypt provides an easy and consistent to use interface for hashing.
-Hashing is buffered and several hash algorithms can be updated at once.
-It is possible to compute a HMAC using the same routines.  The
-programming model follows an open/process/close paradigm and is in that
-similar to other building blocks provided by Libgcrypt.
-
-   For convenience reasons, a few cyclic redundancy check value
-operations are also supported.
-
-* Menu:
-
-* Available hash algorithms::   List of hash algorithms supported by the library.
-* Working with hash algorithms::  List of functions related to hashing.
-
-\1f
-File: gcrypt.info,  Node: Available hash algorithms,  Next: Working with hash algorithms,  Up: Hashing
-
-7.1 Available hash algorithms
-=============================
-
-`GCRY_MD_NONE'
-     This is not a real algorithm but used by some functions as an error
-     return value.  This constant is guaranteed to have the value `0'.
-
-`GCRY_MD_SHA1'
-     This is the SHA-1 algorithm which yields a message digest of 20
-     bytes.  Note that SHA-1 begins to show some weaknesses and it is
-     suggested to fade out its use if strong cryptographic properties
-     are required.
-
-`GCRY_MD_RMD160'
-     This is the 160 bit version of the RIPE message digest
-     (RIPE-MD-160).  Like SHA-1 it also yields a digest of 20 bytes.
-     This algorithm share a lot of design properties with SHA-1 and
-     thus it is advisable not to use it for new protocols.
-
-`GCRY_MD_MD5'
-     This is the well known MD5 algorithm, which yields a message
-     digest of 16 bytes.  Note that the MD5 algorithm has severe
-     weaknesses, for example it is easy to compute two messages
-     yielding the same hash (collision attack).  The use of this
-     algorithm is only justified for non-cryptographic application.
-
-`GCRY_MD_MD4'
-     This is the MD4 algorithm, which yields a message digest of 16
-     bytes.  This algorithm has severe weaknesses and should not be
-     used.
-
-`GCRY_MD_MD2'
-     This is an reserved identifier for MD-2; there is no
-     implementation yet.  This algorithm has severe weaknesses and
-     should not be used.
-
-`GCRY_MD_TIGER'
-     This is the TIGER/192 algorithm which yields a message digest of 24
-     bytes.  Actually this is a variant of TIGER with a different output
-     print order as used by GnuPG up to version 1.3.2.
-
-`GCRY_MD_TIGER1'
-     This is the TIGER variant as used by the NESSIE project.  It uses
-     the most commonly used output print order.
-
-`GCRY_MD_TIGER2'
-     This is another variant of TIGER with a different padding scheme.
-
-`GCRY_MD_HAVAL'
-     This is an reserved value for the HAVAL algorithm with 5 passes
-     and 160 bit. It yields a message digest of 20 bytes.  Note that
-     there is no implementation yet available.
-
-`GCRY_MD_SHA224'
-     This is the SHA-224 algorithm which yields a message digest of 28
-     bytes.  See Change Notice 1 for FIPS 180-2 for the specification.
-
-`GCRY_MD_SHA256'
-     This is the SHA-256 algorithm which yields a message digest of 32
-     bytes.  See FIPS 180-2 for the specification.
-
-`GCRY_MD_SHA384'
-     This is the SHA-384 algorithm which yields a message digest of 48
-     bytes.  See FIPS 180-2 for the specification.
-
-`GCRY_MD_SHA512'
-     This is the SHA-384 algorithm which yields a message digest of 64
-     bytes.  See FIPS 180-2 for the specification.
-
-`GCRY_MD_CRC32'
-     This is the ISO 3309 and ITU-T V.42 cyclic redundancy check.  It
-     yields an output of 4 bytes.  Note that this is not a hash
-     algorithm in the cryptographic sense.
-
-`GCRY_MD_CRC32_RFC1510'
-     This is the above cyclic redundancy check function, as modified by
-     RFC 1510.  It yields an output of 4 bytes.  Note that this is not
-     a hash algorithm in the cryptographic sense.
-
-`GCRY_MD_CRC24_RFC2440'
-     This is the OpenPGP cyclic redundancy check function.  It yields an
-     output of 3 bytes.  Note that this is not a hash algorithm in the
-     cryptographic sense.
-
-`GCRY_MD_WHIRLPOOL'
-     This is the Whirlpool algorithm which yields a message digest of 64
-     bytes.
-
-`GCRY_MD_GOSTR3411_94'
-     This is the hash algorithm described in GOST R 34.11-94 which
-     yields a message digest of 32 bytes.
-
-`GCRY_MD_STRIBOG256'
-     This is the 256-bit version of hash algorithm described in GOST R
-     34.11-2012 which yields a message digest of 32 bytes.
-
-`GCRY_MD_STRIBOG512'
-     This is the 512-bit version of hash algorithm described in GOST R
-     34.11-2012 which yields a message digest of 64 bytes.
-
-
-\1f
-File: gcrypt.info,  Node: Working with hash algorithms,  Prev: Available hash algorithms,  Up: Hashing
-
-7.2 Working with hash algorithms
-================================
-
-To use most of these function it is necessary to create a context; this
-is done using:
-
- -- Function: gcry_error_t gcry_md_open (gcry_md_hd_t *HD, int ALGO,
-          unsigned int FLAGS)
-     Create a message digest object for algorithm ALGO.  FLAGS may be
-     given as an bitwise OR of constants described below.  ALGO may be
-     given as `0' if the algorithms to use are later set using
-     `gcry_md_enable'. HD is guaranteed to either receive a valid
-     handle or NULL.
-
-     For a list of supported algorithms, see *Note Available hash
-     algorithms::.
-
-     The flags allowed for MODE are:
-
-    `GCRY_MD_FLAG_SECURE'
-          Allocate all buffers and the resulting digest in "secure
-          memory".  Use this is the hashed data is highly confidential.
-
-    `GCRY_MD_FLAG_HMAC'
-          Turn the algorithm into a HMAC message authentication
-          algorithm.  This only works if just one algorithm is enabled
-          for the handle.  Note that the function `gcry_md_setkey' must
-          be used to set the MAC key.  The size of the MAC is equal to
-          the message digest of the underlying hash algorithm.  If you
-          want CBC message authentication codes based on a cipher, see
-          *Note Working with cipher handles::.
-
-    `GCRY_MD_FLAG_BUGEMU1'
-          Versions of Libgcrypt before 1.6.0 had a bug in the Whirlpool
-          code which led to a wrong result for certain input sizes and
-          write patterns.  Using this flag emulates that bug.  This may
-          for example be useful for applications which use Whirlpool as
-          part of their key generation.  It is strongly suggested to
-          use this flag only if really needed and if possible to the
-          data should be re-processed using the regular Whirlpool
-          algorithm.
-
-          Note that this flag works for the entire hash context.  If
-          needed arises it may be used to enable bug emulation for
-          other hash algorithms.  Thus you should not use this flag for
-          a multi-algorithm hash context.
-
-
-     You may use the function `gcry_md_is_enabled' to later check
-     whether an algorithm has been enabled.
-
-
-   If you want to calculate several hash algorithms at the same time,
-you have to use the following function right after the `gcry_md_open':
-
- -- Function: gcry_error_t gcry_md_enable (gcry_md_hd_t H, int ALGO)
-     Add the message digest algorithm ALGO to the digest object
-     described by handle H.  Duplicated enabling of algorithms is
-     detected and ignored.
-
-   If the flag `GCRY_MD_FLAG_HMAC' was used, the key for the MAC must
-be set using the function:
-
- -- Function: gcry_error_t gcry_md_setkey (gcry_md_hd_t H, const void
-          *KEY, size_t KEYLEN)
-     For use with the HMAC feature, set the MAC key to the value of KEY
-     of length KEYLEN bytes.  There is no restriction on the length of
-     the key.
-
-   After you are done with the hash calculation, you should release the
-resources by using:
-
- -- Function: void gcry_md_close (gcry_md_hd_t H)
-     Release all resources of hash context H.  H should not be used
-     after a call to this function.  A `NULL' passed as H is ignored.
-     The function also zeroises all sensitive information associated
-     with this handle.
-
-
-   Often you have to do several hash operations using the same
-algorithm.  To avoid the overhead of creating and releasing context, a
-reset function is provided:
-
- -- Function: void gcry_md_reset (gcry_md_hd_t H)
-     Reset the current context to its initial state.  This is
-     effectively identical to a close followed by an open and enabling
-     all currently active algorithms.
-
-   Often it is necessary to start hashing some data and then continue to
-hash different data.  To avoid hashing the same data several times
-(which might not even be possible if the data is received from a pipe),
-a snapshot of the current hash context can be taken and turned into a
-new context:
-
- -- Function: gcry_error_t gcry_md_copy (gcry_md_hd_t *HANDLE_DST,
-          gcry_md_hd_t HANDLE_SRC)
-     Create a new digest object as an exact copy of the object
-     described by handle HANDLE_SRC and store it in HANDLE_DST.  The
-     context is not reset and you can continue to hash data using this
-     context and independently using the original context.
-
-   Now that we have prepared everything to calculate hashes, it is time
-to see how it is actually done.  There are two ways for this, one to
-update the hash with a block of memory and one macro to update the hash
-by just one character.  Both methods can be used on the same hash
-context.
-
- -- Function: void gcry_md_write (gcry_md_hd_t H, const void *BUFFER,
-          size_t LENGTH)
-     Pass LENGTH bytes of the data in BUFFER to the digest object with
-     handle H to update the digest values. This function should be used
-     for large blocks of data.
-
- -- Function: void gcry_md_putc (gcry_md_hd_t H, int C)
-     Pass the byte in C to the digest object with handle H to update
-     the digest value.  This is an efficient function, implemented as a
-     macro to buffer the data before an actual update.
-
-   The semantics of the hash functions do not provide for reading out
-intermediate message digests because the calculation must be finalized
-first.  This finalization may for example include the number of bytes
-hashed in the message digest or some padding.
-
- -- Function: void gcry_md_final (gcry_md_hd_t H)
-     Finalize the message digest calculation.  This is not really needed
-     because `gcry_md_read' does this implicitly.  After this has been
-     done no further updates (by means of `gcry_md_write' or
-     `gcry_md_putc' are allowed.  Only the first call to this function
-     has an effect. It is implemented as a macro.
-
-   The way to read out the calculated message digest is by using the
-function:
-
- -- Function: unsigned char * gcry_md_read (gcry_md_hd_t H, int ALGO)
-     `gcry_md_read' returns the message digest after finalizing the
-     calculation.  This function may be used as often as required but
-     it will always return the same value for one handle.  The returned
-     message digest is allocated within the message context and
-     therefore valid until the handle is released or reseted (using
-     `gcry_md_close' or `gcry_md_reset'.  ALGO may be given as 0 to
-     return the only enabled message digest or it may specify one of
-     the enabled algorithms.  The function does return `NULL' if the
-     requested algorithm has not been enabled.
-
-   Because it is often necessary to get the message digest of blocks of
-memory, two fast convenience function are available for this task:
-
- -- Function: gpg_err_code_t gcry_md_hash_buffers ( int ALGO,
-          unsigned int FLAGS, void *DIGEST, const gcry_buffer_t *IOV,
-          int IOVCNT )
-     `gcry_md_hash_buffers' is a shortcut function to calculate a
-     message digest from several buffers.  This function does not
-     require a context and immediately returns the message digest of of
-     the data described by IOV and IOVCNT.  DIGEST must be allocated by
-     the caller, large enough to hold the message digest yielded by the
-     the specified algorithm ALGO.  This required size may be obtained
-     by using the function `gcry_md_get_algo_dlen'.
-
-     IOV is an array of buffer descriptions with IOVCNT items.  The
-     caller should zero out the structures in this array and for each
-     array item set the fields `.data' to the address of the data to be
-     hashed, `.len' to number of bytes to be hashed.  If .OFF is also
-     set, the data is taken starting at .OFF bytes from the begin of
-     the buffer.  The field `.size' is not used.
-
-     The only supported flag value for FLAGS is GCRY_MD_FLAG_HMAC which
-     turns this function into a HMAC function; the first item in IOV is
-     then used as the key.
-
-     On success the function returns 0 and stores the resulting hash or
-     MAC at DIGEST.
-
- -- Function: void gcry_md_hash_buffer (int ALGO, void *DIGEST, const
-          void *BUFFER, size_t LENGTH);
-     `gcry_md_hash_buffer' is a shortcut function to calculate a message
-     digest of a buffer.  This function does not require a context and
-     immediately returns the message digest of the LENGTH bytes at
-     BUFFER.  DIGEST must be allocated by the caller, large enough to
-     hold the message digest yielded by the the specified algorithm
-     ALGO.  This required size may be obtained by using the function
-     `gcry_md_get_algo_dlen'.
-
-     Note that in contrast to `gcry_md_hash_buffers' this function will
-     abort the process if an unavailable algorithm is used.
-
-   Hash algorithms are identified by internal algorithm numbers (see
-`gcry_md_open' for a list).  However, in most applications they are
-used by names, so two functions are available to map between string
-representations and hash algorithm identifiers.
-
- -- Function: const char * gcry_md_algo_name (int ALGO)
-     Map the digest algorithm id ALGO to a string representation of the
-     algorithm name.  For unknown algorithms this function returns the
-     string `"?"'.  This function should not be used to test for the
-     availability of an algorithm.
-
- -- Function: int gcry_md_map_name (const char *NAME)
-     Map the algorithm with NAME to a digest algorithm identifier.
-     Returns 0 if the algorithm name is not known.  Names representing
-     ASN.1 object identifiers are recognized if the IETF dotted format
-     is used and the OID is prefixed with either "`oid.'" or "`OID.'".
-     For a list of supported OIDs, see the source code at
-     `cipher/md.c'. This function should not be used to test for the
-     availability of an algorithm.
-
- -- Function: gcry_error_t gcry_md_get_asnoid (int ALGO, void *BUFFER,
-          size_t *LENGTH)
-     Return an DER encoded ASN.1 OID for the algorithm ALGO in the user
-     allocated BUFFER. LENGTH must point to variable with the available
-     size of BUFFER and receives after return the actual size of the
-     returned OID.  The returned error code may be `GPG_ERR_TOO_SHORT'
-     if the provided buffer is to short to receive the OID; it is
-     possible to call the function with `NULL' for BUFFER to have it
-     only return the required size.  The function returns 0 on success.
-
-
-   To test whether an algorithm is actually available for use, the
-following macro should be used:
-
- -- Function: gcry_error_t gcry_md_test_algo (int ALGO)
-     The macro returns 0 if the algorithm ALGO is available for use.
-
-   If the length of a message digest is not known, it can be retrieved
-using the following function:
-
- -- Function: unsigned int gcry_md_get_algo_dlen (int ALGO)
-     Retrieve the length in bytes of the digest yielded by algorithm
-     ALGO.  This is often used prior to `gcry_md_read' to allocate
-     sufficient memory for the digest.
-
-   In some situations it might be hard to remember the algorithm used
-for the ongoing hashing. The following function might be used to get
-that information:
-
- -- Function: int gcry_md_get_algo (gcry_md_hd_t H)
-     Retrieve the algorithm used with the handle H.  Note that this
-     does not work reliable if more than one algorithm is enabled in H.
-
-   The following macro might also be useful:
-
- -- Function: int gcry_md_is_secure (gcry_md_hd_t H)
-     This function returns true when the digest object H is allocated
-     in "secure memory"; i.e. H was created with the
-     `GCRY_MD_FLAG_SECURE'.
-
- -- Function: int gcry_md_is_enabled (gcry_md_hd_t H, int ALGO)
-     This function returns true when the algorithm ALGO has been
-     enabled for the digest object H.
-
-   Tracking bugs related to hashing is often a cumbersome task which
-requires to add a lot of printf statements into the code.  Libgcrypt
-provides an easy way to avoid this.  The actual data hashed can be
-written to files on request.
-
- -- Function: void gcry_md_debug (gcry_md_hd_t H, const char *SUFFIX)
-     Enable debugging for the digest object with handle H.  This
-     creates create files named `dbgmd-<n>.<string>' while doing the
-     actual hashing.  SUFFIX is the string part in the filename.  The
-     number is a counter incremented for each new hashing.  The data in
-     the file is the raw data as passed to `gcry_md_write' or
-     `gcry_md_putc'.  If `NULL' is used for SUFFIX, the debugging is
-     stopped and the file closed.  This is only rarely required because
-     `gcry_md_close' implicitly stops debugging.
-
-\1f
-File: gcrypt.info,  Node: Message Authentication Codes,  Next: Key Derivation,  Prev: Hashing,  Up: Top
-
-8 Message Authentication Codes
-******************************
-
-Libgcrypt provides an easy and consistent to use interface for
-generating Message Authentication Codes (MAC). MAC generation is
-buffered and interface similar to the one used with hash algorithms.
-The programming model follows an open/process/close paradigm and is in
-that similar to other building blocks provided by Libgcrypt.
-
-* Menu:
-
-* Available MAC algorithms::   List of MAC algorithms supported by the library.
-* Working with MAC algorithms::  List of functions related to MAC algorithms.
-
-\1f
-File: gcrypt.info,  Node: Available MAC algorithms,  Next: Working with MAC algorithms,  Up: Message Authentication Codes
-
-8.1 Available MAC algorithms
-============================
-
-`GCRY_MAC_NONE'
-     This is not a real algorithm but used by some functions as an error
-     return value.  This constant is guaranteed to have the value `0'.
-
-`GCRY_MAC_HMAC_SHA256'
-     This is keyed-hash message authentication code (HMAC) message
-     authentication algorithm based on the SHA-256 hash algorithm.
-
-`GCRY_MAC_HMAC_SHA224'
-     This is HMAC message authentication algorithm based on the SHA-224
-     hash algorithm.
-
-`GCRY_MAC_HMAC_SHA512'
-     This is HMAC message authentication algorithm based on the SHA-512
-     hash algorithm.
-
-`GCRY_MAC_HMAC_SHA384'
-     This is HMAC message authentication algorithm based on the SHA-384
-     hash algorithm.
-
-`GCRY_MAC_HMAC_SHA1'
-     This is HMAC message authentication algorithm based on the SHA-1
-     hash algorithm.
-
-`GCRY_MAC_HMAC_MD5'
-     This is HMAC message authentication algorithm based on the MD5 hash
-     algorithm.
-
-`GCRY_MAC_HMAC_MD4'
-     This is HMAC message authentication algorithm based on the MD4 hash
-     algorithm.
-
-`GCRY_MAC_HMAC_RMD160'
-     This is HMAC message authentication algorithm based on the
-     RIPE-MD-160 hash algorithm.
-
-`GCRY_MAC_HMAC_WHIRLPOOL'
-     This is HMAC message authentication algorithm based on the
-     WHIRLPOOL hash algorithm.
-
-`GCRY_MAC_HMAC_GOSTR3411_94'
-     This is HMAC message authentication algorithm based on the GOST R
-     34.11-94 hash algorithm.
-
-`GCRY_MAC_HMAC_STRIBOG256'
-     This is HMAC message authentication algorithm based on the 256-bit
-     hash algorithm described in GOST R 34.11-2012.
-
-`GCRY_MAC_HMAC_STRIBOG512'
-     This is HMAC message authentication algorithm based on the 512-bit
-     hash algorithm described in GOST R 34.11-2012.
-
-`GCRY_MAC_CMAC_AES'
-     This is CMAC (Cipher-based MAC) message authentication algorithm
-     based on the AES block cipher algorithm.
-
-`GCRY_MAC_CMAC_3DES'
-     This is CMAC message authentication algorithm based on the
-     three-key EDE Triple-DES block cipher algorithm.
-
-`GCRY_MAC_CMAC_CAMELLIA'
-     This is CMAC message authentication algorithm based on the
-     Camellia block cipher algorithm.
-
-`GCRY_MAC_CMAC_CAST5'
-     This is CMAC message authentication algorithm based on the
-     CAST128-5 block cipher algorithm.
-
-`GCRY_MAC_CMAC_BLOWFISH'
-     This is CMAC message authentication algorithm based on the Blowfish
-     block cipher algorithm.
-
-`GCRY_MAC_CMAC_TWOFISH'
-     This is CMAC message authentication algorithm based on the Twofish
-     block cipher algorithm.
-
-`GCRY_MAC_CMAC_SERPENT'
-     This is CMAC message authentication algorithm based on the Serpent
-     block cipher algorithm.
-
-`GCRY_MAC_CMAC_SEED'
-     This is CMAC message authentication algorithm based on the SEED
-     block cipher algorithm.
-
-`GCRY_MAC_CMAC_RFC2268'
-     This is CMAC message authentication algorithm based on the Ron's
-     Cipher 2 block cipher algorithm.
-
-`GCRY_MAC_CMAC_IDEA'
-     This is CMAC message authentication algorithm based on the IDEA
-     block cipher algorithm.
-
-`GCRY_MAC_CMAC_GOST28147'
-     This is CMAC message authentication algorithm based on the GOST
-     28147-89 block cipher algorithm.
-
-`GCRY_MAC_GMAC_AES'
-     This is GMAC (GCM mode based MAC) message authentication algorithm
-     based on the AES block cipher algorithm.
-
-`GCRY_MAC_GMAC_CAMELLIA'
-     This is GMAC message authentication algorithm based on the Camellia
-     block cipher algorithm.
-
-`GCRY_MAC_GMAC_TWOFISH'
-     This is GMAC message authentication algorithm based on the Twofish
-     block cipher algorithm.
-
-`GCRY_MAC_GMAC_SERPENT'
-     This is GMAC message authentication algorithm based on the Serpent
-     block cipher algorithm.
-
-`GCRY_MAC_GMAC_SEED'
-     This is GMAC message authentication algorithm based on the SEED
-     block cipher algorithm.
-
-
-\1f
-File: gcrypt.info,  Node: Working with MAC algorithms,  Prev: Available MAC algorithms,  Up: Message Authentication Codes
-
-8.2 Working with MAC algorithms
-===============================
-
-To use most of these function it is necessary to create a context; this
-is done using:
-
- -- Function: gcry_error_t gcry_mac_open (gcry_mac_hd_t *HD, int ALGO,
-          unsigned int FLAGS, gcry_ctx_t CTX)
-     Create a MAC object for algorithm ALGO. FLAGS may be given as an
-     bitwise OR of constants described below. HD is guaranteed to either
-     receive a valid handle or NULL. CTX is context object to associate
-     MAC object with. CTX maybe set to NULL.
-
-     For a list of supported algorithms, see *Note Available MAC
-     algorithms::.
-
-     The flags allowed for MODE are:
-
-    `GCRY_MAC_FLAG_SECURE'
-          Allocate all buffers and the resulting MAC in "secure
-          memory".  Use this if the MAC data is highly confidential.
-
-
-
-   In order to use a handle for performing MAC algorithm operations, a
-`key' has to be set first:
-
- -- Function: gcry_error_t gcry_mac_setkey (gcry_mac_hd_t H, const void
-          *KEY, size_t KEYLEN)
-     Set the MAC key to the value of KEY of length KEYLEN bytes. With
-     HMAC algorithms, there is no restriction on the length of the key.
-     With CMAC algorithms, the length of the key is restricted to those
-     supported by the underlying block cipher.
-
-   GMAC algorithms need initialization vector to be set, which can be
-performed with function:
-
- -- Function: gcry_error_t gcry_mac_setiv (gcry_mac_hd_t H, const void
-          *IV, size_t IVLEN)
-     Set the IV to the value of IV of length IVLEN bytes.
-
-   After you are done with the MAC calculation, you should release the
-resources by using:
-
- -- Function: void gcry_mac_close (gcry_mac_hd_t H)
-     Release all resources of MAC context H.  H should not be used
-     after a call to this function.  A `NULL' passed as H is ignored.
-     The function also clears all sensitive information associated with
-     this handle.
-
-   Often you have to do several MAC operations using the same algorithm.
-To avoid the overhead of creating and releasing context, a reset
-function is provided:
-
- -- Function: gcry_error_t gcry_mac_reset (gcry_mac_hd_t H)
-     Reset the current context to its initial state. This is
-     effectively identical to a close followed by an open and setting
-     same key.
-
-     Note that gcry_mac_reset is implemented as a macro.
-
-   Now that we have prepared everything to calculate MAC, it is time to
-see how it is actually done.
-
- -- Function: gcry_error_t gcry_mac_write (gcry_mac_hd_t H, const void
-          *BUFFER, size_t LENGTH)
-     Pass LENGTH bytes of the data in BUFFER to the MAC object with
-     handle H to update the MAC values.
-
-   The way to read out the calculated MAC is by using the function:
-
- -- Function: gcry_error_t gcry_mac_read (gcry_mac_hd_t H, void
-          *BUFFER, size_t *LENGTH)
-     `gcry_mac_read' returns the MAC after finalizing the calculation.
-     Function copies the resulting MAC value to BUFFER of the length
-     LENGTH. If LENGTH is larger than length of resulting MAC value,
-     then length of MAC is returned through LENGTH.
-
-   To compare existing MAC value with recalculated MAC, one is to use
-the function:
-
- -- Function: gcry_error_t gcry_mac_verify (gcry_mac_hd_t H, void
-          *BUFFER, size_t LENGTH)
-     `gcry_mac_verify' finalizes MAC calculation and compares result
-     with LENGTH bytes of data in BUFFER. Error code `GPG_ERR_CHECKSUM'
-     is returned if the MAC value in the buffer BUFFER does not match
-     the MAC calculated in object H.
-
-   MAC algorithms are identified by internal algorithm numbers (see
-`gcry_mac_open' for a list).  However, in most applications they are
-used by names, so two functions are available to map between string
-representations and MAC algorithm identifiers.
-
- -- Function: const char * gcry_mac_algo_name (int ALGO)
-     Map the MAC algorithm id ALGO to a string representation of the
-     algorithm name.  For unknown algorithms this function returns the
-     string `"?"'.  This function should not be used to test for the
-     availability of an algorithm.
-
- -- Function: int gcry_mac_map_name (const char *NAME)
-     Map the algorithm with NAME to a MAC algorithm identifier.
-     Returns 0 if the algorithm name is not known. This function should
-     not be used to test for the availability of an algorithm.
-
-   To test whether an algorithm is actually available for use, the
-following macro should be used:
-
- -- Function: gcry_error_t gcry_mac_test_algo (int ALGO)
-     The macro returns 0 if the MAC algorithm ALGO is available for use.
-
-   If the length of a message digest is not known, it can be retrieved
-using the following function:
-
- -- Function: unsigned int gcry_mac_get_algo_maclen (int ALGO)
-     Retrieve the length in bytes of the MAC yielded by algorithm ALGO.
-     This is often used prior to `gcry_mac_read' to allocate sufficient
-     memory for the MAC value. On error `0' is returned.
-
- -- Function: unsigned int gcry_mac_get_algo_keylen (ALGO)
-     This function returns length of the key for MAC algorithm ALGO.  If
-     the algorithm supports multiple key lengths, the default supported
-     key length is returned.  On error `0' is returned.  The key length
-     is returned as number of octets.
-
-\1f
-File: gcrypt.info,  Node: Key Derivation,  Next: Random Numbers,  Prev: Message Authentication Codes,  Up: Top
-
-9 Key Derivation
-****************
-
-Libgcypt provides a general purpose function to derive keys from
-strings.
-
- -- Function: gpg_error_t gcry_kdf_derive ( const void *PASSPHRASE,
-          size_t PASSPHRASELEN, int ALGO, int SUBALGO,
-          const void *SALT, size_t SALTLEN, unsigned long ITERATIONS,
-          size_t KEYSIZE, void *KEYBUFFER )
-     Derive a key from a passphrase.  KEYSIZE gives the requested size
-     of the keys in octets.  KEYBUFFER is a caller provided buffer
-     filled on success with the derived key.  The input passphrase is
-     taken from PASSPHRASE which is an arbitrary memory buffer of
-     PASSPHRASELEN octets.  ALGO specifies the KDF algorithm to use;
-     see below.  SUBALGO specifies an algorithm used internally by the
-     KDF algorithms; this is usually a hash algorithm but certain KDF
-     algorithms may use it differently.  SALT is a salt of length
-     SALTLEN octets, as needed by most KDF algorithms.  ITERATIONS is a
-     positive integer parameter to most KDFs.
-
-     On success 0 is returned; on failure an error code.
-
-     Currently supported KDFs (parameter ALGO):
-
-    `GCRY_KDF_SIMPLE_S2K'
-          The OpenPGP simple S2K algorithm (cf. RFC4880).  Its use is
-          strongly deprecated.  SALT and ITERATIONS are not needed and
-          may be passed as `NULL'/`0'.
-
-    `GCRY_KDF_SALTED_S2K'
-          The OpenPGP salted S2K algorithm (cf. RFC4880).  Usually not
-          used.  ITERATIONS is not needed and may be passed as `0'.
-          SALTLEN must be given as 8.
-
-    `GCRY_KDF_ITERSALTED_S2K'
-          The OpenPGP iterated+salted S2K algorithm (cf. RFC4880).
-          This is the default for most OpenPGP applications.  SALTLEN
-          must be given as 8.  Note that OpenPGP defines a special
-          encoding of the ITERATIONS; however this function takes the
-          plain decoded iteration count.
-
-    `GCRY_KDF_PBKDF2'
-          The PKCS#5 Passphrase Based Key Derivation Function number 2.
-
-    `GCRY_KDF_SCRYPT'
-          The SCRYPT Key Derivation Function.  The subalgorithm is used
-          to specify the CPU/memory cost parameter N, and the number of
-          iterations is used for the parallelization parameter p.  The
-          block size is fixed at 8 in the current implementation.
-
-
-\1f
-File: gcrypt.info,  Node: Random Numbers,  Next: S-expressions,  Prev: Key Derivation,  Up: Top
-
-10 Random Numbers
-*****************
-
-* Menu:
-
-* Quality of random numbers::   Libgcrypt uses different quality levels.
-* Retrieving random numbers::   How to retrieve random numbers.
-
-\1f
-File: gcrypt.info,  Node: Quality of random numbers,  Next: Retrieving random numbers,  Up: Random Numbers
-
-10.1 Quality of random numbers
-==============================
-
-Libgcypt offers random numbers of different quality levels:
-
- -- Data type: gcry_random_level_t
-     The constants for the random quality levels are of this enum type.
-
-`GCRY_WEAK_RANDOM'
-     For all functions, except for `gcry_mpi_randomize', this level maps
-     to GCRY_STRONG_RANDOM.  If you do not want this, consider using
-     `gcry_create_nonce'.
-
-`GCRY_STRONG_RANDOM'
-     Use this level for session keys and similar purposes.
-
-`GCRY_VERY_STRONG_RANDOM'
-     Use this level for long term key material.
-
-\1f
-File: gcrypt.info,  Node: Retrieving random numbers,  Prev: Quality of random numbers,  Up: Random Numbers
-
-10.2 Retrieving random numbers
-==============================
-
- -- Function: void gcry_randomize (unsigned char *BUFFER, size_t
-          LENGTH, enum gcry_random_level LEVEL)
-     Fill BUFFER with LENGTH random bytes using a random quality as
-     defined by LEVEL.
-
- -- Function: void * gcry_random_bytes (size_t NBYTES, enum
-          gcry_random_level LEVEL)
-     Convenience function to allocate a memory block consisting of
-     NBYTES fresh random bytes using a random quality as defined by
-     LEVEL.
-
- -- Function: void * gcry_random_bytes_secure (size_t NBYTES, enum
-          gcry_random_level LEVEL)
-     Convenience function to allocate a memory block consisting of
-     NBYTES fresh random bytes using a random quality as defined by
-     LEVEL.  This function differs from `gcry_random_bytes' in that the
-     returned buffer is allocated in a "secure" area of the memory.
-
- -- Function: void gcry_create_nonce (unsigned char *BUFFER, size_t
-          LENGTH)
-     Fill BUFFER with LENGTH unpredictable bytes.  This is commonly
-     called a nonce and may also be used for initialization vectors and
-     padding.  This is an extra function nearly independent of the
-     other random function for 3 reasons: It better protects the
-     regular random generator's internal state, provides better
-     performance and does not drain the precious entropy pool.
-
-
-\1f
-File: gcrypt.info,  Node: S-expressions,  Next: MPI library,  Prev: Random Numbers,  Up: Top
-
-11 S-expressions
-****************
-
-S-expressions are used by the public key functions to pass complex data
-structures around.  These LISP like objects are used by some
-cryptographic protocols (cf. RFC-2692) and Libgcrypt provides functions
-to parse and construct them.  For detailed information, see `Ron
-Rivest, code and description of S-expressions,
-`http://theory.lcs.mit.edu/~rivest/sexp.html''.
-
-* Menu:
-
-* Data types for S-expressions::  Data types related with S-expressions.
-* Working with S-expressions::  How to work with S-expressions.
-
-\1f
-File: gcrypt.info,  Node: Data types for S-expressions,  Next: Working with S-expressions,  Up: S-expressions
-
-11.1 Data types for S-expressions
-=================================
-
- -- Data type: gcry_sexp_t
-     The `gcry_sexp_t' type describes an object with the Libgcrypt
-     internal representation of an S-expression.
-
-\1f
-File: gcrypt.info,  Node: Working with S-expressions,  Prev: Data types for S-expressions,  Up: S-expressions
-
-11.2 Working with S-expressions
-===============================
-
-There are several functions to create an Libgcrypt S-expression object
-from its external representation or from a string template.  There is
-also a function to convert the internal representation back into one of
-the external formats:
-
- -- Function: gcry_error_t gcry_sexp_new (gcry_sexp_t *R_SEXP,
-          const void *BUFFER, size_t LENGTH, int AUTODETECT)
-     This is the generic function to create an new S-expression object
-     from its external representation in BUFFER of LENGTH bytes.  On
-     success the result is stored at the address given by R_SEXP.  With
-     AUTODETECT set to 0, the data in BUFFER is expected to be in
-     canonized format, with AUTODETECT set to 1 the parses any of the
-     defined external formats.  If BUFFER does not hold a valid
-     S-expression an error code is returned and R_SEXP set to `NULL'.
-     Note that the caller is responsible for releasing the newly
-     allocated S-expression using `gcry_sexp_release'.
-
- -- Function: gcry_error_t gcry_sexp_create (gcry_sexp_t *R_SEXP,
-          void *BUFFER, size_t LENGTH, int AUTODETECT,
-          void (*FREEFNC)(void*))
-     This function is identical to `gcry_sexp_new' but has an extra
-     argument FREEFNC, which, when not set to `NULL', is expected to be
-     a function to release the BUFFER; most likely the standard `free'
-     function is used for this argument.  This has the effect of
-     transferring the ownership of BUFFER to the created object in
-     R_SEXP.  The advantage of using this function is that Libgcrypt
-     might decide to directly use the provided buffer and thus avoid
-     extra copying.
-
- -- Function: gcry_error_t gcry_sexp_sscan (gcry_sexp_t *R_SEXP,
-          size_t *ERROFF, const char *BUFFER, size_t LENGTH)
-     This is another variant of the above functions.  It behaves nearly
-     identical but provides an ERROFF argument which will receive the
-     offset into the buffer where the parsing stopped on error.
-
- -- Function: gcry_error_t gcry_sexp_build (gcry_sexp_t *R_SEXP,
-          size_t *ERROFF, const char *FORMAT, ...)
-     This function creates an internal S-expression from the string
-     template FORMAT and stores it at the address of R_SEXP. If there
-     is a parsing error, the function returns an appropriate error code
-     and stores the offset into FORMAT where the parsing stopped in
-     ERROFF.  The function supports a couple of printf-like formatting
-     characters and expects arguments for some of these escape
-     sequences right after FORMAT.  The following format characters are
-     defined:
-
-    `%m'
-          The next argument is expected to be of type `gcry_mpi_t' and
-          a copy of its value is inserted into the resulting
-          S-expression.  The MPI is stored as a signed integer.
-
-    `%M'
-          The next argument is expected to be of type `gcry_mpi_t' and
-          a copy of its value is inserted into the resulting
-          S-expression.  The MPI is stored as an unsigned integer.
-
-    `%s'
-          The next argument is expected to be of type `char *' and that
-          string is inserted into the resulting S-expression.
-
-    `%d'
-          The next argument is expected to be of type `int' and its
-          value is inserted into the resulting S-expression.
-
-    `%u'
-          The next argument is expected to be of type `unsigned int' and
-          its value is inserted into the resulting S-expression.
-
-    `%b'
-          The next argument is expected to be of type `int' directly
-          followed by an argument of type `char *'.  This represents a
-          buffer of given length to be inserted into the resulting
-          S-expression.
-
-    `%S'
-          The next argument is expected to be of type `gcry_sexp_t' and
-          a copy of that S-expression is embedded in the resulting
-          S-expression.  The argument needs to be a regular
-          S-expression, starting with a parenthesis.
-
-
-     No other format characters are defined and would return an error.
-     Note that the format character `%%' does not exists, because a
-     percent sign is not a valid character in an S-expression.
-
- -- Function: void gcry_sexp_release (gcry_sexp_t SEXP)
-     Release the S-expression object SEXP.  If the S-expression is
-     stored in secure memory it explicitly zeroises that memory; note
-     that this is done in addition to the zeroisation always done when
-     freeing secure memory.
-
-The next 2 functions are used to convert the internal representation
-back into a regular external S-expression format and to show the
-structure for debugging.
-
- -- Function: size_t gcry_sexp_sprint (gcry_sexp_t SEXP, int MODE,
-          char *BUFFER, size_t MAXLENGTH)
-     Copies the S-expression object SEXP into BUFFER using the format
-     specified in MODE.  MAXLENGTH must be set to the allocated length
-     of BUFFER.  The function returns the actual length of valid bytes
-     put into BUFFER or 0 if the provided buffer is too short.  Passing
-     `NULL' for BUFFER returns the required length for BUFFER.  For
-     convenience reasons an extra byte with value 0 is appended to the
-     buffer.
-
-     The following formats are supported:
-
-    `GCRYSEXP_FMT_DEFAULT'
-          Returns a convenient external S-expression representation.
-
-    `GCRYSEXP_FMT_CANON'
-          Return the S-expression in canonical format.
-
-    `GCRYSEXP_FMT_BASE64'
-          Not currently supported.
-
-    `GCRYSEXP_FMT_ADVANCED'
-          Returns the S-expression in advanced format.
-
- -- Function: void gcry_sexp_dump (gcry_sexp_t SEXP)
-     Dumps SEXP in a format suitable for debugging to Libgcrypt's
-     logging stream.
-
-Often canonical encoding is used in the external representation.  The
-following function can be used to check for valid encoding and to learn
-the length of the S-expression"
-
- -- Function: size_t gcry_sexp_canon_len (const unsigned char *BUFFER,
-          size_t LENGTH, size_t *ERROFF, int *ERRCODE)
-     Scan the canonical encoded BUFFER with implicit length values and
-     return the actual length this S-expression uses.  For a valid
-     S-expression it should never return 0.  If LENGTH is not 0, the
-     maximum length to scan is given; this can be used for syntax
-     checks of data passed from outside.  ERRCODE and ERROFF may both be
-     passed as `NULL'.
-
-
-There are functions to parse S-expressions and retrieve elements:
-
- -- Function: gcry_sexp_t gcry_sexp_find_token (const gcry_sexp_t LIST,
-          const char *TOKEN, size_t TOKLEN)
-     Scan the S-expression for a sublist with a type (the car of the
-     list) matching the string TOKEN.  If TOKLEN is not 0, the token is
-     assumed to be raw memory of this length.  The function returns a
-     newly allocated S-expression consisting of the found sublist or
-     `NULL' when not found.
-
- -- Function: int gcry_sexp_length (const gcry_sexp_t LIST)
-     Return the length of the LIST.  For a valid S-expression this
-     should be at least 1.
-
- -- Function: gcry_sexp_t gcry_sexp_nth (const gcry_sexp_t LIST,
-          int NUMBER)
-     Create and return a new S-expression from the element with index
-     NUMBER in LIST.  Note that the first element has the index 0.  If
-     there is no such element, `NULL' is returned.
-
- -- Function: gcry_sexp_t gcry_sexp_car (const gcry_sexp_t LIST)
-     Create and return a new S-expression from the first element in
-     LIST; this is called the "type" and should always exist per
-     S-expression specification and in general be a string.  `NULL' is
-     returned in case of a problem.
-
- -- Function: gcry_sexp_t gcry_sexp_cdr (const gcry_sexp_t LIST)
-     Create and return a new list form all elements except for the
-     first one.  Note that this function may return an invalid
-     S-expression because it is not guaranteed, that the type exists
-     and is a string.  However, for parsing a complex S-expression it
-     might be useful for intermediate lists.  Returns `NULL' on error.
-
- -- Function: const char * gcry_sexp_nth_data (const gcry_sexp_t LIST,
-          int NUMBER, size_t *DATALEN)
-     This function is used to get data from a LIST.  A pointer to the
-     actual data with index NUMBER is returned and the length of this
-     data will be stored to DATALEN.  If there is no data at the given
-     index or the index represents another list, `NULL' is returned.
-     *Caution:* The returned pointer is valid as long as LIST is not
-     modified or released.
-
-     Here is an example on how to extract and print the surname (Meier)
-     from the S-expression `(Name Otto Meier (address Burgplatz 3))':
-
-          size_t len;
-          const char *name;
-
-          name = gcry_sexp_nth_data (list, 2, &len);
-          printf ("my name is %.*s\n", (int)len, name);
-
- -- Function: void * gcry_sexp_nth_buffer (const gcry_sexp_t LIST,
-          int NUMBER, size_t *RLENGTH)
-     This function is used to get data from a LIST.  A malloced buffer
-     with the actual data at list index NUMBER is returned and the
-     length of this buffer will be stored to RLENGTH.  If there is no
-     data at the given index or the index represents another list,
-     `NULL' is returned.  The caller must release the result using
-     `gcry_free'.
-
-     Here is an example on how to extract and print the CRC value from
-     the S-expression `(hash crc32 #23ed00d7)':
-
-          size_t len;
-          char *value;
-
-          value = gcry_sexp_nth_buffer (list, 2, &len);
-          if (value)
-            fwrite (value, len, 1, stdout);
-          gcry_free (value);
-
- -- Function: char * gcry_sexp_nth_string (gcry_sexp_t LIST, int NUMBER)
-     This function is used to get and convert data from a LIST. The
-     data is assumed to be a Nul terminated string.  The caller must
-     release this returned value using `gcry_free'.  If there is no
-     data at the given index, the index represents a list or the value
-     can't be converted to a string, `NULL' is returned.
-
- -- Function: gcry_mpi_t gcry_sexp_nth_mpi (gcry_sexp_t LIST,
-          int NUMBER, int MPIFMT)
-     This function is used to get and convert data from a LIST. This
-     data is assumed to be an MPI stored in the format described by
-     MPIFMT and returned as a standard Libgcrypt MPI.  The caller must
-     release this returned value using `gcry_mpi_release'.  If there is
-     no data at the given index, the index represents a list or the
-     value can't be converted to an MPI, `NULL' is returned.  If you use
-     this function to parse results of a public key function, you most
-     likely want to use `GCRYMPI_FMT_USG'.
-
- -- Function: gpg_error_t gcry_sexp_extract_param ( gcry_sexp_t SEXP,
-          const char *PATH, const char *LIST, ...)
-     Extract parameters from an S-expression using a list of parameter
-     names.  The names of these parameters are specified in LIST.  White
-     space between the parameter names are ignored. Some special
-     characters may be given to control the conversion:
-
-    `+'
-          Switch to unsigned integer format (GCRYMPI_FMT_USG).  This is
-          the default mode.
-
-    `-'
-          Switch to standard signed format (GCRYMPI_FMT_STD).
-
-    `/'
-          Switch to opaque MPI format.  The resulting MPIs may not be
-          used for computations; see `gcry_mpi_get_opaque' for details.
-
-    `&'
-          Switch to buffer descriptor mode.  See below for details.
-
-    `?'
-          If immediately following a parameter letter (no white space
-          allowed), that parameter is considered optional.
-
-     In general parameter names are single letters.  To use a string
-     for a parameter name, enclose the name in single quotes.
-
-     Unless in buffer descriptor mode for each parameter name a pointer
-     to an `gcry_mpi_t' variable is expected finally followed by a
-     `NULL'.  For example
-            _gcry_sexp_extract_param (key, NULL, "n/x+e d-'foo'",
-                                      &mpi_n, &mpi_x, &mpi_e, &mpi_foo, NULL)
-
-     stores the parameter 'n' from KEY as an unsigned MPI into MPI_N,
-     the parameter 'x' as an opaque MPI into MPI_X, the parameter 'e'
-     again as an unsigned MPI into MPI_E, and the parameter 'foo' as a
-     signed MPI.
-
-     PATH is an optional string used to locate a token.  The
-     exclamation mark separated tokens are used via
-     `gcry_sexp_find_token' to find a start point inside the
-     S-expression.
-
-     In buffer descriptor mode a pointer to a `gcry_buffer_t'
-     descriptor is expected instead of a pointer to an MPI.  The caller
-     may use two different operation modes here: If the DATA field of
-     the provided descriptor is `NULL', the function allocates a new
-     buffer and stores it at DATA; the other fields are set accordingly
-     with OFF set to 0.  If DATA is not `NULL', the function assumes
-     that the DATA, SIZE, and OFF fields specify a buffer where to but
-     the value of the respective parameter; on return the LEN field
-     receives the number of bytes copied to that buffer; in case the
-     buffer is too small, the function immediately returns with an
-     error code (and LEN is set to 0).
-
-     The function returns NULL on success.  On error an error code is
-     returned and the passed MPIs are either unchanged or set to NULL.
-
-\1f
-File: gcrypt.info,  Node: MPI library,  Next: Prime numbers,  Prev: S-expressions,  Up: Top
-
-12 MPI library
-**************
-
-* Menu:
-
-* Data types::                  MPI related data types.
-* Basic functions::             First steps with MPI numbers.
-* MPI formats::                 External representation of MPIs.
-* Calculations::                Performing MPI calculations.
-* Comparisons::                 How to compare MPI values.
-* Bit manipulations::           How to access single bits of MPI values.
-* EC functions::                Elliptic curve related functions.
-* Miscellaneous::               Miscellaneous MPI functions.
-
-   Public key cryptography is based on mathematics with large numbers.
-To implement the public key functions, a library for handling these
-large numbers is required.  Because of the general usefulness of such a
-library, its interface is exposed by Libgcrypt.  In the context of
-Libgcrypt and in most other applications, these large numbers are
-called MPIs (multi-precision-integers).
-
-\1f
-File: gcrypt.info,  Node: Data types,  Next: Basic functions,  Up: MPI library
-
-12.1 Data types
-===============
-
- -- Data type: gcry_mpi_t
-     This type represents an object to hold an MPI.
-
- -- Data type: gcry_mpi_point_t
-     This type represents an object to hold a point for elliptic curve
-     math.
-
-\1f
-File: gcrypt.info,  Node: Basic functions,  Next: MPI formats,  Prev: Data types,  Up: MPI library
-
-12.2 Basic functions
-====================
-
-To work with MPIs, storage must be allocated and released for the
-numbers.  This can be done with one of these functions:
-
- -- Function: gcry_mpi_t gcry_mpi_new (unsigned int NBITS)
-     Allocate a new MPI object, initialize it to 0 and initially
-     allocate enough memory for a number of at least NBITS.  This
-     pre-allocation is only a small performance issue and not actually
-     necessary because Libgcrypt automatically re-allocates the
-     required memory.
-
- -- Function: gcry_mpi_t gcry_mpi_snew (unsigned int NBITS)
-     This is identical to `gcry_mpi_new' but allocates the MPI in the so
-     called "secure memory" which in turn will take care that all
-     derived values will also be stored in this "secure memory".  Use
-     this for highly confidential data like private key parameters.
-
- -- Function: gcry_mpi_t gcry_mpi_copy (const gcry_mpi_t A)
-     Create a new MPI as the exact copy of A but with the constant and
-     immutable flags cleared.
-
- -- Function: void gcry_mpi_release (gcry_mpi_t A)
-     Release the MPI A and free all associated resources.  Passing
-     `NULL' is allowed and ignored.  When a MPI stored in the "secure
-     memory" is released, that memory gets wiped out immediately.
-
-The simplest operations are used to assign a new value to an MPI:
-
- -- Function: gcry_mpi_t gcry_mpi_set (gcry_mpi_t W, const gcry_mpi_t U)
-     Assign the value of U to W and return W.  If `NULL' is passed for
-     W, a new MPI is allocated, set to the value of U and returned.
-
- -- Function: gcry_mpi_t gcry_mpi_set_ui (gcry_mpi_t W, unsigned long U)
-     Assign the value of U to W and return W.  If `NULL' is passed for
-     W, a new MPI is allocated, set to the value of U and returned.
-     This function takes an `unsigned int' as type for U and thus it is
-     only possible to set W to small values (usually up to the word
-     size of the CPU).
-
- -- Function: void gcry_mpi_swap (gcry_mpi_t A, gcry_mpi_t B)
-     Swap the values of A and B.
-
- -- Function: void gcry_mpi_snatch (gcry_mpi_t W, const gcry_mpi_t U)
-     Set U into W and release U.  If W is `NULL' only U will be
-     released.
-
- -- Function: void gcry_mpi_neg (gcry_mpi_t W, gcry_mpi_t U)
-     Set the sign of W to the negative of U.
-
- -- Function: void gcry_mpi_abs (gcry_mpi_t W)
-     Clear the sign of W.
-
-\1f
-File: gcrypt.info,  Node: MPI formats,  Next: Calculations,  Prev: Basic functions,  Up: MPI library
-
-12.3 MPI formats
-================
-
-The following functions are used to convert between an external
-representation of an MPI and the internal one of Libgcrypt.
-
- -- Function: gcry_error_t gcry_mpi_scan (gcry_mpi_t *R_MPI,
-          enum gcry_mpi_format FORMAT, const unsigned char *BUFFER,
-          size_t BUFLEN, size_t *NSCANNED)
-     Convert the external representation of an integer stored in BUFFER
-     with a length of BUFLEN into a newly created MPI returned which
-     will be stored at the address of R_MPI.  For certain formats the
-     length argument is not required and should be passed as `0'.
-     After a successful operation the variable NSCANNED receives the
-     number of bytes actually scanned unless NSCANNED was given as
-     `NULL'. FORMAT describes the format of the MPI as stored in BUFFER:
-
-    `GCRYMPI_FMT_STD'
-          2-complement stored without a length header.  Note that
-          `gcry_mpi_print' stores a `0' as a string of zero length.
-
-    `GCRYMPI_FMT_PGP'
-          As used by OpenPGP (only defined as unsigned). This is
-          basically `GCRYMPI_FMT_STD' with a 2 byte big endian length
-          header.
-
-    `GCRYMPI_FMT_SSH'
-          As used in the Secure Shell protocol.  This is
-          `GCRYMPI_FMT_STD' with a 4 byte big endian header.
-
-    `GCRYMPI_FMT_HEX'
-          Stored as a string with each byte of the MPI encoded as 2 hex
-          digits.  Negative numbers are prefix with a minus sign and in
-          addition the high bit is always zero to make clear that an
-          explicit sign ist used.  When using this format, BUFLEN must
-          be zero.
-
-    `GCRYMPI_FMT_USG'
-          Simple unsigned integer.
-
-     Note that all of the above formats store the integer in big-endian
-     format (MSB first).
-
- -- Function: gcry_error_t gcry_mpi_print (enum gcry_mpi_format FORMAT,
-          unsigned char *BUFFER, size_t BUFLEN, size_t *NWRITTEN,
-          const gcry_mpi_t A)
-     Convert the MPI A into an external representation described by
-     FORMAT (see above) and store it in the provided BUFFER which has a
-     usable length of at least the BUFLEN bytes. If NWRITTEN is not
-     NULL, it will receive the number of bytes actually stored in
-     BUFFER after a successful operation.
-
- -- Function: gcry_error_t gcry_mpi_aprint
-          (enum gcry_mpi_format FORMAT, unsigned char **BUFFER,
-          size_t *NBYTES, const gcry_mpi_t A)
-     Convert the MPI A into an external representation described by
-     FORMAT (see above) and store it in a newly allocated buffer which
-     address will be stored in the variable BUFFER points to.  The
-     number of bytes stored in this buffer will be stored in the
-     variable NBYTES points to, unless NBYTES is `NULL'.
-
-     Even if NBYTES is zero, the function allocates at least one byte
-     and store a zero there.  Thus with formats `GCRYMPI_FMT_STD' and
-     `GCRYMPI_FMT_USG' the caller may safely set a returned length of 0
-     to 1 to represent a zero as a 1 byte string.
-
-
- -- Function: void gcry_mpi_dump (const gcry_mpi_t A)
-     Dump the value of A in a format suitable for debugging to
-     Libgcrypt's logging stream.  Note that one leading space but no
-     trailing space or linefeed will be printed.  It is okay to pass
-     `NULL' for A.
-
-\1f
-File: gcrypt.info,  Node: Calculations,  Next: Comparisons,  Prev: MPI formats,  Up: MPI library
-
-12.4 Calculations
-=================
-
-Basic arithmetic operations:
-
- -- Function: void gcry_mpi_add (gcry_mpi_t W, gcry_mpi_t U,
-          gcry_mpi_t V)
-     W = U + V.
-
- -- Function: void gcry_mpi_add_ui (gcry_mpi_t W, gcry_mpi_t U,
-          unsigned long V)
-     W = U + V.  Note that V is an unsigned integer.
-
- -- Function: void gcry_mpi_addm (gcry_mpi_t W, gcry_mpi_t U,
-          gcry_mpi_t V, gcry_mpi_t M)
-     W = U + V \bmod M.
-
- -- Function: void gcry_mpi_sub (gcry_mpi_t W, gcry_mpi_t U,
-          gcry_mpi_t V)
-     W = U - V.
-
- -- Function: void gcry_mpi_sub_ui (gcry_mpi_t W, gcry_mpi_t U,
-          unsigned long V)
-     W = U - V.  V is an unsigned integer.
-
- -- Function: void gcry_mpi_subm (gcry_mpi_t W, gcry_mpi_t U,
-          gcry_mpi_t V, gcry_mpi_t M)
-     W = U - V \bmod M.
-
- -- Function: void gcry_mpi_mul (gcry_mpi_t W, gcry_mpi_t U,
-          gcry_mpi_t V)
-     W = U * V.
-
- -- Function: void gcry_mpi_mul_ui (gcry_mpi_t W, gcry_mpi_t U,
-          unsigned long V)
-     W = U * V.  V is an unsigned integer.
-
- -- Function: void gcry_mpi_mulm (gcry_mpi_t W, gcry_mpi_t U,
-          gcry_mpi_t V, gcry_mpi_t M)
-     W = U * V \bmod M.
-
- -- Function: void gcry_mpi_mul_2exp (gcry_mpi_t W, gcry_mpi_t U,
-          unsigned long E)
-     W = U * 2^e.
-
- -- Function: void gcry_mpi_div (gcry_mpi_t Q, gcry_mpi_t R,
-          gcry_mpi_t DIVIDEND, gcry_mpi_t DIVISOR, int ROUND)
-     Q = DIVIDEND / DIVISOR, R = DIVIDEND \bmod DIVISOR.  Q and R may
-     be passed as `NULL'.  ROUND should be negative or 0.
-
- -- Function: void gcry_mpi_mod (gcry_mpi_t R, gcry_mpi_t DIVIDEND,
-          gcry_mpi_t DIVISOR)
-     R = DIVIDEND \bmod DIVISOR.
-
- -- Function: void gcry_mpi_powm (gcry_mpi_t W, const gcry_mpi_t B,
-          const gcry_mpi_t E, const gcry_mpi_t M)
-     W = B^e \bmod M.
-
- -- Function: int gcry_mpi_gcd (gcry_mpi_t G, gcry_mpi_t A,
-          gcry_mpi_t B)
-     Set G to the greatest common divisor of A and B.  Return true if
-     the G is 1.
-
- -- Function: int gcry_mpi_invm (gcry_mpi_t X, gcry_mpi_t A,
-          gcry_mpi_t M)
-     Set X to the multiplicative inverse of A \bmod M.  Return true if
-     the inverse exists.
-
-\1f
-File: gcrypt.info,  Node: Comparisons,  Next: Bit manipulations,  Prev: Calculations,  Up: MPI library
-
-12.5 Comparisons
-================
-
-The next 2 functions are used to compare MPIs:
-
- -- Function: int gcry_mpi_cmp (const gcry_mpi_t U, const gcry_mpi_t V)
-     Compare the multi-precision-integers number U and V returning 0
-     for equality, a positive value for U > V and a negative for U < V.
-     If both numbers are opaque values (cf, gcry_mpi_set_opaque) the
-     comparison is done by checking the bit sizes using memcmp.  If
-     only one number is an opaque value, the opaque value is less than
-     the other number.
-
- -- Function: int gcry_mpi_cmp_ui (const gcry_mpi_t U, unsigned long V)
-     Compare the multi-precision-integers number U with the unsigned
-     integer V returning 0 for equality, a positive value for U > V and
-     a negative for U < V.
-
- -- Function: int gcry_mpi_is_neg (const gcry_mpi_t A)
-     Return 1 if A is less than zero; return 0 if zero or positive.
-
-\1f
-File: gcrypt.info,  Node: Bit manipulations,  Next: EC functions,  Prev: Comparisons,  Up: MPI library
-
-12.6 Bit manipulations
-======================
-
-There are a couple of functions to get information on arbitrary bits in
-an MPI and to set or clear them:
-
- -- Function: unsigned int gcry_mpi_get_nbits (gcry_mpi_t A)
-     Return the number of bits required to represent A.
-
- -- Function: int gcry_mpi_test_bit (gcry_mpi_t A, unsigned int N)
-     Return true if bit number N (counting from 0) is set in A.
-
- -- Function: void gcry_mpi_set_bit (gcry_mpi_t A, unsigned int N)
-     Set bit number N in A.
-
- -- Function: void gcry_mpi_clear_bit (gcry_mpi_t A, unsigned int N)
-     Clear bit number N in A.
-
- -- Function: void gcry_mpi_set_highbit (gcry_mpi_t A, unsigned int N)
-     Set bit number N in A and clear all bits greater than N.
-
- -- Function: void gcry_mpi_clear_highbit (gcry_mpi_t A, unsigned int N)
-     Clear bit number N in A and all bits greater than N.
-
- -- Function: void gcry_mpi_rshift (gcry_mpi_t X, gcry_mpi_t A,
-          unsigned int N)
-     Shift the value of A by N bits to the right and store the result
-     in X.
-
- -- Function: void gcry_mpi_lshift (gcry_mpi_t X, gcry_mpi_t A,
-          unsigned int N)
-     Shift the value of A by N bits to the left and store the result in
-     X.
-
-\1f
-File: gcrypt.info,  Node: EC functions,  Next: Miscellaneous,  Prev: Bit manipulations,  Up: MPI library
-
-12.7 EC functions
-=================
-
-Libgcrypt provides an API to access low level functions used by its
-elliptic curve implementation.  These functions allow to implement
-elliptic curve methods for which no explicit support is available.
-
- -- Function: gcry_mpi_point_t gcry_mpi_point_new (unsigned int NBITS)
-     Allocate a new point object, initialize it to 0, and allocate
-     enough memory for a points of at least NBITS.  This pre-allocation
-     yields only a small performance win and is not really necessary
-     because Libgcrypt automatically re-allocates the required memory.
-     Using 0 for NBITS is usually the right thing to do.
-
- -- Function: void gcry_mpi_point_release (gcry_mpi_point_t POINT)
-     Release POINT and free all associated resources.  Passing `NULL'
-     is allowed and ignored.
-
- -- Function: void gcry_mpi_point_get (gcry_mpi_t X, gcry_mpi_t Y,
-          gcry_mpi_t Z, gcry_mpi_point_t POINT)
-     Store the projective coordinates from POINT into the MPIs X, Y,
-     and Z.  If a coordinate is not required, `NULL' may be used for X,
-     Y, or Z.
-
- -- Function: void gcry_mpi_point_snatch_get (gcry_mpi_t X,
-          gcry_mpi_t Y, gcry_mpi_t Z, gcry_mpi_point_t POINT)
-     Store the projective coordinates from POINT into the MPIs X, Y,
-     and Z.  If a coordinate is not required, `NULL' may be used for X,
-     Y, or Z.  The object POINT is then released.  Using this function
-     instead of `gcry_mpi_point_get' and `gcry_mpi_point_release' has
-     the advantage of avoiding some extra memory allocations and copies.
-
- -- Function: gcry_mpi_point_t gcry_mpi_point_set (
-          gcry_mpi_point_t POINT, gcry_mpi_t X, gcry_mpi_t Y,
-          gcry_mpi_t Z)
-     Store the projective coordinates from X, Y, and Z into POINT.  If
-     a coordinate is given as `NULL', the value 0 is used.  If `NULL'
-     is used for POINT a new point object is allocated and returned.
-     Returns POINT or the newly allocated point object.
-
- -- Function: gcry_mpi_point_t gcry_mpi_point_snatch_set (
-          gcry_mpi_point_t POINT, gcry_mpi_t X, gcry_mpi_t Y,
-          gcry_mpi_t Z)
-     Store the projective coordinates from X, Y, and Z into POINT.  If
-     a coordinate is given as `NULL', the value 0 is used.  If `NULL'
-     is used for POINT a new point object is allocated and returned.
-     The MPIs X, Y, and Z are released.  Using this function instead of
-     `gcry_mpi_point_set' and 3 calls to `gcry_mpi_release' has the
-     advantage of avoiding some extra memory allocations and copies.
-     Returns POINT or the newly allocated point object.
-
- -- Function: gpg_error_t gcry_mpi_ec_p_new (gpg_ctx_t *R_CTX,
-          gcry_sexp_t KEYPARAM, const char *CURVENAME)
-     Allocate a new context for elliptic curve operations.  If KEYPARAM
-     is given it specifies the parameters of the curve (*note
-     ecc_keyparam::).  If CURVENAME is given in addition to KEYPARAM
-     and the key parameters do not include a named curve reference, the
-     string CURVENAME is used to fill in missing parameters.  If only
-     CURVENAME is given, the context is initialized for this named
-     curve.
-
-     If a parameter specifying a point (e.g. `g' or `q') is not found,
-     the parser looks for a non-encoded point by appending `.x', `.y',
-     and `.z' to the parameter name and looking them all up to create a
-     point.  A parameter with the suffix `.z' is optional and defaults
-     to 1.
-
-     On success the function returns 0 and stores the new context
-     object at R_CTX; this object eventually needs to be released
-     (*note gcry_ctx_release::).  On error the function stores `NULL' at
-     R_CTX and returns an error code.
-
- -- Function: gcry_mpi_t gcry_mpi_ec_get_mpi ( const char *NAME,
-          gcry_ctx_t CTX, int COPY)
-     Return the MPI with NAME from the context CTX.  If not found
-     `NULL' is returned.  If the returned MPI may later be modified, it
-     is suggested to pass `1' to COPY, so that the function guarantees
-     that a modifiable copy of the MPI is returned.  If `0' is used for
-     COPY, this function may return a constant flagged MPI.  In any
-     case `gcry_mpi_release' needs to be called to release the result.
-     For valid names *note ecc_keyparam::.  If the public key `q' is
-     requested but only the private key `d' is available, `q' will be
-     recomputed on the fly.  If a point parameter is requested it is
-     returned as an uncompressed encoded point unless these special
-     names are used:
-    Q@EDDSA
-          Return an EdDSA style compressed point.  This is only
-          supported for Twisted Edwards curves.
-
- -- Function: gcry_mpi_point_t gcry_mpi_ec_get_point (
-          const char *NAME, gcry_ctx_t CTX, int COPY)
-     Return the point with NAME from the context CTX.  If not found
-     `NULL' is returned.  If the returned MPI may later be modified, it
-     is suggested to pass `1' to COPY, so that the function guarantees
-     that a modifiable copy of the MPI is returned.  If `0' is used for
-     COPY, this function may return a constant flagged point.  In any
-     case `gcry_mpi_point_release' needs to be called to release the
-     result.  If the public key `q' is requested but only the private
-     key `d' is available, `q' will be recomputed on the fly.
-
- -- Function: gpg_error_t gcry_mpi_ec_set_mpi ( const char *NAME,
-          gcry_mpi_t NEWVALUE, gcry_ctx_t CTX)
-     Store the MPI NEWVALUE at NAME into the context CTX.  On success
-     `0' is returned; on error an error code.  Valid names are the MPI
-     parameters of an elliptic curve (*note ecc_keyparam::).
-
- -- Function: gpg_error_t gcry_mpi_ec_set_point ( const char *NAME,
-          gcry_mpi_point_t NEWVALUE, gcry_ctx_t CTX)
-     Store the point NEWVALUE at NAME into the context CTX.  On success
-     `0' is returned; on error an error code.  Valid names are the
-     point parameters of an elliptic curve (*note ecc_keyparam::).
-
- -- Function: int gcry_mpi_ec_get_affine ( gcry_mpi_t X, gcry_mpi_t Y,
-          gcry_mpi_point_t POINT, gcry_ctx_t CTX)
-     Compute the affine coordinates from the projective coordinates in
-     POINT and store them into X and Y.  If one coordinate is not
-     required, `NULL' may be passed to X or Y.  CTX is the context
-     object which has been created using `gcry_mpi_ec_new'. Returns 0
-     on success or not 0 if POINT is at infinity.
-
-     Note that you can use `gcry_mpi_ec_set_point' with the value
-     `GCRYMPI_CONST_ONE' for Z to convert affine coordinates back into
-     projective coordinates.
-
-
- -- Function: void gcry_mpi_ec_dup ( gcry_mpi_point_t W,
-          gcry_mpi_point_t U, gcry_ctx_t CTX)
-     Double the point U of the elliptic curve described by CTX and
-     store the result into W.
-
- -- Function: void gcry_mpi_ec_add ( gcry_mpi_point_t W,
-          gcry_mpi_point_t U, gcry_mpi_point_t V, gcry_ctx_t CTX)
-     Add the points U and V of the elliptic curve described by CTX and
-     store the result into W.
-
- -- Function: void gcry_mpi_ec_mul ( gcry_mpi_point_t W, gcry_mpi_t N,
-          gcry_mpi_point_t U, gcry_ctx_t CTX)
-     Multiply the point U of the elliptic curve described by CTX by N
-     and store the result into W.
-
- -- Function: int gcry_mpi_ec_curve_point ( gcry_mpi_point_t POINT,
-          gcry_ctx_t CTX)
-     Return true if POINT is on the elliptic curve described by CTX.
-
-\1f
-File: gcrypt.info,  Node: Miscellaneous,  Prev: EC functions,  Up: MPI library
-
-12.8 Miscellaneous
-==================
-
-An MPI data type is allowed to be "misused" to store an arbitrary
-value.  Two functions implement this kludge:
-
- -- Function: gcry_mpi_t gcry_mpi_set_opaque (gcry_mpi_t A, void *P,
-          unsigned int NBITS)
-     Store NBITS of the value P points to in A and mark A as an opaque
-     value (i.e. an value that can't be used for any math calculation
-     and is only used to store an arbitrary bit pattern in A).
-     Ownership of P is taken by this function and thus the user may not
-     use dereference the passed value anymore.  It is required that
-     them memory referenced by P has been allocated in a way that
-     `gcry_free' is able to release it.
-
-     WARNING: Never use an opaque MPI for actual math operations.  The
-     only valid functions are gcry_mpi_get_opaque and gcry_mpi_release.
-     Use gcry_mpi_scan to convert a string of arbitrary bytes into an
-     MPI.
-
- -- Function: gcry_mpi_t gcry_mpi_set_opaque_copy (gcry_mpi_t A,
-          const void *P, unsigned int NBITS)
-     Same as `gcry_mpi_set_opaque' but ownership of P is not taken
-     instead a copy of P is used.
-
- -- Function: void * gcry_mpi_get_opaque (gcry_mpi_t A,
-          unsigned int *NBITS)
-     Return a pointer to an opaque value stored in A and return its
-     size in NBITS.  Note that the returned pointer is still owned by A
-     and that the function should never be used for an non-opaque MPI.
-
-   Each MPI has an associated set of flags for special purposes.  The
-currently defined flags are:
-
-`GCRYMPI_FLAG_SECURE'
-     Setting this flag converts A into an MPI stored in "secure
-     memory".  Clearing this flag is not allowed.
-
-`GCRYMPI_FLAG_OPAQUE'
-     This is an interanl flag, indicating the an opaque valuue and not
-     an integer is stored.  This is an read-only flag; it may not be
-     set or cleared.
-
-`GCRYMPI_FLAG_IMMUTABLE'
-     If this flag is set, the MPI is marked as immutable.  Setting or
-     changing the value of that MPI is ignored and an error message is
-     logged.  The flag is sometimes useful for debugging.
-
-`GCRYMPI_FLAG_CONST'
-     If this flag is set, the MPI is marked as a constant and as
-     immutable Setting or changing the value of that MPI is ignored and
-     an error message is logged.  Such an MPI will never be deallocated
-     and may thus be used without copying.  Note that using
-     gcry_mpi_copy will return a copy of that constant with this and
-     the immutable flag cleared.  A few commonly used constants are
-     pre-defined and accessible using the macros `GCRYMPI_CONST_ONE',
-     `GCRYMPI_CONST_TWO', `GCRYMPI_CONST_THREE', `GCRYMPI_CONST_FOUR',
-     and `GCRYMPI_CONST_EIGHT'.
-
-`GCRYMPI_FLAG_USER1'
-`GCRYMPI_FLAG_USER2'
-`GCRYMPI_FLAG_USER3'
-`GCRYMPI_FLAG_USER4'
-     These flags are reserved for use by the application.
-
- -- Function: void gcry_mpi_set_flag (gcry_mpi_t A,
-          enum gcry_mpi_flag FLAG)
-     Set the FLAG for the MPI A.  The only allowed flags are
-     `GCRYMPI_FLAG_SECURE', `GCRYMPI_FLAG_IMMUTABLE', and
-     `GCRYMPI_FLAG_CONST'.
-
- -- Function: void gcry_mpi_clear_flag (gcry_mpi_t A,
-          enum gcry_mpi_flag FLAG)
-     Clear FLAG for the multi-precision-integers A.  The only allowed
-     flag is `GCRYMPI_FLAG_IMMUTABLE' but only if `GCRYMPI_FLAG_CONST'
-     is not set.  If `GCRYMPI_FLAG_CONST' is set, clearing
-     `GCRYMPI_FLAG_IMMUTABLE' will simply be ignored.
-   o
-
- -- Function: int gcry_mpi_get_flag (gcry_mpi_t A,
-          enum gcry_mpi_flag FLAG)
-     Return true if FLAG is set for A.
-
-   To put a random value into an MPI, the following convenience function
-may be used:
-
- -- Function: void gcry_mpi_randomize (gcry_mpi_t W,
-          unsigned int NBITS, enum gcry_random_level LEVEL)
-     Set the multi-precision-integers W to a random non-negative number
-     of NBITS, using random data quality of level LEVEL.  In case NBITS
-     is not a multiple of a byte, NBITS is rounded up to the next byte
-     boundary.  When using a LEVEL of `GCRY_WEAK_RANDOM' this function
-     makes use of `gcry_create_nonce'.
-
-\1f
-File: gcrypt.info,  Node: Prime numbers,  Next: Utilities,  Prev: MPI library,  Up: Top
-
-13 Prime numbers
-****************
-
-* Menu:
-
-* Generation::                  Generation of new prime numbers.
-* Checking::                    Checking if a given number is prime.
-
-\1f
-File: gcrypt.info,  Node: Generation,  Next: Checking,  Up: Prime numbers
-
-13.1 Generation
-===============
-
- -- Function: gcry_error_t gcry_prime_generate (gcry_mpi_t
-          *PRIME,unsigned int PRIME_BITS, unsigned int FACTOR_BITS,
-          gcry_mpi_t **FACTORS, gcry_prime_check_func_t CB_FUNC, void
-          *CB_ARG, gcry_random_level_t RANDOM_LEVEL, unsigned int FLAGS)
-     Generate a new prime number of PRIME_BITS bits and store it in
-     PRIME.  If FACTOR_BITS is non-zero, one of the prime factors of
-     (PRIME - 1) / 2 must be FACTOR_BITS bits long.  If FACTORS is
-     non-zero, allocate a new, `NULL'-terminated array holding the
-     prime factors and store it in FACTORS.  FLAGS might be used to
-     influence the prime number generation process.
-
- -- Function: gcry_error_t gcry_prime_group_generator (gcry_mpi_t *R_G,
-          gcry_mpi_t PRIME, gcry_mpi_t *FACTORS, gcry_mpi_t START_G)
-     Find a generator for PRIME where the factorization of (PRIME-1) is
-     in the `NULL' terminated array FACTORS.  Return the generator as a
-     newly allocated MPI in R_G.  If START_G is not NULL, use this as
-     the start for the search.
-
- -- Function: void gcry_prime_release_factors (gcry_mpi_t *FACTORS)
-     Convenience function to release the FACTORS array.
-
-\1f
-File: gcrypt.info,  Node: Checking,  Prev: Generation,  Up: Prime numbers
-
-13.2 Checking
-=============
-
- -- Function: gcry_error_t gcry_prime_check (gcry_mpi_t P, unsigned int
-          FLAGS)
-     Check whether the number P is prime.  Returns zero in case P is
-     indeed a prime, returns `GPG_ERR_NO_PRIME' in case P is not a
-     prime and a different error code in case something went horribly
-     wrong.
-
-\1f
-File: gcrypt.info,  Node: Utilities,  Next: Tools,  Prev: Prime numbers,  Up: Top
-
-14 Utilities
-************
-
-* Menu:
-
-* Memory allocation::   Functions related with memory allocation.
-* Context management::  Functions related with context management.
-* Buffer description::  A data type to describe buffers.
-
-\1f
-File: gcrypt.info,  Node: Memory allocation,  Next: Context management,  Up: Utilities
-
-14.1 Memory allocation
-======================
-
- -- Function: void * gcry_malloc (size_t N)
-     This function tries to allocate N bytes of memory.  On success it
-     returns a pointer to the memory area, in an out-of-core condition,
-     it returns NULL.
-
- -- Function: void * gcry_malloc_secure (size_t N)
-     Like `gcry_malloc', but uses secure memory.
-
- -- Function: void * gcry_calloc (size_t N, size_t M)
-     This function allocates a cleared block of memory (i.e.
-     initialized with zero bytes) long enough to contain a vector of N
-     elements, each of size M bytes.  On success it returns a pointer
-     to the memory block; in an out-of-core condition, it returns NULL.
-
- -- Function: void * gcry_calloc_secure (size_t N, size_t M)
-     Like `gcry_calloc', but uses secure memory.
-
- -- Function: void * gcry_realloc (void *P, size_t N)
-     This function tries to resize the memory area pointed to by P to N
-     bytes.  On success it returns a pointer to the new memory area, in
-     an out-of-core condition, it returns NULL.  Depending on whether
-     the memory pointed to by P is secure memory or not, gcry_realloc
-     tries to use secure memory as well.
-
- -- Function: void gcry_free (void *P)
-     Release the memory area pointed to by P.
-
-\1f
-File: gcrypt.info,  Node: Context management,  Next: Buffer description,  Prev: Memory allocation,  Up: Utilities
-
-14.2 Context management
-=======================
-
-Some function make use of a context object.  As of now there are only a
-few math functions. However, future versions of Libgcrypt may make more
-use of this context object.
-
- -- Data type: gcry_ctx_t
-     This type is used to refer to the general purpose context object.
-
- -- Function: void gcry_ctx_release (gcry_ctx_t CTX)
-     Release the context object CTX and all associated resources.  A
-     `NULL' passed as CTX is ignored.
-
-\1f
-File: gcrypt.info,  Node: Buffer description,  Prev: Context management,  Up: Utilities
-
-14.3 Buffer description
-=======================
-
-To help hashing non-contiguous areas of memory a general purpose data
-type is defined:
-
- -- Data type: gcry_buffer_t
-     This type is a structure to describe a buffer.  The user should
-     make sure that this structure is initialized to zero.  The
-     available fields of this structure are:
-
-    `.size'
-          This is either 0 for no information available or indicates the
-           allocated length of the buffer.
-
-    `.off'
-          This is the offset into the buffer.
-
-    `.len'
-          This is the valid length of the buffer starting at `.off'.
-
-    `.data'
-          This is the address of the buffer.
-
-\1f
-File: gcrypt.info,  Node: Tools,  Next: Architecture,  Prev: Utilities,  Up: Top
-
-15 Tools
-********
-
-* Menu:
-
-* hmac256:: A standalone HMAC-SHA-256 implementation
-
-\1f
-File: gcrypt.info,  Node: hmac256,  Up: Tools
-
-15.1 A HMAC-SHA-256 tool
-========================
-
-This is a standalone HMAC-SHA-256 implementation used to compute an
-HMAC-SHA-256 message authentication code.  The tool has originally been
-developed as a second implementation for Libgcrypt to allow comparing
-against the primary implementation and to be used for internal
-consistency checks.  It should not be used for sensitive data because
-no mechanisms to clear the stack etc are used.
-
-   The code has been written in a highly portable manner and requires
-only a few standard definitions to be provided in a config.h file.
-
-`hmac256' is commonly invoked as
-
-     hmac256 "This is my key" foo.txt
-
-This compute the MAC on the file `foo.txt' using the key given on the
-command line.
-
-`hmac256' understands these options:
-
-`--binary'
-     Print the MAC as a binary string.  The default is to print the MAC
-     encoded has lower case hex digits.
-
-`--version'
-     Print version of the program and exit.
-
-
-\1f
-File: gcrypt.info,  Node: Architecture,  Next: Self-Tests,  Prev: Tools,  Up: Top
-
-16 Architecture
-***************
-
-This chapter describes the internal architecture of Libgcrypt.
-
-   Libgcrypt is a function library written in ISO C-90.  Any compliant
-compiler should be able to build Libgcrypt as long as the target is
-either a POSIX platform or compatible to the API used by Windows NT.
-Provisions have been take so that the library can be directly used from
-C++ applications; however building with a C++ compiler is not supported.
-
-   Building Libgcrypt is done by using the common `./configure && make'
-approach.  The configure command is included in the source distribution
-and as a portable shell script it works on any Unix-alike system.  The
-result of running the configure script are a C header file
-(`config.h'), customized Makefiles, the setup of symbolic links and a
-few other things.  After that the make tool builds and optionally
-installs the library and the documentation.  See the files `INSTALL'
-and `README' in the source distribution on how to do this.
-
-   Libgcrypt is developed using a Subversion(1) repository.  Although
-all released versions are tagged in this repository, they should not be
-used to build production versions of Libgcrypt.  Instead released
-tarballs should be used.  These tarballs are available from several
-places with the master copy at <ftp://ftp.gnupg.org/gcrypt/libgcrypt/>.
-Announcements of new releases are posted to the
-<gnupg-announce@gnupg.org> mailing list(2).
-
-    \0\b[image src="libgcrypt-modules.png" alt="Libgcrypt subsystems"\0\b]
-Figure 16.1: Libgcrypt subsystems
-
-   Libgcrypt consists of several subsystems (*note Figure 16.1:
-fig:subsystems.) and all these subsystems provide a public API; this
-includes the helper subsystems like the one for S-expressions.  The API
-style depends on the subsystem; in general an open-use-close approach
-is implemented.  The open returns a handle to a context used for all
-further operations on this handle, several functions may then be used
-on this handle and a final close function releases all resources
-associated with the handle.
-
-* Menu:
-
-* Public-Key Subsystem Architecture::              About public keys.
-* Symmetric Encryption Subsystem Architecture::    About standard ciphers.
-* Hashing and MACing Subsystem Architecture::      About hashing.
-* Multi-Precision-Integer Subsystem Architecture:: About big integers.
-* Prime-Number-Generator Subsystem Architecture::  About prime numbers.
-* Random-Number Subsystem Architecture::           About random stuff.
-
-   ---------- Footnotes ----------
-
-   (1) A version control system available for many platforms
-
-   (2) See `http://www.gnupg.org/documentation/mailing-lists.en.html'
-for details.
-
-\1f
-File: gcrypt.info,  Node: Public-Key Subsystem Architecture,  Next: Symmetric Encryption Subsystem Architecture,  Up: Architecture
-
-16.1 Public-Key Architecture
-============================
-
-Because public key cryptography is almost always used to process small
-amounts of data (hash values or session keys), the interface is not
-implemented using the open-use-close paradigm, but with single
-self-contained functions.  Due to the wide variety of parameters
-required by different algorithms S-expressions, as flexible way to
-convey these parameters, are used.  There is a set of helper functions
-to work with these S-expressions.
-
-   Aside of functions to register new algorithms, map algorithms names
-to algorithms identifiers and to lookup properties of a key, the
-following main functions are available:
-
-`gcry_pk_encrypt'
-     Encrypt data using a public key.
-
-`gcry_pk_decrypt'
-     Decrypt data using a private key.
-
-`gcry_pk_sign'
-     Sign data using a private key.
-
-`gcry_pk_verify'
-     Verify that a signature matches the data.
-
-`gcry_pk_testkey'
-     Perform a consistency over a public or private key.
-
-`gcry_pk_genkey'
-     Create a new public/private key pair.
-
-
-   All these functions lookup the module implementing the algorithm and
-pass the actual work to that module.  The parsing of the S-expression
-input and the construction of S-expression for the return values is
-done by the high level code (`cipher/pubkey.c').  Thus the internal
-interface between the algorithm modules and the high level functions
-passes data in a custom format.
-
-   By default Libgcrypt uses a blinding technique for RSA decryption to
-mitigate real world timing attacks over a network: Instead of using the
-RSA decryption directly, a blinded value y = x r^e \bmod n is decrypted
-and the unblinded value x' = y' r^-1 \bmod n returned.  The blinding
-value r is a random value with the size of the modulus n and generated
-with `GCRY_WEAK_RANDOM' random level.
-
-   The algorithm used for RSA and DSA key generation depends on whether
-Libgcrypt is operated in standard or in FIPS mode.  In standard mode an
-algorithm based on the Lim-Lee prime number generator is used.  In FIPS
-mode RSA keys are generated as specified in ANSI X9.31 (1998) and DSA
-keys as specified in FIPS 186-2.
-
-\1f
-File: gcrypt.info,  Node: Symmetric Encryption Subsystem Architecture,  Next: Hashing and MACing Subsystem Architecture,  Prev: Public-Key Subsystem Architecture,  Up: Architecture
-
-16.2 Symmetric Encryption Subsystem Architecture
-================================================
-
-The interface to work with symmetric encryption algorithms is made up
-of functions from the `gcry_cipher_' name space.  The implementation
-follows the open-use-close paradigm and uses registered algorithm
-modules for the actual work.  Unless a module implements optimized
-cipher mode implementations, the high level code (`cipher/cipher.c')
-implements the modes and calls the core algorithm functions to process
-each block.
-
-   The most important functions are:
-
-`gcry_cipher_open'
-     Create a new instance to encrypt or decrypt using a specified
-     algorithm and mode.
-
-`gcry_cipher_close'
-     Release an instance.
-
-`gcry_cipher_setkey'
-     Set a key to be used for encryption or decryption.
-
-`gcry_cipher_setiv'
-     Set an initialization vector to be used for encryption or
-     decryption.
-
-`gcry_cipher_encrypt'
-`gcry_cipher_decrypt'
-     Encrypt or decrypt data.  These functions may be called with
-     arbitrary amounts of data and as often as needed to encrypt or
-     decrypt all data.
-
-
-   There are also functions to query properties of algorithms or
-context, like block length, key length, map names or to enable features
-like padding methods.
-
-\1f
-File: gcrypt.info,  Node: Hashing and MACing Subsystem Architecture,  Next: Multi-Precision-Integer Subsystem Architecture,  Prev: Symmetric Encryption Subsystem Architecture,  Up: Architecture
-
-16.3 Hashing and MACing Subsystem Architecture
-==============================================
-
-The interface to work with message digests and CRC algorithms is made
-up of functions from the `gcry_md_' name space.  The implementation
-follows the open-use-close paradigm and uses registered algorithm
-modules for the actual work.  Although CRC algorithms are not
-considered cryptographic hash algorithms, they share enough properties
-so that it makes sense to handle them in the same way.  It is possible
-to use several algorithms at once with one context and thus compute
-them all on the same data.
-
-   The most important functions are:
-
-`gcry_md_open'
-     Create a new message digest instance and optionally enable one
-     algorithm.  A flag may be used to turn the message digest algorithm
-     into a HMAC algorithm.
-
-`gcry_md_enable'
-     Enable an additional algorithm for the instance.
-
-`gcry_md_setkey'
-     Set the key for the MAC.
-
-`gcry_md_write'
-     Pass more data for computing the message digest to an instance.
-
-`gcry_md_putc'
-     Buffered version of `gcry_md_write' implemented as a macro.
-
-`gcry_md_read'
-     Finalize the computation of the message digest or HMAC and return
-     the result.
-
-`gcry_md_close'
-     Release an instance
-
-`gcry_md_hash_buffer'
-     Convenience function to directly compute a message digest over a
-     memory buffer without the need to create an instance first.
-
-
-   There are also functions to query properties of algorithms or the
-instance, like enabled algorithms, digest length, map algorithm names.
-it is also possible to reset an instance or to copy the current state
-of an instance at any time.  Debug functions to write the hashed data
-to files are available as well.
-
-\1f
-File: gcrypt.info,  Node: Multi-Precision-Integer Subsystem Architecture,  Next: Prime-Number-Generator Subsystem Architecture,  Prev: Hashing and MACing Subsystem Architecture,  Up: Architecture
-
-16.4 Multi-Precision-Integer Subsystem Architecture
-===================================================
-
-The implementation of Libgcrypt's big integer computation code is based
-on an old release of GNU Multi-Precision Library (GMP).  The decision
-not to use the GMP library directly was due to stalled development at
-that time and due to security requirements which could not be provided
-by the code in GMP.  As GMP does, Libgcrypt provides high performance
-assembler implementations of low level code for several CPUS to gain
-much better performance than with a generic C implementation.
-
-Major features of Libgcrypt's multi-precision-integer code compared to
-GMP are:
-
-   * Avoidance of stack based allocations to allow protection against
-     swapping out of sensitive data and for easy zeroing of sensitive
-     intermediate results.
-
-   * Optional use of secure memory and tracking of its use so that
-     results are also put into secure memory.
-
-   * MPIs are identified by a handle (implemented as a pointer) to give
-     better control over allocations and to augment them with extra
-     properties like opaque data.
-
-   * Removal of unnecessary code to reduce complexity.
-
-   * Functions specialized for public key cryptography.
-
-
-\1f
-File: gcrypt.info,  Node: Prime-Number-Generator Subsystem Architecture,  Next: Random-Number Subsystem Architecture,  Prev: Multi-Precision-Integer Subsystem Architecture,  Up: Architecture
-
-16.5 Prime-Number-Generator Subsystem Architecture
-==================================================
-
-Libgcrypt provides an interface to its prime number generator.  These
-functions make use of the internal prime number generator which is
-required for the generation for public key key pairs.  The plain prime
-checking function is exported as well.
-
-   The generation of random prime numbers is based on the Lim and Lee
-algorithm to create practically save primes.(1) This algorithm creates
-a pool of smaller primes, select a few of them to create candidate
-primes of the form 2 * p_0 * p_1 * ... * p_n + 1, tests the candidate
-for primality and permutates the pool until a prime has been found.  It
-is possible to clamp one of the small primes to a certain size to help
-DSA style algorithms.  Because most of the small primes in the pool are
-not used for the resulting prime number, they are saved for later use
-(see `save_pool_prime' and `get_pool_prime' in `cipher/primegen.c').
-The prime generator optionally supports the finding of an appropriate
-generator.
-
-The primality test works in three steps:
-
-  1. The standard sieve algorithm using the primes up to 4999 is used
-     as a quick first check.
-
-  2. A Fermat test filters out almost all non-primes.
-
-  3. A 5 round Rabin-Miller test is finally used.  The first round uses
-     a witness of 2, whereas the next rounds use a random witness.
-
-
-   To support the generation of RSA and DSA keys in FIPS mode according
-to X9.31 and FIPS 186-2, Libgcrypt implements two additional prime
-generation functions: `_gcry_derive_x931_prime' and
-`_gcry_generate_fips186_2_prime'.  These functions are internal and not
-available through the public API.
-
-   ---------- Footnotes ----------
-
-   (1) Chae Hoon Lim and Pil Joong Lee. A key recovery attack on
-discrete log-based schemes using a prime order subgroup. In Burton S.
-Kaliski Jr., editor, Advances in Cryptology: Crypto '97, pages
-249­-263, Berlin / Heidelberg / New York, 1997. Springer-Verlag.
-Described on page 260.
-
-\1f
-File: gcrypt.info,  Node: Random-Number Subsystem Architecture,  Prev: Prime-Number-Generator Subsystem Architecture,  Up: Architecture
-
-16.6 Random-Number Subsystem Architecture
-=========================================
-
-Libgcrypt provides 3 levels or random quality: The level
-`GCRY_VERY_STRONG_RANDOM' usually used for key generation, the level
-`GCRY_STRONG_RANDOM' for all other strong random requirements and the
-function `gcry_create_nonce' which is used for weaker usages like
-nonces.  There is also a level `GCRY_WEAK_RANDOM' which in general maps
-to `GCRY_STRONG_RANDOM' except when used with the function
-`gcry_mpi_randomize', where it randomizes an multi-precision-integer
-using the `gcry_create_nonce' function.
-
-There are two distinct random generators available:
-
-   * The Continuously Seeded Pseudo Random Number Generator (CSPRNG),
-     which is based on the classic GnuPG derived big pool
-     implementation.  Implemented in `random/random-csprng.c' and used
-     by default.
-
-   * A FIPS approved ANSI X9.31 PRNG using AES with a 128 bit key.
-     Implemented in `random/random-fips.c' and used if Libgcrypt is in
-     FIPS mode.
-
-Both generators make use of so-called entropy gathering modules:
-
-rndlinux
-     Uses the operating system provided `/dev/random' and
-     `/dev/urandom' devices.
-
-rndunix
-     Runs several operating system commands to collect entropy from
-     sources like virtual machine and process statistics.  It is a kind
-     of poor-man's `/dev/random' implementation. It is not available in
-     FIPS mode.
-
-rndegd
-     Uses the operating system provided Entropy Gathering Daemon (EGD).
-     The EGD basically uses the same algorithms as rndunix does.
-     However as a system daemon it keeps on running and thus can serve
-     several processes requiring entropy input and does not waste
-     collected entropy if the application does not need all the
-     collected entropy. It is not available in FIPS mode.
-
-rndw32
-     Targeted for the Microsoft Windows OS.  It uses certain properties
-     of that system and is the only gathering module available for that
-     OS.
-
-rndhw
-     Extra module to collect additional entropy by utilizing a hardware
-     random number generator.  As of now the only supported hardware
-     RNG is the Padlock engine of VIA (Centaur) CPUs.  It is not
-     available in FIPS mode.
-
-
-* Menu:
-
-* CSPRNG Description::      Description of the CSPRNG.
-* FIPS PRNG Description::   Description of the FIPS X9.31 PRNG.
-
-\1f
-File: gcrypt.info,  Node: CSPRNG Description,  Next: FIPS PRNG Description,  Up: Random-Number Subsystem Architecture
-
-16.6.1 Description of the CSPRNG
---------------------------------
-
-This random number generator is loosely modelled after the one
-described in Peter Gutmann's paper: "Software Generation of Practically
-Strong Random Numbers".(1)
-
-   A pool of 600 bytes is used and mixed using the core RIPE-MD160 hash
-transform function.  Several extra features are used to make the robust
-against a wide variety of attacks and to protect against failures of
-subsystems.  The state of the generator may be saved to a file and
-initially seed form a file.
-
-   Depending on how Libgcrypt was build the generator is able to select
-the best working entropy gathering module.  It makes use of the slow
-and fast collection methods and requires the pool to initially seeded
-form the slow gatherer or a seed file.  An entropy estimation is used
-to mix in enough data from the gather modules before returning the
-actual random output.  Process fork detection and protection is
-implemented.
-
-   The implementation of the nonce generator (for `gcry_create_nonce')
-is a straightforward repeated hash design: A 28 byte buffer is
-initially seeded with the PID and the time in seconds in the first 20
-bytes and with 8 bytes of random taken from the `GCRY_STRONG_RANDOM'
-generator.  Random numbers are then created by hashing all the 28 bytes
-with SHA-1 and saving that again in the first 20 bytes.  The hash is
-also returned as result.
-
-   ---------- Footnotes ----------
-
-   (1) Also described in chapter 6 of his book "Cryptographic Security
-Architecture", New York, 2004, ISBN 0-387-95387-6.
-
-\1f
-File: gcrypt.info,  Node: FIPS PRNG Description,  Prev: CSPRNG Description,  Up: Random-Number Subsystem Architecture
-
-16.6.2 Description of the FIPS X9.31 PRNG
------------------------------------------
-
-The core of this deterministic random number generator is implemented
-according to the document "NIST-Recommended Random Number Generator
-Based on ANSI X9.31 Appendix A.2.4 Using the 3-Key Triple DES and AES
-Algorithms", dated 2005-01-31.  This implementation uses the AES
-variant.
-
-   The generator is based on contexts to utilize the same core functions
-for all random levels as required by the high-level interface.  All
-random generators return their data in 128 bit blocks.  If the caller
-requests less bits, the extra bits are not used.  The key for each
-generator is only set once at the first time a generator context is
-used.  The seed value is set along with the key and again after 1000
-output blocks.
-
-   On Unix like systems the `GCRY_VERY_STRONG_RANDOM' and
-`GCRY_STRONG_RANDOM' generators are keyed and seeded using the rndlinux
-module with the `/dev/random' device. Thus these generators may block
-until the OS kernel has collected enough entropy.  When used with
-Microsoft Windows the rndw32 module is used instead.
-
-   The generator used for `gcry_create_nonce' is keyed and seeded from
-the `GCRY_STRONG_RANDOM' generator.  Thus is may also block if the
-`GCRY_STRONG_RANDOM' generator has not yet been used before and thus
-gets initialized on the first use by `gcry_create_nonce'.  This special
-treatment is justified by the weaker requirements for a nonce generator
-and to save precious kernel entropy for use by the "real" random
-generators.
-
-   A self-test facility uses a separate context to check the
-functionality of the core X9.31 functions using a known answers test.
-During runtime each output block is compared to the previous one to
-detect a stuck generator.
-
-   The DT value for the generator is made up of the current time down to
-microseconds (if available) and a free running 64 bit counter.  When
-used with the test context the DT value is taken from the context and
-incremented on each use.
-
-\1f
-File: gcrypt.info,  Node: Self-Tests,  Next: FIPS Mode,  Prev: Architecture,  Up: Top
-
-Appendix A Description of the Self-Tests
-****************************************
-
-In addition to the build time regression test suite, Libgcrypt
-implements self-tests to be performed at runtime.  Which self-tests are
-actually used depends on the mode Libgcrypt is used in.  In standard
-mode a limited set of self-tests is run at the time an algorithm is
-first used.  Note that not all algorithms feature a self-test in
-standard mode.  The `GCRYCTL_SELFTEST' control command may be used to
-run all implemented self-tests at any time; this will even run more
-tests than those run in FIPS mode.
-
-   If any of the self-tests fails, the library immediately returns an
-error code to the caller.  If Libgcrypt is in FIPS mode the self-tests
-will be performed within the "Self-Test" state and any failure puts the
-library into the "Error" state.
-
-A.1 Power-Up Tests
-==================
-
-Power-up tests are only performed if Libgcrypt is in FIPS mode.
-
-A.1.1 Symmetric Cipher Algorithm Power-Up Tests
------------------------------------------------
-
-The following symmetric encryption algorithm tests are run during
-power-up:
-
-3DES
-     To test the 3DES 3-key EDE encryption in ECB mode these tests are
-     run:
-       1. A known answer test is run on a 64 bit test vector processed
-          by 64 rounds of Single-DES block encryption and decryption
-          using a key changed with each round.
-
-       2. A known answer test is run on a 64 bit test vector processed
-          by 16 rounds of 2-key and 3-key Triple-DES block encryption
-          and decryptions using a key changed with each round.
-
-       3. 10 known answer tests using 3-key Triple-DES EDE encryption,
-          comparing the ciphertext to the known value, then running a
-          decryption and comparing it to the initial plaintext.
-          (`cipher/des.c:selftest')
-
-AES-128
-     A known answer tests is run using one test vector and one test key
-     with AES in ECB mode. (`cipher/rijndael.c:selftest_basic_128')
-
-AES-192
-     A known answer tests is run using one test vector and one test key
-     with AES in ECB mode. (`cipher/rijndael.c:selftest_basic_192')
-
-AES-256
-     A known answer tests is run using one test vector and one test key
-     with AES in ECB mode. (`cipher/rijndael.c:selftest_basic_256')
-
-A.1.2 Hash Algorithm Power-Up Tests
------------------------------------
-
-The following hash algorithm tests are run during power-up:
-
-SHA-1
-     A known answer test using the string `"abc"' is run.
-     (`cipher/sha1.c:selftests_sha1')
-
-SHA-224
-     A known answer test using the string `"abc"' is run.
-     (`cipher/sha256.c:selftests_sha224')
-
-SHA-256
-     A known answer test using the string `"abc"' is run.
-     (`cipher/sha256.c:selftests_sha256')
-
-SHA-384
-     A known answer test using the string `"abc"' is run.
-     (`cipher/sha512.c:selftests_sha384')
-
-SHA-512
-     A known answer test using the string `"abc"' is run.
-     (`cipher/sha512.c:selftests_sha512')
-
-A.1.3 MAC Algorithm Power-Up Tests
-----------------------------------
-
-The following MAC algorithm tests are run during power-up:
-
-HMAC SHA-1
-     A known answer test using 9 byte of data and a 64 byte key is run.
-     (`cipher/hmac-tests.c:selftests_sha1')
-
-HMAC SHA-224
-     A known answer test using 28 byte of data and a 4 byte key is run.
-     (`cipher/hmac-tests.c:selftests_sha224')
-
-HMAC SHA-256
-     A known answer test using 28 byte of data and a 4 byte key is run.
-     (`cipher/hmac-tests.c:selftests_sha256')
-
-HMAC SHA-384
-     A known answer test using 28 byte of data and a 4 byte key is run.
-     (`cipher/hmac-tests.c:selftests_sha384')
-
-HMAC SHA-512
-     A known answer test using 28 byte of data and a 4 byte key is run.
-     (`cipher/hmac-tests.c:selftests_sha512')
-
-A.1.4 Random Number Power-Up Test
----------------------------------
-
-The DRNG is tested during power-up this way:
-
-  1. Requesting one block of random using the public interface to check
-     general working and the duplicated block detection.
-
-  2. 3 know answer tests using pre-defined keys, seed and initial DT
-     values.  For each test 3 blocks of 16 bytes are requested and
-     compared to the expected result.  The DT value is incremented for
-     each block.
-
-A.1.5 Public Key Algorithm Power-Up Tests
------------------------------------------
-
-The public key algorithms are tested during power-up:
-
-RSA
-     A pre-defined 1024 bit RSA key is used and these tests are run in
-     turn:
-       1. Conversion of S-expression to internal format.
-          (`cipher/rsa.c:selftests_rsa')
-
-       2. Private key consistency check.  (`cipher/rsa.c:selftests_rsa')
-
-       3. A pre-defined 20 byte value is signed with PKCS#1 padding for
-          SHA-1.  The result is verified using the public key against
-          the original data and against modified data.
-          (`cipher/rsa.c:selftest_sign_1024')
-
-       4. A 1000 bit random value is encrypted and checked that it does
-          not match the original random value.  The encrypted result is
-          then decrypted and checked that it matches the original
-          random value.  (`cipher/rsa.c:selftest_encr_1024')
-
-DSA
-     A pre-defined 1024 bit DSA key is used and these tests are run in
-     turn:
-       1. Conversion of S-expression to internal format.
-          (`cipher/dsa.c:selftests_dsa')
-
-       2. Private key consistency check.  (`cipher/dsa.c:selftests_dsa')
-
-       3. A pre-defined 20 byte value is signed with PKCS#1 padding for
-          SHA-1.  The result is verified using the public key against
-          the original data and against modified data.
-          (`cipher/dsa.c:selftest_sign_1024')
-
-A.1.6 Integrity Power-Up Tests
-------------------------------
-
-The integrity of the Libgcrypt is tested during power-up but only if
-checking has been enabled at build time.  The check works by computing
-a HMAC SHA-256 checksum over the file used to load Libgcrypt into
-memory.  That checksum is compared against a checksum stored in a file
-of the same name but with a single dot as a prefix and a suffix of
-`.hmac'.
-
-A.1.7 Critical Functions Power-Up Tests
----------------------------------------
-
-The 3DES weak key detection is tested during power-up by calling the
-detection function with keys taken from a table listening all weak
-keys.  The table itself is protected using a SHA-1 hash.
-(`cipher/des.c:selftest')
-
-A.2 Conditional Tests
-=====================
-
-The conditional tests are performed if a certain condition is met.
-This may occur at any time; the library does not necessary enter the
-"Self-Test" state to run these tests but will transit to the "Error"
-state if a test failed.
-
-A.2.1 Key-Pair Generation Tests
--------------------------------
-
-After an asymmetric key-pair has been generated, Libgcrypt runs a
-pair-wise consistency tests on the generated key.  On failure the
-generated key is not used, an error code is returned and, if in FIPS
-mode, the library is put into the "Error" state.
-
-RSA
-     The test uses a random number 64 bits less the size of the modulus
-     as plaintext and runs an encryption and decryption operation in
-     turn.  The encrypted value is checked to not match the plaintext
-     and the result of the decryption is checked to match the plaintext.
-
-     A new random number of the same size is generated, signed and
-     verified to test the correctness of the signing operation.  As a
-     second signing test, the signature is modified by incrementing its
-     value and then verified with the expected result that the
-     verification fails.  (`cipher/rsa.c:test_keys')
-
-DSA
-     The test uses a random number of the size of the Q parameter to
-     create a signature and then checks that the signature verifies.
-     As a second signing test, the data is modified by incrementing its
-     value and then verified against the signature with the expected
-     result that the verification fails.  (`cipher/dsa.c:test_keys')
-
-A.2.2 Software Load Tests
--------------------------
-
-No code is loaded at runtime.
-
-A.2.3 Manual Key Entry Tests
-----------------------------
-
-A manual key entry feature is not implemented in Libgcrypt.
-
-A.2.4 Continuous RNG Tests
---------------------------
-
-The continuous random number test is only used in FIPS mode.  The RNG
-generates blocks of 128 bit size; the first block generated per context
-is saved in the context and another block is generated to be returned
-to the caller.  Each block is compared against the saved block and then
-stored in the context.  If a duplicated block is detected an error is
-signaled and the library is put into the "Fatal-Error" state.
-(`random/random-fips.c:x931_aes_driver')
-
-A.3 Application Requested Tests
-===============================
-
-The application may requests tests at any time by means of the
-`GCRYCTL_SELFTEST' control command.  Note that using these tests is not
-FIPS conform: Although Libgcrypt rejects all application requests for
-services while running self-tests, it does not ensure that no other
-operations of Libgcrypt are still being executed.  Thus, in FIPS mode
-an application requesting self-tests needs to power-cycle Libgcrypt
-instead.
-
-   When self-tests are requested, Libgcrypt runs all the tests it does
-during power-up as well as a few extra checks as described below.
-
-A.3.1 Symmetric Cipher Algorithm Tests
---------------------------------------
-
-The following symmetric encryption algorithm tests are run in addition
-to the power-up tests:
-
-AES-128
-     A known answer tests with test vectors taken from NIST SP800-38a
-     and using the high level functions is run for block modes CFB and
-     OFB.
-
-
-A.3.2 Hash Algorithm Tests
---------------------------
-
-The following hash algorithm tests are run in addition to the power-up
-tests:
-
-SHA-1
-SHA-224
-SHA-256
-       1. A known answer test using a 56 byte string is run.
-
-       2. A known answer test using a string of one million letters "a"
-          is run.
-          (`cipher/sha1.c:selftests_sha1',
-     `cipher/sha256.c:selftests_sha224',
-     `cipher/sha256.c:selftests_sha256')
-
-SHA-384
-
-SHA-512
-       1. A known answer test using a 112 byte string is run.
-
-       2. A known answer test using a string of one million letters "a"
-          is run.
-          (`cipher/sha512.c:selftests_sha384',
-     `cipher/sha512.c:selftests_sha512')
-
-A.3.3 MAC Algorithm Tests
--------------------------
-
-The following MAC algorithm tests are run in addition to the power-up
-tests:
-
-HMAC SHA-1
-       1. A known answer test using 9 byte of data and a 20 byte key is
-          run.
-
-       2. A known answer test using 9 byte of data and a 100 byte key
-          is run.
-
-       3. A known answer test using 9 byte of data and a 49 byte key is
-          run.
-          (`cipher/hmac-tests.c:selftests_sha1')
-
-HMAC SHA-224
-HMAC SHA-256
-HMAC SHA-384
-HMAC SHA-512
-       1. A known answer test using 9 byte of data and a 20 byte key is
-          run.
-
-       2. A known answer test using 50 byte of data and a 20 byte key
-          is run.
-
-       3. A known answer test using 50 byte of data and a 26 byte key
-          is run.
-
-       4. A known answer test using 54 byte of data and a 131 byte key
-          is run.
-
-       5. A known answer test using 152 byte of data and a 131 byte key
-          is run.
-          (`cipher/hmac-tests.c:selftests_sha224',
-     `cipher/hmac-tests.c:selftests_sha256',
-     `cipher/hmac-tests.c:selftests_sha384',
-     `cipher/hmac-tests.c:selftests_sha512')
-
-\1f
-File: gcrypt.info,  Node: FIPS Mode,  Next: Library Copying,  Prev: Self-Tests,  Up: Top
-
-Appendix B Description of the FIPS Mode
-***************************************
-
-This appendix gives detailed information pertaining to the FIPS mode.
-In particular, the changes to the standard mode and the finite state
-machine are described.  The self-tests required in this mode are
-described in the appendix on self-tests.
-
-B.1 Restrictions in FIPS Mode
-=============================
-
-If Libgcrypt is used in FIPS mode these restrictions are effective:
-
-   * The cryptographic algorithms are restricted to this list:
-
-    GCRY_CIPHER_3DES
-          3 key EDE Triple-DES symmetric encryption.
-
-    GCRY_CIPHER_AES128
-          AES 128 bit symmetric encryption.
-
-    GCRY_CIPHER_AES192
-          AES 192 bit symmetric encryption.
-
-    GCRY_CIPHER_AES256
-          AES 256 bit symmetric encryption.
-
-    GCRY_MD_SHA1
-          SHA-1 message digest.
-
-    GCRY_MD_SHA224
-          SHA-224 message digest.
-
-    GCRY_MD_SHA256
-          SHA-256 message digest.
-
-    GCRY_MD_SHA384
-          SHA-384 message digest.
-
-    GCRY_MD_SHA512
-          SHA-512 message digest.
-
-    GCRY_MD_SHA1,GCRY_MD_FLAG_HMAC
-          HMAC using a SHA-1 message digest.
-
-    GCRY_MD_SHA224,GCRY_MD_FLAG_HMAC
-          HMAC using a SHA-224 message digest.
-
-    GCRY_MD_SHA256,GCRY_MD_FLAG_HMAC
-          HMAC using a SHA-256 message digest.
-
-    GCRY_MD_SHA384,GCRY_MD_FLAG_HMAC
-          HMAC using a SHA-384 message digest.
-
-    GCRY_MD_SHA512,GCRY_MD_FLAG_HMAC
-          HMAC using a SHA-512 message digest.
-
-    GCRY_PK_RSA
-          RSA encryption and signing.
-
-    GCRY_PK_DSA
-          DSA signing.
-
-     Note that the CRC algorithms are not considered cryptographic
-     algorithms and thus are in addition available.
-
-   * RSA key generation refuses to create a key with a keysize of less
-     than 1024 bits.
-
-   * DSA key generation refuses to create a key with a keysize other
-     than 1024 bits.
-
-   * The `transient-key' flag for RSA and DSA key generation is ignored.
-
-   * Support for the VIA Padlock engine is disabled.
-
-   * FIPS mode may only be used on systems with a /dev/random device.
-     Switching into FIPS mode on other systems will fail at runtime.
-
-   * Saving and loading a random seed file is ignored.
-
-   * An X9.31 style random number generator is used in place of the
-     large-pool-CSPRNG generator.
-
-   * The command `GCRYCTL_ENABLE_QUICK_RANDOM' is ignored.
-
-   * Message digest debugging is disabled.
-
-   * All debug output related to cryptographic data is suppressed.
-
-   * On-the-fly self-tests are not performed, instead self-tests are run
-     before entering operational state.
-
-   * The function `gcry_set_allocation_handler' may not be used.  If it
-     is used Libgcrypt disables FIPS mode unless Enforced FIPS mode is
-     enabled, in which case Libgcrypt will enter the error state.
-
-   * The digest algorithm MD5 may not be used.  If it is used Libgcrypt
-     disables FIPS mode unless Enforced FIPS mode is enabled, in which
-     case Libgcrypt will enter the error state.
-
-   * In Enforced FIPS mode the command `GCRYCTL_DISABLE_SECMEM' is
-     ignored.  In standard FIPS mode it disables FIPS mode.
-
-   * A handler set by `gcry_set_outofcore_handler' is ignored.
-
-   * A handler set by `gcry_set_fatalerror_handler' is ignored.
-
-
-   Note that when we speak about disabling FIPS mode, it merely means
-that the function `gcry_fips_mode_active' returns false; it does not
-mean that any non FIPS algorithms are allowed.
-
-B.2 FIPS Finite State Machine
-=============================
-
-The FIPS mode of libgcrypt implements a finite state machine (FSM) using
-8 states (*note tbl:fips-states::) and checks at runtime that only valid
-transitions (*note tbl:fips-state-transitions::) may happen.
-
-           \0\b[image src="fips-fsm.png" alt="FIPS FSM Diagram"\0\b]
-Figure B.1: FIPS mode state diagram
-
-States used by the FIPS FSM:
-Power-Off
-     Libgcrypt is not runtime linked to another application.  This
-     usually means that the library is not loaded into main memory.
-     This state is documentation only.
-
-Power-On
-     Libgcrypt is loaded into memory and API calls may be made.
-     Compiler introduced constructor functions may be run.  Note that
-     Libgcrypt does not implement any arbitrary constructor functions
-     to be called by the operating system
-
-Init
-     The Libgcrypt initialization functions are performed and the
-     library has not yet run any self-test.
-
-Self-Test
-     Libgcrypt is performing self-tests.
-
-Operational
-     Libgcrypt is in the operational state and all interfaces may be
-     used.
-
-Error
-     Libgrypt is in the error state.  When calling any FIPS relevant
-     interfaces they either return an error (`GPG_ERR_NOT_OPERATIONAL')
-     or put Libgcrypt into the Fatal-Error state and won't return.
-
-Fatal-Error
-     Libgcrypt is in a non-recoverable error state and will
-     automatically transit into the  Shutdown state.
-
-Shutdown
-     Libgcrypt is about to be terminated and removed from the memory.
-     The application may at this point still running cleanup handlers.
-
-
-Table B.1: FIPS mode states
-
-The valid state transitions (*note Figure B.1: fig:fips-fsm.) are:
-`1'
-     Power-Off to Power-On is implicitly done by the OS loading
-     Libgcrypt as a shared library and having it linked to an
-     application.
-
-`2'
-     Power-On to Init is triggered by the application calling the
-     Libgcrypt initialization function `gcry_check_version'.
-
-`3'
-     Init to Self-Test is either triggered by a dedicated API call or
-     implicit by invoking a libgrypt service controlled by the FSM.
-
-`4'
-     Self-Test to Operational is triggered after all self-tests passed
-     successfully.
-
-`5'
-     Operational to Shutdown is an artificial state without any direct
-     action in Libgcrypt.  When reaching the Shutdown state the library
-     is deinitialized and can't return to any other state again.
-
-`6'
-     Shutdown to Power-off is the process of removing Libgcrypt from the
-     computer's memory.  For obvious reasons the Power-Off state can't
-     be represented within Libgcrypt and thus this transition is for
-     documentation only.
-
-`7'
-     Operational to Error is triggered if Libgcrypt detected an
-     application error which can't be returned to the caller but still
-     allows Libgcrypt to properly run.  In the Error state all FIPS
-     relevant interfaces return an error code.
-
-`8'
-     Error to Shutdown is similar to the Operational to Shutdown
-     transition (5).
-
-`9'
-     Error to Fatal-Error is triggered if Libgrypt detects an fatal
-     error while already being in Error state.
-
-`10'
-     Fatal-Error to Shutdown is automatically entered by Libgcrypt
-     after having reported the error.
-
-`11'
-     Power-On to Shutdown is an artificial state to document that
-     Libgcrypt has not ye been initialized but the process is about to
-     terminate.
-
-`12'
-     Power-On to Fatal-Error will be triggered if certain Libgcrypt
-     functions are used without having reached the Init state.
-
-`13'
-     Self-Test to Fatal-Error is triggered by severe errors in
-     Libgcrypt while running self-tests.
-
-`14'
-     Self-Test to Error is triggered by a failed self-test.
-
-`15'
-     Operational to Fatal-Error is triggered if Libcrypt encountered a
-     non-recoverable error.
-
-`16'
-     Operational to Self-Test is triggered if the application requested
-     to run the self-tests again.
-
-`17'
-     Error to Self-Test is triggered if the application has requested
-     to run self-tests to get to get back into operational state after
-     an error.
-
-`18'
-     Init to Error is triggered by errors in the initialization code.
-
-`19'
-     Init to Fatal-Error is triggered by non-recoverable errors in the
-     initialization code.
-
-`20'
-     Error to Error is triggered by errors while already in the Error
-     state.
-
-
-Table B.2: FIPS mode state transitions
-
-B.3 FIPS Miscellaneous Information
-==================================
-
-Libgcrypt does not do any key management on itself; the application
-needs to care about it.  Keys which are passed to Libgcrypt should be
-allocated in secure memory as available with the functions
-`gcry_malloc_secure' and `gcry_calloc_secure'.  By calling `gcry_free'
-on this memory, the memory and thus the keys are overwritten with zero
-bytes before releasing the memory.
-
-   For use with the random number generator, Libgcrypt generates 3
-internal keys which are stored in the encryption contexts used by the
-RNG.  These keys are stored in secure memory for the lifetime of the
-process.  Application are required to use `GCRYCTL_TERM_SECMEM' before
-process termination.  This will zero out the entire secure memory and
-thus also the encryption contexts with these keys.
-
-\1f
-File: gcrypt.info,  Node: Library Copying,  Next: Copying,  Prev: FIPS Mode,  Up: Top
-
-GNU Lesser General Public License
-*********************************
-
-                      Version 2.1, February 1999
-
-     Copyright (C) 1991, 1999 Free Software Foundation, Inc.
-     59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
-     Everyone is permitted to copy and distribute verbatim copies
-     of this license document, but changing it is not allowed.
-
-     [This is the first released version of the Lesser GPL.  It also counts
-     as the successor of the GNU Library Public License, version 2, hence the
-     version number 2.1.]
-
-Preamble
-========
-
-The licenses for most software are designed to take away your freedom
-to share and change it.  By contrast, the GNU General Public Licenses
-are intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.
-
-   This license, the Lesser General Public License, applies to some
-specially designated software--typically libraries--of the Free
-Software Foundation and other authors who decide to use it.  You can use
-it too, but we suggest you first think carefully about whether this
-license or the ordinary General Public License is the better strategy to
-use in any particular case, based on the explanations below.
-
-   When we speak of free software, we are referring to freedom of use,
-not price.  Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of it
-in new free programs; and that you are informed that you can do these
-things.
-
-   To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights.  These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
-   For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you.  You must make sure that they, too, receive or can get the source
-code.  If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it.  And you must show them these terms so they know their rights.
-
-   We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
-   To protect each distributor, we want to make it very clear that
-there is no warranty for the free library.  Also, if the library is
-modified by someone else and passed on, the recipients should know that
-what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-
-   Finally, software patents pose a constant threat to the existence of
-any free program.  We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder.  Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
-   Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License.  This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and is
-quite different from the ordinary General Public License.  We use this
-license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
-   When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library.  The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom.  The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
-   We call this license the "Lesser" General Public License because it
-does _Less_ to protect the user's freedom than the ordinary General
-Public License.  It also provides other free software developers Less
-of an advantage over competing non-free programs.  These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries.  However, the Lesser license provides advantages in certain
-special circumstances.
-
-   For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it
-becomes a de-facto standard.  To achieve this, non-free programs must be
-allowed to use the library.  A more frequent case is that a free
-library does the same job as widely used non-free libraries.  In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
-   In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of free
-software.  For example, permission to use the GNU C Library in non-free
-programs enables many more people to use the whole GNU operating
-system, as well as its variant, the GNU/Linux operating system.
-
-   Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run that
-program using a modified version of the Library.
-
-   The precise terms and conditions for copying, distribution and
-modification follow.  Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library".  The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-
-                   GNU LESSER GENERAL PUBLIC LICENSE
-    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-  0. This License Agreement applies to any software library or other
-     program which contains a notice placed by the copyright holder or
-     other authorized party saying it may be distributed under the
-     terms of this Lesser General Public License (also called "this
-     License").  Each licensee is addressed as "you".
-
-     A "library" means a collection of software functions and/or data
-     prepared so as to be conveniently linked with application programs
-     (which use some of those functions and data) to form executables.
-
-     The "Library", below, refers to any such software library or work
-     which has been distributed under these terms.  A "work based on the
-     Library" means either the Library or any derivative work under
-     copyright law: that is to say, a work containing the Library or a
-     portion of it, either verbatim or with modifications and/or
-     translated straightforwardly into another language.  (Hereinafter,
-     translation is included without limitation in the term
-     "modification".)
-
-     "Source code" for a work means the preferred form of the work for
-     making modifications to it.  For a library, complete source code
-     means all the source code for all modules it contains, plus any
-     associated interface definition files, plus the scripts used to
-     control compilation and installation of the library.
-
-     Activities other than copying, distribution and modification are
-     not covered by this License; they are outside its scope.  The act
-     of running a program using the Library is not restricted, and
-     output from such a program is covered only if its contents
-     constitute a work based on the Library (independent of the use of
-     the Library in a tool for writing it).  Whether that is true
-     depends on what the Library does and what the program that uses
-     the Library does.
-
-  1. You may copy and distribute verbatim copies of the Library's
-     complete source code as you receive it, in any medium, provided
-     that you conspicuously and appropriately publish on each copy an
-     appropriate copyright notice and disclaimer of warranty; keep
-     intact all the notices that refer to this License and to the
-     absence of any warranty; and distribute a copy of this License
-     along with the Library.
-
-     You may charge a fee for the physical act of transferring a copy,
-     and you may at your option offer warranty protection in exchange
-     for a fee.
-
-  2. You may modify your copy or copies of the Library or any portion
-     of it, thus forming a work based on the Library, and copy and
-     distribute such modifications or work under the terms of Section 1
-     above, provided that you also meet all of these conditions:
-
-       a. The modified work must itself be a software library.
-
-       b. You must cause the files modified to carry prominent notices
-          stating that you changed the files and the date of any change.
-
-       c. You must cause the whole of the work to be licensed at no
-          charge to all third parties under the terms of this License.
-
-       d. If a facility in the modified Library refers to a function or
-          a table of data to be supplied by an application program that
-          uses the facility, other than as an argument passed when the
-          facility is invoked, then you must make a good faith effort
-          to ensure that, in the event an application does not supply
-          such function or table, the facility still operates, and
-          performs whatever part of its purpose remains meaningful.
-
-          (For example, a function in a library to compute square roots
-          has a purpose that is entirely well-defined independent of the
-          application.  Therefore, Subsection 2d requires that any
-          application-supplied function or table used by this function
-          must be optional: if the application does not supply it, the
-          square root function must still compute square roots.)
-
-     These requirements apply to the modified work as a whole.  If
-     identifiable sections of that work are not derived from the
-     Library, and can be reasonably considered independent and separate
-     works in themselves, then this License, and its terms, do not
-     apply to those sections when you distribute them as separate
-     works.  But when you distribute the same sections as part of a
-     whole which is a work based on the Library, the distribution of
-     the whole must be on the terms of this License, whose permissions
-     for other licensees extend to the entire whole, and thus to each
-     and every part regardless of who wrote it.
-
-     Thus, it is not the intent of this section to claim rights or
-     contest your rights to work written entirely by you; rather, the
-     intent is to exercise the right to control the distribution of
-     derivative or collective works based on the Library.
-
-     In addition, mere aggregation of another work not based on the
-     Library with the Library (or with a work based on the Library) on
-     a volume of a storage or distribution medium does not bring the
-     other work under the scope of this License.
-
-  3. You may opt to apply the terms of the ordinary GNU General Public
-     License instead of this License to a given copy of the Library.
-     To do this, you must alter all the notices that refer to this
-     License, so that they refer to the ordinary GNU General Public
-     License, version 2, instead of to this License.  (If a newer
-     version than version 2 of the ordinary GNU General Public License
-     has appeared, then you can specify that version instead if you
-     wish.)  Do not make any other change in these notices.
-
-     Once this change is made in a given copy, it is irreversible for
-     that copy, so the ordinary GNU General Public License applies to
-     all subsequent copies and derivative works made from that copy.
-
-     This option is useful when you wish to copy part of the code of
-     the Library into a program that is not a library.
-
-  4. You may copy and distribute the Library (or a portion or
-     derivative of it, under Section 2) in object code or executable
-     form under the terms of Sections 1 and 2 above provided that you
-     accompany it with the complete corresponding machine-readable
-     source code, which must be distributed under the terms of Sections
-     1 and 2 above on a medium customarily used for software
-     interchange.
-
-     If distribution of object code is made by offering access to copy
-     from a designated place, then offering equivalent access to copy
-     the source code from the same place satisfies the requirement to
-     distribute the source code, even though third parties are not
-     compelled to copy the source along with the object code.
-
-  5. A program that contains no derivative of any portion of the
-     Library, but is designed to work with the Library by being
-     compiled or linked with it, is called a "work that uses the
-     Library".  Such a work, in isolation, is not a derivative work of
-     the Library, and therefore falls outside the scope of this License.
-
-     However, linking a "work that uses the Library" with the Library
-     creates an executable that is a derivative of the Library (because
-     it contains portions of the Library), rather than a "work that
-     uses the library".  The executable is therefore covered by this
-     License.  Section 6 states terms for distribution of such
-     executables.
-
-     When a "work that uses the Library" uses material from a header
-     file that is part of the Library, the object code for the work may
-     be a derivative work of the Library even though the source code is
-     not.  Whether this is true is especially significant if the work
-     can be linked without the Library, or if the work is itself a
-     library.  The threshold for this to be true is not precisely
-     defined by law.
-
-     If such an object file uses only numerical parameters, data
-     structure layouts and accessors, and small macros and small inline
-     functions (ten lines or less in length), then the use of the object
-     file is unrestricted, regardless of whether it is legally a
-     derivative work.  (Executables containing this object code plus
-     portions of the Library will still fall under Section 6.)
-
-     Otherwise, if the work is a derivative of the Library, you may
-     distribute the object code for the work under the terms of Section
-     6.  Any executables containing that work also fall under Section 6,
-     whether or not they are linked directly with the Library itself.
-
-  6. As an exception to the Sections above, you may also combine or
-     link a "work that uses the Library" with the Library to produce a
-     work containing portions of the Library, and distribute that work
-     under terms of your choice, provided that the terms permit
-     modification of the work for the customer's own use and reverse
-     engineering for debugging such modifications.
-
-     You must give prominent notice with each copy of the work that the
-     Library is used in it and that the Library and its use are covered
-     by this License.  You must supply a copy of this License.  If the
-     work during execution displays copyright notices, you must include
-     the copyright notice for the Library among them, as well as a
-     reference directing the user to the copy of this License.  Also,
-     you must do one of these things:
-
-       a. Accompany the work with the complete corresponding
-          machine-readable source code for the Library including
-          whatever changes were used in the work (which must be
-          distributed under Sections 1 and 2 above); and, if the work
-          is an executable linked with the Library, with the complete
-          machine-readable "work that uses the Library", as object code
-          and/or source code, so that the user can modify the Library
-          and then relink to produce a modified executable containing
-          the modified Library.  (It is understood that the user who
-          changes the contents of definitions files in the Library will
-          not necessarily be able to recompile the application to use
-          the modified definitions.)
-
-       b. Use a suitable shared library mechanism for linking with the
-          Library.  A suitable mechanism is one that (1) uses at run
-          time a copy of the library already present on the user's
-          computer system, rather than copying library functions into
-          the executable, and (2) will operate properly with a modified
-          version of the library, if the user installs one, as long as
-          the modified version is interface-compatible with the version
-          that the work was made with.
-
-       c. Accompany the work with a written offer, valid for at least
-          three years, to give the same user the materials specified in
-          Subsection 6a, above, for a charge no more than the cost of
-          performing this distribution.
-
-       d. If distribution of the work is made by offering access to copy
-          from a designated place, offer equivalent access to copy the
-          above specified materials from the same place.
-
-       e. Verify that the user has already received a copy of these
-          materials or that you have already sent this user a copy.
-
-     For an executable, the required form of the "work that uses the
-     Library" must include any data and utility programs needed for
-     reproducing the executable from it.  However, as a special
-     exception, the materials to be distributed need not include
-     anything that is normally distributed (in either source or binary
-     form) with the major components (compiler, kernel, and so on) of
-     the operating system on which the executable runs, unless that
-     component itself accompanies the executable.
-
-     It may happen that this requirement contradicts the license
-     restrictions of other proprietary libraries that do not normally
-     accompany the operating system.  Such a contradiction means you
-     cannot use both them and the Library together in an executable
-     that you distribute.
-
-  7. You may place library facilities that are a work based on the
-     Library side-by-side in a single library together with other
-     library facilities not covered by this License, and distribute
-     such a combined library, provided that the separate distribution
-     of the work based on the Library and of the other library
-     facilities is otherwise permitted, and provided that you do these
-     two things:
-
-       a. Accompany the combined library with a copy of the same work
-          based on the Library, uncombined with any other library
-          facilities.  This must be distributed under the terms of the
-          Sections above.
-
-       b. Give prominent notice with the combined library of the fact
-          that part of it is a work based on the Library, and explaining
-          where to find the accompanying uncombined form of the same
-          work.
-
-  8. You may not copy, modify, sublicense, link with, or distribute the
-     Library except as expressly provided under this License.  Any
-     attempt otherwise to copy, modify, sublicense, link with, or
-     distribute the Library is void, and will automatically terminate
-     your rights under this License.  However, parties who have
-     received copies, or rights, from you under this License will not
-     have their licenses terminated so long as such parties remain in
-     full compliance.
-
-  9. You are not required to accept this License, since you have not
-     signed it.  However, nothing else grants you permission to modify
-     or distribute the Library or its derivative works.  These actions
-     are prohibited by law if you do not accept this License.
-     Therefore, by modifying or distributing the Library (or any work
-     based on the Library), you indicate your acceptance of this
-     License to do so, and all its terms and conditions for copying,
-     distributing or modifying the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
-     Library), the recipient automatically receives a license from the
-     original licensor to copy, distribute, link with or modify the
-     Library subject to these terms and conditions.  You may not impose
-     any further restrictions on the recipients' exercise of the rights
-     granted herein.  You are not responsible for enforcing compliance
-     by third parties with this License.
-
- 11. If, as a consequence of a court judgment or allegation of patent
-     infringement or for any other reason (not limited to patent
-     issues), conditions are imposed on you (whether by court order,
-     agreement or otherwise) that contradict the conditions of this
-     License, they do not excuse you from the conditions of this
-     License.  If you cannot distribute so as to satisfy simultaneously
-     your obligations under this License and any other pertinent
-     obligations, then as a consequence you may not distribute the
-     Library at all.  For example, if a patent license would not permit
-     royalty-free redistribution of the Library by all those who
-     receive copies directly or indirectly through you, then the only
-     way you could satisfy both it and this License would be to refrain
-     entirely from distribution of the Library.
-
-     If any portion of this section is held invalid or unenforceable
-     under any particular circumstance, the balance of the section is
-     intended to apply, and the section as a whole is intended to apply
-     in other circumstances.
-
-     It is not the purpose of this section to induce you to infringe any
-     patents or other property right claims or to contest validity of
-     any such claims; this section has the sole purpose of protecting
-     the integrity of the free software distribution system which is
-     implemented by public license practices.  Many people have made
-     generous contributions to the wide range of software distributed
-     through that system in reliance on consistent application of that
-     system; it is up to the author/donor to decide if he or she is
-     willing to distribute software through any other system and a
-     licensee cannot impose that choice.
-
-     This section is intended to make thoroughly clear what is believed
-     to be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
-     certain countries either by patents or by copyrighted interfaces,
-     the original copyright holder who places the Library under this
-     License may add an explicit geographical distribution limitation
-     excluding those countries, so that distribution is permitted only
-     in or among countries not thus excluded.  In such case, this
-     License incorporates the limitation as if written in the body of
-     this License.
-
- 13. The Free Software Foundation may publish revised and/or new
-     versions of the Lesser General Public License from time to time.
-     Such new versions will be similar in spirit to the present version,
-     but may differ in detail to address new problems or concerns.
-
-     Each version is given a distinguishing version number.  If the
-     Library specifies a version number of this License which applies
-     to it and "any later version", you have the option of following
-     the terms and conditions either of that version or of any later
-     version published by the Free Software Foundation.  If the Library
-     does not specify a license version number, you may choose any
-     version ever published by the Free Software Foundation.
-
- 14. If you wish to incorporate parts of the Library into other free
-     programs whose distribution conditions are incompatible with these,
-     write to the author to ask for permission.  For software which is
-     copyrighted by the Free Software Foundation, write to the Free
-     Software Foundation; we sometimes make exceptions for this.  Our
-     decision will be guided by the two goals of preserving the free
-     status of all derivatives of our free software and of promoting
-     the sharing and reuse of software generally.
-
-                                NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-     WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE
-     LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-     HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT
-     WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT
-     NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-     FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE
-     QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU.  SHOULD THE
-     LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY
-     SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-     WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY
-     MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE
-     LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
-     INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
-     INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF
-     DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU
-     OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY
-     OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN
-     ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
-                      END OF TERMS AND CONDITIONS
-How to Apply These Terms to Your New Libraries
-==============================================
-
-If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change.  You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of
-the ordinary General Public License).
-
-   To apply these terms, attach the following notices to the library.
-It is safest to attach them to the start of each source file to most
-effectively convey the exclusion of warranty; and each file should have
-at least the "copyright" line and a pointer to where the full notice is
-found.
-
-     ONE LINE TO GIVE THE LIBRARY'S NAME AND AN IDEA OF WHAT IT DOES.
-     Copyright (C) YEAR  NAME OF AUTHOR
-
-     This library is free software; you can redistribute it and/or modify it
-     under the terms of the GNU Lesser General Public License as published by
-     the Free Software Foundation; either version 2.1 of the License, or (at
-     your option) any later version.
-
-     This library is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     Lesser General Public License for more details.
-
-     You should have received a copy of the GNU Lesser General Public
-     License along with this library; if not, write to the Free Software
-     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
-     USA.
-
-   Also add information on how to contact you by electronic and paper
-mail.
-
-   You should also get your employer (if you work as a programmer) or
-your school, if any, to sign a "copyright disclaimer" for the library,
-if necessary.  Here is a sample; alter the names:
-
-     Yoyodyne, Inc., hereby disclaims all copyright interest in the library
-     `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
-     SIGNATURE OF TY COON, 1 April 1990
-     Ty Coon, President of Vice
-
-   That's all there is to it!
-
-\1f
-File: gcrypt.info,  Node: Copying,  Next: Figures and Tables,  Prev: Library Copying,  Up: Top
-
-GNU General Public License
-**************************
-
-                         Version 2, June 1991
-
-     Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-     59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
-     Everyone is permitted to copy and distribute verbatim copies
-     of this license document, but changing it is not allowed.
-
-Preamble
-========
-
-The licenses for most software are designed to take away your freedom
-to share and change it.  By contrast, the GNU General Public License is
-intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.)  You can apply it to
-your programs, too.
-
-   When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it in
-new free programs; and that you know you can do these things.
-
-   To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-   For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-   We protect your rights with two steps: (1) copyright the software,
-and (2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-   Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-   Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-   The precise terms and conditions for copying, distribution and
-modification follow.
-
-    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-  1. This License applies to any program or other work which contains a
-     notice placed by the copyright holder saying it may be distributed
-     under the terms of this General Public License.  The "Program",
-     below, refers to any such program or work, and a "work based on
-     the Program" means either the Program or any derivative work under
-     copyright law: that is to say, a work containing the Program or a
-     portion of it, either verbatim or with modifications and/or
-     translated into another language.  (Hereinafter, translation is
-     included without limitation in the term "modification".)  Each
-     licensee is addressed as "you".
-
-     Activities other than copying, distribution and modification are
-     not covered by this License; they are outside its scope.  The act
-     of running the Program is not restricted, and the output from the
-     Program is covered only if its contents constitute a work based on
-     the Program (independent of having been made by running the
-     Program).  Whether that is true depends on what the Program does.
-
-  2. You may copy and distribute verbatim copies of the Program's
-     source code as you receive it, in any medium, provided that you
-     conspicuously and appropriately publish on each copy an appropriate
-     copyright notice and disclaimer of warranty; keep intact all the
-     notices that refer to this License and to the absence of any
-     warranty; and give any other recipients of the Program a copy of
-     this License along with the Program.
-
-     You may charge a fee for the physical act of transferring a copy,
-     and you may at your option offer warranty protection in exchange
-     for a fee.
-
-  3. You may modify your copy or copies of the Program or any portion
-     of it, thus forming a work based on the Program, and copy and
-     distribute such modifications or work under the terms of Section 1
-     above, provided that you also meet all of these conditions:
-
-       a. You must cause the modified files to carry prominent notices
-          stating that you changed the files and the date of any change.
-
-       b. You must cause any work that you distribute or publish, that
-          in whole or in part contains or is derived from the Program
-          or any part thereof, to be licensed as a whole at no charge
-          to all third parties under the terms of this License.
-
-       c. If the modified program normally reads commands interactively
-          when run, you must cause it, when started running for such
-          interactive use in the most ordinary way, to print or display
-          an announcement including an appropriate copyright notice and
-          a notice that there is no warranty (or else, saying that you
-          provide a warranty) and that users may redistribute the
-          program under these conditions, and telling the user how to
-          view a copy of this License.  (Exception: if the Program
-          itself is interactive but does not normally print such an
-          announcement, your work based on the Program is not required
-          to print an announcement.)
-
-     These requirements apply to the modified work as a whole.  If
-     identifiable sections of that work are not derived from the
-     Program, and can be reasonably considered independent and separate
-     works in themselves, then this License, and its terms, do not
-     apply to those sections when you distribute them as separate
-     works.  But when you distribute the same sections as part of a
-     whole which is a work based on the Program, the distribution of
-     the whole must be on the terms of this License, whose permissions
-     for other licensees extend to the entire whole, and thus to each
-     and every part regardless of who wrote it.
-
-     Thus, it is not the intent of this section to claim rights or
-     contest your rights to work written entirely by you; rather, the
-     intent is to exercise the right to control the distribution of
-     derivative or collective works based on the Program.
-
-     In addition, mere aggregation of another work not based on the
-     Program with the Program (or with a work based on the Program) on
-     a volume of a storage or distribution medium does not bring the
-     other work under the scope of this License.
-
-  4. You may copy and distribute the Program (or a work based on it,
-     under Section 2) in object code or executable form under the terms
-     of Sections 1 and 2 above provided that you also do one of the
-     following:
-
-       a. Accompany it with the complete corresponding machine-readable
-          source code, which must be distributed under the terms of
-          Sections 1 and 2 above on a medium customarily used for
-          software interchange; or,
-
-       b. Accompany it with a written offer, valid for at least three
-          years, to give any third party, for a charge no more than your
-          cost of physically performing source distribution, a complete
-          machine-readable copy of the corresponding source code, to be
-          distributed under the terms of Sections 1 and 2 above on a
-          medium customarily used for software interchange; or,
-
-       c. Accompany it with the information you received as to the offer
-          to distribute corresponding source code.  (This alternative is
-          allowed only for noncommercial distribution and only if you
-          received the program in object code or executable form with
-          such an offer, in accord with Subsection b above.)
-
-     The source code for a work means the preferred form of the work for
-     making modifications to it.  For an executable work, complete
-     source code means all the source code for all modules it contains,
-     plus any associated interface definition files, plus the scripts
-     used to control compilation and installation of the executable.
-     However, as a special exception, the source code distributed need
-     not include anything that is normally distributed (in either
-     source or binary form) with the major components (compiler,
-     kernel, and so on) of the operating system on which the executable
-     runs, unless that component itself accompanies the executable.
-
-     If distribution of executable or object code is made by offering
-     access to copy from a designated place, then offering equivalent
-     access to copy the source code from the same place counts as
-     distribution of the source code, even though third parties are not
-     compelled to copy the source along with the object code.
-
-  5. You may not copy, modify, sublicense, or distribute the Program
-     except as expressly provided under this License.  Any attempt
-     otherwise to copy, modify, sublicense or distribute the Program is
-     void, and will automatically terminate your rights under this
-     License.  However, parties who have received copies, or rights,
-     from you under this License will not have their licenses
-     terminated so long as such parties remain in full compliance.
-
-  6. You are not required to accept this License, since you have not
-     signed it.  However, nothing else grants you permission to modify
-     or distribute the Program or its derivative works.  These actions
-     are prohibited by law if you do not accept this License.
-     Therefore, by modifying or distributing the Program (or any work
-     based on the Program), you indicate your acceptance of this
-     License to do so, and all its terms and conditions for copying,
-     distributing or modifying the Program or works based on it.
-
-  7. Each time you redistribute the Program (or any work based on the
-     Program), the recipient automatically receives a license from the
-     original licensor to copy, distribute or modify the Program
-     subject to these terms and conditions.  You may not impose any
-     further restrictions on the recipients' exercise of the rights
-     granted herein.  You are not responsible for enforcing compliance
-     by third parties to this License.
-
-  8. If, as a consequence of a court judgment or allegation of patent
-     infringement or for any other reason (not limited to patent
-     issues), conditions are imposed on you (whether by court order,
-     agreement or otherwise) that contradict the conditions of this
-     License, they do not excuse you from the conditions of this
-     License.  If you cannot distribute so as to satisfy simultaneously
-     your obligations under this License and any other pertinent
-     obligations, then as a consequence you may not distribute the
-     Program at all.  For example, if a patent license would not permit
-     royalty-free redistribution of the Program by all those who
-     receive copies directly or indirectly through you, then the only
-     way you could satisfy both it and this License would be to refrain
-     entirely from distribution of the Program.
-
-     If any portion of this section is held invalid or unenforceable
-     under any particular circumstance, the balance of the section is
-     intended to apply and the section as a whole is intended to apply
-     in other circumstances.
-
-     It is not the purpose of this section to induce you to infringe any
-     patents or other property right claims or to contest validity of
-     any such claims; this section has the sole purpose of protecting
-     the integrity of the free software distribution system, which is
-     implemented by public license practices.  Many people have made
-     generous contributions to the wide range of software distributed
-     through that system in reliance on consistent application of that
-     system; it is up to the author/donor to decide if he or she is
-     willing to distribute software through any other system and a
-     licensee cannot impose that choice.
-
-     This section is intended to make thoroughly clear what is believed
-     to be a consequence of the rest of this License.
-
-  9. If the distribution and/or use of the Program is restricted in
-     certain countries either by patents or by copyrighted interfaces,
-     the original copyright holder who places the Program under this
-     License may add an explicit geographical distribution limitation
-     excluding those countries, so that distribution is permitted only
-     in or among countries not thus excluded.  In such case, this
-     License incorporates the limitation as if written in the body of
-     this License.
-
- 10. The Free Software Foundation may publish revised and/or new
-     versions of the General Public License from time to time.  Such
-     new versions will be similar in spirit to the present version, but
-     may differ in detail to address new problems or concerns.
-
-     Each version is given a distinguishing version number.  If the
-     Program specifies a version number of this License which applies
-     to it and "any later version", you have the option of following
-     the terms and conditions either of that version or of any later
-     version published by the Free Software Foundation.  If the Program
-     does not specify a version number of this License, you may choose
-     any version ever published by the Free Software Foundation.
-
- 11. If you wish to incorporate parts of the Program into other free
-     programs whose distribution conditions are different, write to the
-     author to ask for permission.  For software which is copyrighted
-     by the Free Software Foundation, write to the Free Software
-     Foundation; we sometimes make exceptions for this.  Our decision
-     will be guided by the two goals of preserving the free status of
-     all derivatives of our free software and of promoting the sharing
-     and reuse of software generally.
-
-                                NO WARRANTY
-
- 12. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO
-     WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE
-     LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-     HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
-     WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT
-     NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-     FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE
-     QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-     PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY
-     SERVICING, REPAIR OR CORRECTION.
-
- 13. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-     WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY
-     MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE
-     LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
-     INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
-     INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-     DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU
-     OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY
-     OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN
-     ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
-                      END OF TERMS AND CONDITIONS
-How to Apply These Terms to Your New Programs
-=============================================
-
-If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these
-terms.
-
-   To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-     ONE LINE TO GIVE THE PROGRAM'S NAME AND AN IDEA OF WHAT IT DOES.
-     Copyright (C) 19YY  NAME OF AUTHOR
-
-     This program is free software; you can redistribute it and/or
-     modify it under the terms of the GNU General Public License
-     as published by the Free Software Foundation; either version 2
-     of the License, or (at your option) any later version.
-
-     This program is distributed in the hope that it will be useful,
-     but WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-     GNU General Public License for more details.
-
-     You should have received a copy of the GNU General Public License along
-     with this program; if not, write to the Free Software Foundation, Inc.,
-     59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-
-   Also add information on how to contact you by electronic and paper
-mail.
-
-   If the program is interactive, make it output a short notice like
-this when it starts in an interactive mode:
-
-     Gnomovision version 69, Copyright (C) 19YY NAME OF AUTHOR
-     Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
-     type `show w'.  This is free software, and you are welcome
-     to redistribute it under certain conditions; type `show c'
-     for details.
-
-   The hypothetical commands `show w' and `show c' should show the
-appropriate parts of the General Public License.  Of course, the
-commands you use may be called something other than `show w' and `show
-c'; they could even be mouse-clicks or menu items--whatever suits your
-program.
-
-   You should also get your employer (if you work as a programmer) or
-your school, if any, to sign a "copyright disclaimer" for the program,
-if necessary.  Here is a sample; alter the names:
-
-     Yoyodyne, Inc., hereby disclaims all copyright
-     interest in the program `Gnomovision'
-     (which makes passes at compilers) written
-     by James Hacker.
-
-     SIGNATURE OF TY COON, 1 April 1989
-     Ty Coon, President of Vice
-
-   This General Public License does not permit incorporating your
-program into proprietary programs.  If your program is a subroutine
-library, you may consider it more useful to permit linking proprietary
-applications with the library.  If this is what you want to do, use the
-GNU Library General Public License instead of this License.
-
-\1f
-File: gcrypt.info,  Node: Figures and Tables,  Next: Concept Index,  Prev: Copying,  Up: Top
-
-List of Figures and Tables
-**************************
-
-* Menu:
-
-* Figure 16.1: Libgcrypt subsystems:     fig:subsystems.
-* Figure B.1: FIPS mode state ...:       fig:fips-fsm.
-
-* Menu:
-
-* Table B.1: FIPS mode states:           tbl:fips-states.
-* Table B.2: FIPS mode state ...:        tbl:fips-state-transitions.
-
-\1f
-File: gcrypt.info,  Node: Concept Index,  Next: Function and Data Index,  Prev: Figures and Tables,  Up: Top
-
-Concept Index
-*************
-
-\0\b[index\0\b]
-* Menu:
-
-* 3DES:                                  Available ciphers.    (line 14)
-* Advanced Encryption Standard:          Available ciphers.    (line 35)
-* AES:                                   Available ciphers.    (line 35)
-* AES-Wrap mode:                         Available cipher modes.
-                                                               (line 32)
-* Arcfour:                               Available ciphers.    (line 52)
-* Blowfish:                              Available ciphers.    (line 22)
-* bug emulation:                         Working with hash algorithms.
-                                                               (line 36)
-* Camellia:                              Available ciphers.    (line 77)
-* CAST5:                                 Available ciphers.    (line 19)
-* CBC, Cipher Block Chaining mode:       Available cipher modes.
-                                                               (line 20)
-* CBC-MAC:                               Working with cipher handles.
-                                                               (line 55)
-* CCM, Counter with CBC-MAC mode:        Available cipher modes.
-                                                               (line 45)
-* CFB, Cipher Feedback mode:             Available cipher modes.
-                                                               (line 16)
-* cipher text stealing:                  Working with cipher handles.
-                                                               (line 48)
-* comp:                                  Cryptographic Functions.
-                                                               (line 13)
-* CRC32:                                 Available hash algorithms.
-                                                               (line  6)
-* CTR, Counter mode:                     Available cipher modes.
-                                                               (line 29)
-* DES:                                   Available ciphers.    (line 57)
-* DES-EDE:                               Available ciphers.    (line 14)
-* Digital Encryption Standard:           Available ciphers.    (line 14)
-* ECB, Electronic Codebook mode:         Available cipher modes.
-                                                               (line 13)
-* EdDSA:                                 Cryptographic Functions.
-                                                               (line 33)
-* Enforced FIPS mode:                    Enabling FIPS mode.   (line 30)
-* error codes:                           Error Values.         (line  6)
-* error codes, list of <1>:              Error Codes.          (line  6)
-* error codes, list of:                  Error Sources.        (line  6)
-* error codes, printing of:              Error Strings.        (line  6)
-* error sources:                         Error Values.         (line  6)
-* error sources, printing of:            Error Strings.        (line  6)
-* error strings:                         Error Strings.        (line  6)
-* error values:                          Error Values.         (line  6)
-* error values, printing of:             Error Strings.        (line  6)
-* FIPS 140:                              Enabling FIPS mode.   (line  6)
-* FIPS 186 <1>:                          Public-Key Subsystem Architecture.
-                                                               (line 51)
-* FIPS 186:                              Cryptographic Functions.
-                                                               (line 66)
-* FIPS 186-2:                            Cryptographic Functions.
-                                                               (line 74)
-* FIPS mode:                             Enabling FIPS mode.   (line  6)
-* GCM, Galois/Counter Mode:              Available cipher modes.
-                                                               (line 50)
-* GOST 28147-89:                         Available ciphers.    (line 88)
-* GPL, GNU General Public License:       Copying.              (line  6)
-* hardware features:                     Hardware features.    (line  6)
-* HAVAL:                                 Available hash algorithms.
-                                                               (line  6)
-* HMAC:                                  Working with hash algorithms.
-                                                               (line 27)
-* HMAC-GOSTR-3411-94:                    Available MAC algorithms.
-                                                               (line  6)
-* HMAC-MD2, HMAC-MD4, HMAC-MD5:          Available MAC algorithms.
-                                                               (line  6)
-* HMAC-RIPE-MD-160:                      Available MAC algorithms.
-                                                               (line  6)
-* HMAC-SHA-1:                            Available MAC algorithms.
-                                                               (line  6)
-* HMAC-SHA-224, HMAC-SHA-256, HMAC-SHA-384, HMAC-SHA-512: Available MAC algorithms.
-                                                               (line  6)
-* HMAC-Stribog-256, HMAC-Stribog-512:    Available MAC algorithms.
-                                                               (line  6)
-* HMAC-TIGER1:                           Available MAC algorithms.
-                                                               (line  6)
-* HMAC-Whirlpool:                        Available MAC algorithms.
-                                                               (line  6)
-* IDEA:                                  Available ciphers.    (line 11)
-* LGPL, GNU Lesser General Public License: Library Copying.    (line  6)
-* MD2, MD4, MD5:                         Available hash algorithms.
-                                                               (line  6)
-* no-blinding:                           Cryptographic Functions.
-                                                               (line 41)
-* nocomp:                                Cryptographic Functions.
-                                                               (line 13)
-* OAEP:                                  Cryptographic Functions.
-                                                               (line 27)
-* OFB, Output Feedback mode:             Available cipher modes.
-                                                               (line 26)
-* param:                                 Cryptographic Functions.
-                                                               (line 47)
-* PKCS1:                                 Cryptographic Functions.
-                                                               (line 23)
-* PSS:                                   Cryptographic Functions.
-                                                               (line 30)
-* RC2:                                   Available ciphers.    (line 69)
-* RC4:                                   Available ciphers.    (line 52)
-* rfc-2268:                              Available ciphers.    (line 69)
-* RFC6979:                               Cryptographic Functions.
-                                                               (line 38)
-* Rijndael:                              Available ciphers.    (line 35)
-* RIPE-MD-160:                           Available hash algorithms.
-                                                               (line  6)
-* Salsa20:                               Available ciphers.    (line 81)
-* Salsa20/12:                            Available ciphers.    (line 84)
-* Seed (cipher):                         Available ciphers.    (line 72)
-* Serpent:                               Available ciphers.    (line 65)
-* SHA-1:                                 Available hash algorithms.
-                                                               (line  6)
-* SHA-224, SHA-256, SHA-384, SHA-512:    Available hash algorithms.
-                                                               (line  6)
-* sync mode (OpenPGP):                   Working with cipher handles.
-                                                               (line 43)
-* TIGER, TIGER1, TIGER2:                 Available hash algorithms.
-                                                               (line  6)
-* transient-key:                         Cryptographic Functions.
-                                                               (line 52)
-* Triple-DES:                            Available ciphers.    (line 14)
-* Twofish:                               Available ciphers.    (line 46)
-* Whirlpool:                             Available hash algorithms.
-                                                               (line  6)
-* X9.31 <1>:                             Public-Key Subsystem Architecture.
-                                                               (line 51)
-* X9.31:                                 Cryptographic Functions.
-                                                               (line 59)
-
diff --git a/doc/gcrypt.info-2 b/doc/gcrypt.info-2
deleted file mode 100644 (file)
index 77e74e4..0000000
Binary files a/doc/gcrypt.info-2 and /dev/null differ
index 9e9d436..c2c39ad 100644 (file)
@@ -14,7 +14,7 @@ which is GNU's library of cryptographic building blocks.
 
 @noindent
 Copyright @copyright{} 2000, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2011, 2012 Free Software Foundation, Inc. @*
-Copyright @copyright{} 2012, 2013 g10 Code GmbH
+Copyright @copyright{} 2012, 2013, 2016 g10 Code GmbH
 
 @quotation
 Permission is granted to copy, distribute and/or modify this document
@@ -94,7 +94,8 @@ section entitled ``GNU General Public License''.
 * MPI library::                  How to work with multi-precision-integers.
 * Prime numbers::                How to use the Prime number related functions.
 * Utilities::                    Utility functions.
-* Tools::                        Utility tools
+* Tools::                        Utility tools.
+* Configuration::                Configuration files and evironment variables.
 * Architecture::                 How Libgcrypt works internally.
 
 Appendices
@@ -188,8 +189,8 @@ the same handle, he has to take care of the serialization of such
 functions himself.  If not described otherwise, every function is
 thread-safe.
 
-Libgcrypt depends on the library `libgpg-error', which
-contains common error handling related code for GnuPG components.
+Libgcrypt depends on the library `libgpg-error', which contains some
+common code used by other GnuPG components.
 
 @c **********************************************************
 @c *******************  Preparation  ************************
@@ -267,9 +268,9 @@ example shows how it can be used at the command line:
 gcc -c foo.c `libgcrypt-config --cflags`
 @end example
 
-Adding the output of @samp{libgcrypt-config --cflags} to the compilers
-command line will ensure that the compiler can find the Libgcrypt header
-file.
+Adding the output of @samp{libgcrypt-config --cflags} to the
+compiler’s command line will ensure that the compiler can find the
+Libgcrypt header file.
 
 A similar problem occurs when linking the program with the library.
 Again, the compiler has to find the library files.  For this to work,
@@ -314,7 +315,20 @@ found, execute @var{action-if-found}, otherwise do
 Additionally, the function defines @code{LIBGCRYPT_CFLAGS} to the
 flags needed for compilation of the program to find the
 @file{gcrypt.h} header file, and @code{LIBGCRYPT_LIBS} to the linker
-flags needed to link the program to the Libgcrypt library.
+flags needed to link the program to the Libgcrypt library.  If the
+used helper script does not match the target type you are building for
+a warning is printed and the string @code{libgcrypt} is appended to the
+variable @code{gpg_config_script_warn}.
+
+This macro searches for @command{libgcrypt-config} along the PATH.  If
+you are cross-compiling, it is useful to set the environment variable
+@code{SYSROOT} to the top directory of your target.  The macro will
+then first look for the helper program in the @file{bin} directory
+below that top directory.  An absolute directory name must be used for
+@code{SYSROOT}.  Finally, if the configure command line option
+@code{--with-libgcrypt-prefix} is used, only its value is used for the top
+directory below which the helper script is expected.
+
 @end defmac
 
 You can use the defined Autoconf variables like this in your
@@ -343,8 +357,7 @@ after program startup.
 
 The function @code{gcry_check_version} initializes some subsystems used
 by Libgcrypt and must be invoked before any other function in the
-library, with the exception of the @code{GCRYCTL_SET_THREAD_CBS} command
-(called via the @code{gcry_control} function).
+library.
 @xref{Multi-Threading}.
 
 Furthermore, this function returns the version number of the library.
@@ -369,7 +382,7 @@ memory is not a problem, you should initialize Libgcrypt this way:
 
 @example
   /* Version check should be the very first call because it
-     makes sure that important subsystems are intialized. */
+     makes sure that important subsystems are initialized. */
   if (!gcry_check_version (GCRYPT_VERSION))
     @{
       fputs ("libgcrypt version mismatch\n", stderr);
@@ -450,51 +463,16 @@ thread-safe if you adhere to the following requirements:
 
 @itemize @bullet
 @item
-If your application is multi-threaded, you must set the thread support
-callbacks with the @code{GCRYCTL_SET_THREAD_CBS} command
-@strong{before} any other function in the library.
-
-This is easy enough if you are indeed writing an application using
-Libgcrypt.  It is rather problematic if you are writing a library
-instead.  Here are some tips what to do if you are writing a library:
-
-If your library requires a certain thread package, just initialize
-Libgcrypt to use this thread package.  If your library supports multiple
-thread packages, but needs to be configured, you will have to
-implement a way to determine which thread package the application
-wants to use with your library anyway.  Then configure Libgcrypt to use
-this thread package.
-
-If your library is fully reentrant without any special support by a
-thread package, then you are lucky indeed.  Unfortunately, this does
-not relieve you from doing either of the two above, or use a third
-option.  The third option is to let the application initialize Libgcrypt
-for you.  Then you are not using Libgcrypt transparently, though.
-
-As if this was not difficult enough, a conflict may arise if two
-libraries try to initialize Libgcrypt independently of each others, and
-both such libraries are then linked into the same application.  To
-make it a bit simpler for you, this will probably work, but only if
-both libraries have the same requirement for the thread package.  This
-is currently only supported for the non-threaded case, GNU Pth and
-pthread.
-
 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.
 
-Note that future versions of Libgcrypt will drop this flexible thread
-support and instead only support the platforms standard thread
-implementation.
-
 
 @item
 The function @code{gcry_check_version} must be called before any other
-function in the library, except the @code{GCRYCTL_SET_THREAD_CBS}
-command (called via the @code{gcry_control} function), because it
-initializes the thread support subsystem in Libgcrypt.  To
+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
@@ -515,57 +493,12 @@ Just like the function @code{gpg_strerror}, the function
 @end itemize
 
 
-Libgcrypt contains convenient macros, which define the
-necessary thread callbacks for PThread and for GNU Pth:
-
-@table @code
-@item GCRY_THREAD_OPTION_PTH_IMPL
-
-This macro defines the following (static) symbols:
-@code{gcry_pth_init}, @code{gcry_pth_mutex_init},
-@code{gcry_pth_mutex_destroy}, @code{gcry_pth_mutex_lock},
-@code{gcry_pth_mutex_unlock}, @code{gcry_pth_read},
-@code{gcry_pth_write}, @code{gcry_pth_select},
-@code{gcry_pth_waitpid}, @code{gcry_pth_accept},
-@code{gcry_pth_connect}, @code{gcry_threads_pth}.
-
-After including this macro, @code{gcry_control()} shall be used with a
-command of @code{GCRYCTL_SET_THREAD_CBS} in order to register the
-thread callback structure named ``gcry_threads_pth''.  Example:
-
-@smallexample
-  ret = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth);
-@end smallexample
-
-
-@item GCRY_THREAD_OPTION_PTHREAD_IMPL
-
-This macro defines the following (static) symbols:
-@code{gcry_pthread_mutex_init}, @code{gcry_pthread_mutex_destroy},
-@code{gcry_pthread_mutex_lock}, @code{gcry_pthread_mutex_unlock},
-@code{gcry_threads_pthread}.
-
-After including this macro, @code{gcry_control()} shall be used with a
-command of @code{GCRYCTL_SET_THREAD_CBS} in order to register the
-thread callback structure named ``gcry_threads_pthread''.  Example:
-
-@smallexample
-  ret = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
-@end smallexample
-
-
-@end table
-
-Note that these macros need to be terminated with a semicolon.  Keep
-in mind that these are convenient macros for C programmers; C++
-programmers might have to wrap these macros in an ``extern C'' body.
-
-
 @node Enabling FIPS mode
 @section How to enable the FIPS mode
 @cindex FIPS mode
 @cindex FIPS 140
 
+@anchor{enabling fips mode}
 Libgcrypt may be used in a FIPS 140-2 mode.  Note, that this does not
 necessary mean that Libcgrypt is an appoved FIPS 140-2 module.  Check the
 NIST database at @url{http://csrc.nist.gov/groups/STM/cmvp/} to see what
@@ -614,6 +547,7 @@ If the logging verbosity level of Libgcrypt has been set to at least
 @section How to disable hardware features
 @cindex hardware features
 
+@anchor{hardware features}
 Libgcrypt makes use of certain hardware features.  If the use of a
 feature is not desired it may be either be disabled by a program or
 globally using a configuration file.  The currently supported features
@@ -625,6 +559,7 @@ are
 @item padlock-sha
 @item padlock-mmul
 @item intel-cpu
+@item intel-fast-shld
 @item intel-bmi2
 @item intel-ssse3
 @item intel-pclmul
@@ -863,8 +798,7 @@ This command returns true if the command@*
 GCRYCTL_INITIALIZATION_FINISHED has already been run.
 
 @item GCRYCTL_SET_THREAD_CBS; Arguments: struct ath_ops *ath_ops
-This command registers a thread-callback structure.
-@xref{Multi-Threading}.
+This command is obsolete since version 1.6.
 
 @item GCRYCTL_FAST_POLL; Arguments: none
 Run a fast random poll.
@@ -951,7 +885,7 @@ The default is @code{GCRY_RNG_TYPE_STANDARD} unless FIPS mode as been
 enabled; in which case @code{GCRY_RNG_TYPE_FIPS} is used and locked
 against further changes.
 
-@item GCRYCTL_GETT_CURRENT_RNG_TYPE; Arguments: int *
+@item GCRYCTL_GET_CURRENT_RNG_TYPE; Arguments: int *
 This command stores the type of the currently used RNG as an integer
 value at the provided address.
 
@@ -1647,6 +1581,10 @@ This is the Salsa20/12 - reduced round version of Salsa20 stream cipher.
 The GOST 28147-89 cipher, defined in the respective GOST standard.
 Translation of this GOST into English is provided in the RFC-5830.
 
+@item GCRY_CIPHER_CHACHA20
+@cindex ChaCha20
+This is the ChaCha20 stream cipher.
+
 @end table
 
 @node Available cipher modes
@@ -1663,9 +1601,12 @@ set, this mode may be used to bypass the actual encryption.
 Electronic Codebook mode.
 
 @item GCRY_CIPHER_MODE_CFB
+@item GCRY_CIPHER_MODE_CFB8
 @cindex CFB, Cipher Feedback mode
-Cipher Feedback mode.  The shift size equals the block size of the
-cipher (e.g. for AES it is CFB-128).
+Cipher Feedback mode.  For GCRY_CIPHER_MODE_CFB the shift size equals
+the block size of the cipher (e.g. for AES it is CFB-128).  For
+GCRY_CIPHER_MODE_CFB8 the shift size is 8 bit but that variant is not
+yet available.
 
 @item  GCRY_CIPHER_MODE_CBC
 @cindex CBC, Cipher Block Chaining mode
@@ -1708,6 +1649,24 @@ Galois/Counter Mode (GCM) is an Authenticated Encryption with
 Associated Data (AEAD) block cipher mode, which is specified in
 'NIST Special Publication 800-38D'.
 
+@item  GCRY_CIPHER_MODE_POLY1305
+@cindex Poly1305 based AEAD mode with ChaCha20
+This mode implements the Poly1305 Authenticated Encryption with Associated
+Data (AEAD) mode according to RFC-7539. This mode can be used with ChaCha20
+stream cipher.
+
+@item  GCRY_CIPHER_MODE_OCB
+@cindex OCB, OCB3
+OCB is an Authenticated Encryption with Associated Data (AEAD) block
+cipher mode, which is specified in RFC-7253.  Supported tag lengths
+are 128, 96, and 64 bit with the default being 128 bit.  To switch to
+a different tag length @code{gcry_cipher_ctl} using the command
+@code{GCRYCTL_SET_TAGLEN} and the address of an @code{int} variable
+set to 12 (for 96 bit) or 8 (for 64 bit) provided for the
+@code{buffer} argument and @code{sizeof(int)} for @code{buflen}.
+
+Note that the use of @code{gcry_cipher_final} is required.
+
 @end table
 
 @node Working with cipher handles
@@ -1734,13 +1693,16 @@ The cipher mode to use must be specified via @var{mode}.  See
 @xref{Available cipher modes}, for a list of supported cipher modes
 and the according constants.  Note that some modes are incompatible
 with some algorithms - in particular, stream mode
-(@code{GCRY_CIPHER_MODE_STREAM}) only works with stream ciphers. The
-block cipher modes (@code{GCRY_CIPHER_MODE_ECB},
-@code{GCRY_CIPHER_MODE_CBC}, @code{GCRY_CIPHER_MODE_CFB},
-@code{GCRY_CIPHER_MODE_OFB} and @code{GCRY_CIPHER_MODE_CTR}) will work
-with any block cipher algorithm. @code{GCRY_CIPHER_MODE_CCM} and
-@code{GCRY_CIPHER_MODE_GCM} modes will only work with block cipher algorithms
-which have the block size of 16 bytes.
+(@code{GCRY_CIPHER_MODE_STREAM}) only works with stream ciphers.
+Poly1305 AEAD mode (@code{GCRY_CIPHER_MODE_POLY1305}) only works with
+ChaCha20 stream cipher. The block cipher modes
+(@code{GCRY_CIPHER_MODE_ECB}, @code{GCRY_CIPHER_MODE_CBC},
+@code{GCRY_CIPHER_MODE_CFB}, @code{GCRY_CIPHER_MODE_OFB} and
+@code{GCRY_CIPHER_MODE_CTR}) will work with any block cipher
+algorithm.  GCM mode (@code{GCRY_CIPHER_MODE_CCM}), CCM mode
+(@code{GCRY_CIPHER_MODE_GCM}), and OCB mode
+(@code{GCRY_CIPHER_MODE_OCB}) will only work with block cipher
+algorithms which have the block size of 16 bytes.
 
 The third argument @var{flags} can either be passed as @code{0} or as
 the bit-wise OR of the following constants.
@@ -1803,12 +1765,9 @@ vector is passed as the buffer @var{K} of length @var{l} bytes and
 copied to internal data structures.  The function checks that the IV
 matches the requirement of the selected algorithm and mode.
 
-This function is also used with the Salsa20 stream cipher to set or
-update the required nonce.  In this case it needs to be called after
-setting the key.
-
-This function is also used with the AEAD cipher modes to set or
-update the required nonce.
+This function is also used by AEAD modes and with Salsa20 and ChaCha20
+stream ciphers to set or update the required nonce.  In these cases it
+needs to be called after setting the key.
 
 @end deftypefun
 
@@ -1841,15 +1800,23 @@ authenticated data (AAD) for AEAD cipher modes.
 
 @end deftypefun
 
-@deftypefun gcry_error_t gcry_cipher_gettag (gcry_cipher_hd_t @var{h}, void *@var{tag}, size_t @var{taglen})
+@deftypefun {gcry_error_t} gcry_cipher_gettag @
+            (@w{gcry_cipher_hd_t @var{h}}, @
+            @w{void *@var{tag}}, @w{size_t @var{taglen}})
 
 This function is used to read the authentication tag after encryption.
 The function finalizes and outputs the authentication tag to the buffer
 @var{tag} of length @var{taglen} bytes.
 
+Depending on the used mode certain restrictions for @var{taglen} are
+enforced:  For GCM @var{taglen} must be at least 16 or one of the
+allowed truncated lengths (4, 8, 12, 13, 14, or 15).
+
 @end deftypefun
 
-@deftypefun gcry_error_t gcry_cipher_checktag (gcry_cipher_hd_t @var{h}, const void *@var{tag}, size_t @var{taglen})
+@deftypefun {gcry_error_t} gcry_cipher_checktag @
+            (@w{gcry_cipher_hd_t @var{h}}, @
+            @w{const void *@var{tag}}, @w{size_t @var{taglen}})
 
 Check the authentication tag after decryption. The authentication
 tag is passed as the buffer @var{tag} of length @var{taglen} bytes
@@ -1858,6 +1825,10 @@ decryption.  Error code @code{GPG_ERR_CHECKSUM} is returned if
 the authentication tag in the buffer @var{tag} does not match
 the authentication tag calculated during decryption.
 
+Depending on the used mode certain restrictions for @var{taglen} are
+enforced: For GCM @var{taglen} must either be 16 or one of the allowed
+truncated lengths (4, 8, 12, 13, 14, or 15).
+
 @end deftypefun
 
 The actual encryption and decryption is done by using one of the
@@ -1870,7 +1841,7 @@ all the data.
 can either work in place or with two buffers.  It uses the cipher
 context already setup and described by the handle @var{h}.  There are 2
 ways to use the function: If @var{in} is passed as @code{NULL} and
-@var{inlen} is @code{0}, in-place encryption of the data in @var{out} or
+@var{inlen} is @code{0}, in-place encryption of the data in @var{out} of
 length @var{outsize} takes place.  With @var{in} being not @code{NULL},
 @var{inlen} bytes are encrypted to the buffer @var{out} which must have
 at least a size of @var{inlen}.  @var{outsize} must be set to the
@@ -1880,6 +1851,9 @@ is sufficient space. Note that overlapping buffers are not allowed.
 Depending on the selected algorithms and encryption mode, the length of
 the buffers must be a multiple of the block size.
 
+Some encryption modes require that @code{gcry_cipher_final} is used
+before the final data chunk is passed to this function.
+
 The function returns @code{0} on success or an error code.
 @end deftypefun
 
@@ -1900,11 +1874,27 @@ is sufficient space.  Note that overlapping buffers are not allowed.
 Depending on the selected algorithms and encryption mode, the length of
 the buffers must be a multiple of the block size.
 
+Some encryption modes require that @code{gcry_cipher_final} is used
+before the final data chunk is passed to this function.
+
 The function returns @code{0} on success or an error code.
 @end deftypefun
 
 
-OpenPGP (as defined in RFC-2440) requires a special sync operation in
+The OCB mode features integrated padding and must thus be told about
+the end of the input data. This is done with:
+
+@deftypefun gcry_error_t gcry_cipher_final (gcry_cipher_hd_t @var{h})
+
+Set a flag in the context to tell the encrypt and decrypt functions
+that their next call will provide the last chunk of data.  Only the
+first call to this function has an effect and only for modes which
+support it.  Checking the error is in general not necessary.  This is
+implemented as a macro.
+@end deftypefun
+
+
+OpenPGP (as defined in RFC-4880) requires a special sync operation in
 some places.  The following function is used for this:
 
 @deftypefun gcry_error_t gcry_cipher_sync (gcry_cipher_hd_t @var{h})
@@ -1928,12 +1918,24 @@ handle @var{h}.  Please see the comments in the source code
 (@code{src/global.c}) for details.
 @end deftypefun
 
-@deftypefun gcry_error_t gcry_cipher_info (gcry_cipher_hd_t @var{h}, int @var{what}, void *@var{buffer}, size_t *@var{nbytes})
+@deftypefun gcry_error_t gcry_cipher_info (gcry_cipher_hd_t @var{h}, @
+              int @var{what}, void *@var{buffer}, size_t *@var{nbytes})
 
 @code{gcry_cipher_info} is used to retrieve various
 information about a cipher context or the cipher module in general.
 
-Currently no information is available.
+@c begin constants for gcry_cipher_info
+@table @code
+
+@item GCRYCTL_GET_TAGLEN:
+Return the length of the tag for an AE algorithm mode.  An error is
+returned for modes which do not support a tag.  @var{buffer} must be
+given as NULL.  On success the result is stored @var{nbytes}.  The
+taglen is returned in bytes.
+
+@end table
+@c end constants for gcry_cipher_info
+
 @end deftypefun
 
 @node General cipher functions
@@ -2356,6 +2358,13 @@ random number generator.  This flag may be used for keys which are
 only used for a short time or per-message and do not require full
 cryptographic strength.
 
+@item no-keytest
+@cindex no-keytest
+This flag skips internal failsafe tests to assert that a generated key
+is properly working.  It currently has an effect only for standard ECC
+key generation.  It is mostly useful along with transient-key to
+achieve fastest ECC key generation.
+
 @item use-x931
 @cindex X9.31
 Force the use of the ANSI X9.31 key generation algorithm instead of
@@ -2766,7 +2775,7 @@ operations.  @var{cmd} controls what is to be done. The return value is
 Disable the algorithm given as an algorithm id in @var{buffer}.
 @var{buffer} must point to an @code{int} variable with the algorithm
 id and @var{buflen} must have the value @code{sizeof (int)}.  This
-fucntion is not thread safe and should thus be used before any other
+function is not thread safe and should thus be used before any other
 threads are started.
 
 @end table
@@ -3058,6 +3067,7 @@ are also supported.
 @c begin table of hash algorithms
 @cindex SHA-1
 @cindex SHA-224, SHA-256, SHA-384, SHA-512
+@cindex SHA3-224, SHA3-256, SHA3-384, SHA3-512, SHAKE128, SHAKE256
 @cindex RIPE-MD-160
 @cindex MD2, MD4, MD5
 @cindex TIGER, TIGER1, TIGER2
@@ -3130,6 +3140,32 @@ See FIPS 180-2 for the specification.
 This is the SHA-384 algorithm which yields a message digest of 64 bytes.
 See FIPS 180-2 for the specification.
 
+@item GCRY_MD_SHA3_224
+This is the SHA3-224 algorithm which yields a message digest of 28 bytes.
+See FIPS 202 for the specification.
+
+@item GCRY_MD_SHA3_256
+This is the SHA3-256 algorithm which yields a message digest of 32 bytes.
+See FIPS 202 for the specification.
+
+@item GCRY_MD_SHA3_384
+This is the SHA3-384 algorithm which yields a message digest of 48 bytes.
+See FIPS 202 for the specification.
+
+@item GCRY_MD_SHA3_512
+This is the SHA3-384 algorithm which yields a message digest of 64 bytes.
+See FIPS 202 for the specification.
+
+@item GCRY_MD_SHAKE128
+This is the SHAKE128 extendable-output function (XOF) algorithm with 128 bit
+security strength.
+See FIPS 202 for the specification.
+
+@item GCRY_MD_SHAKE256
+This is the SHAKE256 extendable-output function (XOF) algorithm with 256 bit
+security strength.
+See FIPS 202 for the specification.
+
 @item GCRY_MD_CRC32
 This is the ISO 3309 and ITU-T V.42 cyclic redundancy check.  It yields
 an output of 4 bytes.  Note that this is not a hash algorithm in the
@@ -3192,11 +3228,12 @@ this is the hashed data is highly confidential.
 @item GCRY_MD_FLAG_HMAC
 @cindex HMAC
 Turn the algorithm into a HMAC message authentication algorithm.  This
-only works if just one algorithm is enabled for the handle.  Note that
-the function @code{gcry_md_setkey} must be used to set the MAC key.
-The size of the MAC is equal to the message digest of the underlying
-hash algorithm.  If you want CBC message authentication codes based on
-a cipher, see @xref{Working with cipher handles}.
+only works if just one algorithm is enabled for the handle and that
+algorithm is not an extendable-output function.  Note that the function
+@code{gcry_md_setkey} must be used to set the MAC key.  The size of the
+MAC is equal to the message digest of the underlying hash algorithm.
+If you want CBC message authentication codes based on a cipher,
+see @xref{Working with cipher handles}.
 
 @item GCRY_MD_FLAG_BUGEMU1
 @cindex bug emulation
@@ -3293,7 +3330,11 @@ by just one character.  Both methods can be used on the same hash context.
 
 Pass @var{length} bytes of the data in @var{buffer} to the digest object
 with handle @var{h} to update the digest values. This
-function should be used for large blocks of data.
+function should be used for large blocks of data.  If this function is
+used after the context has been finalized, it will keep on pushing
+the data through the algorithm specific transform function and change
+the context; however the results are not meaningful and this feature
+is only available to mitigate timing attacks.
 @end deftypefun
 
 @deftypefun void gcry_md_putc (gcry_md_hd_t @var{h}, int @var{c})
@@ -3311,9 +3352,11 @@ message digest or some padding.
 @deftypefun void gcry_md_final (gcry_md_hd_t @var{h})
 
 Finalize the message digest calculation.  This is not really needed
-because @code{gcry_md_read} does this implicitly.  After this has been
-done no further updates (by means of @code{gcry_md_write} or
-@code{gcry_md_putc} are allowed.  Only the first call to this function
+because @code{gcry_md_read} and @code{gcry_md_extract} do this implicitly.
+After this has been done no further updates (by means of @code{gcry_md_write}
+or @code{gcry_md_putc} should be done; However, to mitigate timing
+attacks it is sometimes useful to keep on updating the context after
+having stored away the actual digest.  Only the first call to this function
 has an effect. It is implemented as a macro.
 @end deftypefun
 
@@ -3326,13 +3369,30 @@ function:
 calculation.  This function may be used as often as required but it will
 always return the same value for one handle.  The returned message digest
 is allocated within the message context and therefore valid until the
-handle is released or reseted (using @code{gcry_md_close} or
-@code{gcry_md_reset}.  @var{algo} may be given as 0 to return the only
+handle is released or reset-ed (using @code{gcry_md_close} or
+@code{gcry_md_reset} or it has been updated as a mitigation measure
+against timing attacks.  @var{algo} may be given as 0 to return the only
 enabled message digest or it may specify one of the enabled algorithms.
 The function does return @code{NULL} if the requested algorithm has not
 been enabled.
 @end deftypefun
 
+The way to read output of extendable-output function is by using the
+function:
+
+@deftypefun gpg_err_code_t gcry_md_extract (gcry_md_hd_t @var{h}, @
+  int @var{algo}, void *@var{buffer}, size_t @var{length})
+
+@code{gcry_mac_read} returns output from extendable-output function.
+This function may be used as often as required to generate more output
+byte stream from the algorithm.  Function extracts the new output bytes
+to @var{buffer} of the length @var{length}.  Buffer will be fully
+populated with new output.  @var{algo} may be given as 0 to return the only
+enabled message digest or it may specify one of the enabled algorithms.
+The function does return non-zero value if the requested algorithm has not
+been enabled.
+@end deftypefun
+
 Because it is often necessary to get the message digest of blocks of
 memory, two fast convenience function are available for this task:
 
@@ -3343,7 +3403,7 @@ memory, two fast convenience function are available for this task:
 
 @code{gcry_md_hash_buffers} is a shortcut function to calculate a
 message digest from several buffers.  This function does not require a
-context and immediately returns the message digest of of the data
+context and immediately returns the message digest of the data
 described by @var{iov} and @var{iovcnt}.  @var{digest} must be
 allocated by the caller, large enough to hold the message digest
 yielded by the the specified algorithm @var{algo}.  This required size
@@ -3474,7 +3534,7 @@ hashed can be written to files on request.
 @deftypefun void gcry_md_debug (gcry_md_hd_t @var{h}, const char *@var{suffix})
 
 Enable debugging for the digest object with handle @var{h}.  This
-creates create files named @file{dbgmd-<n>.<string>} while doing the
+creates files named @file{dbgmd-<n>.<string>} while doing the
 actual hashing.  @var{suffix} is the string part in the filename.  The
 number is a counter incremented for each new hashing.  The data in the
 file is the raw data as passed to @code{gcry_md_write} or
@@ -3508,6 +3568,7 @@ provided by Libgcrypt.
 @c begin table of MAC algorithms
 @cindex HMAC-SHA-1
 @cindex HMAC-SHA-224, HMAC-SHA-256, HMAC-SHA-384, HMAC-SHA-512
+@cindex HMAC-SHA3-224, HMAC-SHA3-256, HMAC-SHA3-384, HMAC-SHA3-512
 @cindex HMAC-RIPE-MD-160
 @cindex HMAC-MD2, HMAC-MD4, HMAC-MD5
 @cindex HMAC-TIGER1
@@ -3535,6 +3596,22 @@ algorithm.
 This is HMAC message authentication algorithm based on the SHA-384 hash
 algorithm.
 
+@item GCRY_MAC_HMAC_SHA3_256
+This is HMAC message authentication algorithm based on the SHA3-384 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_SHA3_224
+This is HMAC message authentication algorithm based on the SHA3-224 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_SHA3_512
+This is HMAC message authentication algorithm based on the SHA3-512 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_SHA3_384
+This is HMAC message authentication algorithm based on the SHA3-384 hash
+algorithm.
+
 @item GCRY_MAC_HMAC_SHA1
 This is HMAC message authentication algorithm based on the SHA-1 hash
 algorithm.
@@ -3631,6 +3708,30 @@ block cipher algorithm.
 This is GMAC message authentication algorithm based on the SEED
 block cipher algorithm.
 
+@item GCRY_MAC_POLY1305
+This is plain Poly1305 message authentication algorithm, used with
+one-time key.
+
+@item GCRY_MAC_POLY1305_AES
+This is Poly1305-AES message authentication algorithm, used with
+key and one-time nonce.
+
+@item GCRY_MAC_POLY1305_CAMELLIA
+This is Poly1305-Camellia message authentication algorithm, used with
+key and one-time nonce.
+
+@item GCRY_MAC_POLY1305_TWOFISH
+This is Poly1305-Twofish message authentication algorithm, used with
+key and one-time nonce.
+
+@item GCRY_MAC_POLY1305_SERPENT
+This is Poly1305-Serpent message authentication algorithm, used with
+key and one-time nonce.
+
+@item GCRY_MAC_POLY1305_SEED
+This is Poly1305-SEED message authentication algorithm, used with
+key and one-time nonce.
+
 @end table
 @c end table of MAC algorithms
 
@@ -3676,8 +3777,8 @@ underlying block cipher.
 @end deftypefun
 
 
-GMAC algorithms need initialization vector to be set, which can be
-performed with function:
+GMAC algorithms and Poly1305-with-cipher algorithms need initialization vector to be set,
+which can be performed with function:
 
 @deftypefun gcry_error_t gcry_mac_setiv (gcry_mac_hd_t @var{h}, const void *@var{iv}, size_t @var{ivlen})
 
@@ -3716,10 +3817,13 @@ see how it is actually done.
 @deftypefun gcry_error_t gcry_mac_write (gcry_mac_hd_t @var{h}, const void *@var{buffer}, size_t @var{length})
 
 Pass @var{length} bytes of the data in @var{buffer} to the MAC object
-with handle @var{h} to update the MAC values.
+with handle @var{h} to update the MAC values.  If this function is
+used after the context has been finalized, it will keep on pushing the
+data through the algorithm specific transform function and thereby
+change the context; however the results are not meaningful and this
+feature is only available to mitigate timing attacks.
 @end deftypefun
 
-
 The way to read out the calculated MAC is by using the function:
 
 @deftypefun gcry_error_t gcry_mac_read (gcry_mac_hd_t @var{h}, void *@var{buffer}, size_t *@var{length})
@@ -3730,7 +3834,6 @@ Function copies the resulting MAC value to @var{buffer} of the length
 then length of MAC is returned through @var{length}.
 @end deftypefun
 
-
 To compare existing MAC value with recalculated MAC, one is to use the function:
 
 @deftypefun gcry_error_t gcry_mac_verify (gcry_mac_hd_t @var{h}, void *@var{buffer}, size_t @var{length})
@@ -3742,6 +3845,16 @@ the MAC calculated in object @var{h}.
 @end deftypefun
 
 
+In some situations it might be hard to remember the algorithm used for
+the MAC calculation. The following function might be used to get that
+information:
+
+@deftypefun {int} gcry_mac_get_algo (gcry_mac_hd_t @var{h})
+
+Retrieve the algorithm used with the handle @var{h}.
+@end deftypefun
+
+
 @c ***********************************
 @c ***** MAC info functions **********
 @c ***********************************
@@ -4097,7 +4210,7 @@ logging stream.
 @noindent
 Often canonical encoding is used in the external representation.  The
 following function can be used to check for valid encoding and to learn
-the length of the S-expression"
+the length of the S-expression.
 
 @deftypefun size_t gcry_sexp_canon_len (@w{const unsigned char *@var{buffer}}, @w{size_t @var{length}}, @w{size_t *@var{erroff}}, @w{int *@var{errcode}})
 
@@ -4253,8 +4366,10 @@ In general parameter names are single letters.  To use a string for a
 parameter name, enclose the name in single quotes.
 
 Unless in buffer descriptor mode for each parameter name a pointer to
-an @code{gcry_mpi_t} variable is expected finally followed by a @code{NULL}.
-For example
+an @code{gcry_mpi_t} variable is expected that must be set to
+@code{NULL} prior to invoking this function, and finally a @code{NULL}
+is expected.  For example
+
 @example
   _gcry_sexp_extract_param (key, NULL, "n/x+e d-'foo'",
                             &mpi_n, &mpi_x, &mpi_e, &mpi_foo, NULL)
@@ -4283,8 +4398,11 @@ number of bytes copied to that buffer; in case the buffer is too
 small, the function immediately returns with an error code (and
 @var{len} is set to 0).
 
-The function returns NULL on success.  On error an error code is
-returned and the passed MPIs are either unchanged or set to NULL.
+The function returns 0 on success.  On error an error code is
+returned, all passed MPIs that might have been allocated up to this
+point are deallocated and set to @code{NULL}, and all passed buffers
+are either truncated if the caller supplied the buffer, or deallocated
+if the function allocated the buffer.
 @end deftypefun
 
 
@@ -4414,7 +4532,8 @@ representation of an MPI and the internal one of Libgcrypt.
 Convert the external representation of an integer stored in @var{buffer}
 with a length of @var{buflen} into a newly created MPI returned which
 will be stored at the address of @var{r_mpi}.  For certain formats the
-length argument is not required and should be passed as @code{0}.  After a
+length argument is not required and should be passed as @code{0}. A
+@var{buflen} larger than 16 MiByte will be rejected.  After a
 successful operation the variable @var{nscanned} receives the number of
 bytes actually scanned unless @var{nscanned} was given as
 @code{NULL}. @var{format} describes the format of the MPI as stored in
@@ -4428,6 +4547,7 @@ bytes actually scanned unless @var{nscanned} was given as
 @item GCRYMPI_FMT_PGP
 As used by OpenPGP (only defined as unsigned). This is basically
 @code{GCRYMPI_FMT_STD} with a 2 byte big endian length header.
+A length header indicating a length of more than 16384 is not allowed.
 
 @item GCRYMPI_FMT_SSH
 As used in the Secure Shell protocol.  This is @code{GCRYMPI_FMT_STD}
@@ -4722,7 +4842,7 @@ newly allocated point object.
 @end deftypefun
 
 @anchor{gcry_mpi_ec_new}
-@deftypefun gpg_error_t gcry_mpi_ec_p_new (@w{gpg_ctx_t *@var{r_ctx}}, @
+@deftypefun gpg_error_t gcry_mpi_ec_new (@w{gcry_ctx_t *@var{r_ctx}}, @
  @w{gcry_sexp_t @var{keyparam}}, @w{const char *@var{curvename}})
 
 Allocate a new context for elliptic curve operations.  If
@@ -4799,6 +4919,19 @@ Valid names are the point parameters of an elliptic curve
 (@pxref{ecc_keyparam}).
 @end deftypefun
 
+@deftypefun gpg_err_code_t gcry_mpi_ec_decode_point ( @
+ @w{mpi_point_t @var{result}}, @w{gcry_mpi_t @var{value}}, @
+ @w{gcry_ctx_t @var{ctx}})
+
+Decode the point given as an MPI in @var{value} and store at
+@var{result}.  To decide which encoding is used the function takes a
+context @var{ctx} which can be created with @code{gcry_mpi_ec_new}.
+If @code{NULL} is given for the context the function assumes a 0x04
+prefixed uncompressed encoding.  On error an error code is returned
+and @var{result} might be changed.
+@end deftypefun
+
+
 @deftypefun int gcry_mpi_ec_get_affine ( @
  @w{gcry_mpi_t @var{x}}, @w{gcry_mpi_t @var{y}}, @
  @w{gcry_mpi_point_t @var{point}}, @w{gcry_ctx_t @var{ctx}})
@@ -4832,6 +4965,15 @@ Add the points @var{u} and @var{v} of the elliptic curve described by
 @var{ctx} and store the result into @var{w}.
 @end deftypefun
 
+@deftypefun void gcry_mpi_ec_sub ( @
+ @w{gcry_mpi_point_t @var{w}}, @w{gcry_mpi_point_t @var{u}}, @
+ @w{gcry_mpi_point_t @var{v}}, @w{gcry_ctx_t @var{ctx}})
+
+Subtracts the point @var{v} from the point @var{u} of the elliptic
+curve described by @var{ctx} and store the result into @var{w}. Only
+Twisted Edwards curves are supported for now.
+@end deftypefun
+
 @deftypefun void gcry_mpi_ec_mul ( @
  @w{gcry_mpi_point_t @var{w}}, @w{gcry_mpi_t @var{n}}, @
  @w{gcry_mpi_point_t @var{u}}, @w{gcry_ctx_t @var{ctx}})
@@ -5167,6 +5309,82 @@ Print version of the program and exit.
 @manpause
 
 @c **********************************************************
+@c ****************  Environment Variables  *****************
+@c **********************************************************
+@node Configuration
+@chapter Configuration files and evironment variables
+
+This chapter describes which files and environment variables can be
+used to change the behaviour of Libgcrypt.
+
+@noindent
+The environment variables considered by Libgcrypt are:
+
+@table @code
+
+@item GCRYPT_BARRETT
+@cindex GCRYPT_BARRETT
+By setting this variable to any value a different algorithm for
+modular reduction is used for ECC.
+
+@item GCRYPT_RNDUNIX_DBG
+@item GCRYPT_RNDUNIX_DBGALL
+@cindex GCRYPT_RNDUNIX_DBG
+@cindex GCRYPT_RNDUNIX_DBGALL
+These two environment variables are used to enable debug output for
+the rndunix entropy gatherer, which is used on systems lacking a
+/dev/random device.  The value of @code{GCRYPT_RNDUNIX_DBG} is a file
+name or @code{-} for stdout.  Debug output is the written to this
+file.  By setting @code{GCRYPT_RNDUNIX_DBGALL} to any value the debug
+output will be more verbose.
+
+@item GCRYPT_RNDW32_NOPERF
+@cindex GCRYPT_RNDW32_NOPERF
+Setting this environment variable on Windows to any value disables
+the use of performance data (@code{HKEY_PERFORMANCE_DATA}) as source
+for entropy.  On some older Windows systems this could help to speed
+up the creation of random numbers but also decreases the amount of
+data used to init the random number generator.
+
+@item HOME
+@cindex HOME
+This is used to locate the socket to connect to the EGD random
+daemon.  The EGD can be used on system without a /dev/random to speed
+up the random number generator.  It is not needed on the majority of
+today's operating systems and support for EGD requires the use of a
+configure option at build time.
+
+@end table
+
+@noindent
+The files which Libgcrypt uses to retrieve system information and the
+files which can be created by the user to modify Libgcrypt's behavior
+are:
+
+@table @file
+
+@item /etc/gcrypt/hwf.deny
+@cindex /etc/gcrypt/hwf.deny
+This file can be used to disable the use of hardware based
+optimizations, @pxref{hardware features}.
+
+@item /etc/gcrypt/fips_enabled
+@itemx /proc/sys/crypto/fips_enabled
+@cindex /etc/gcrypt/fips_enabled
+@cindex fips_enabled
+On Linux these files are used to enable FIPS mode, @pxref{enabling fips mode}.
+
+@item /proc/cpuinfo
+@itemx /proc/self/auxv
+@cindex /proc/cpuinfo
+@cindex /proc/self/auxv
+On Linux running on the ARM architecture, these files are used to read
+hardware capabilities of the CPU.
+
+@end table
+
+
+@c **********************************************************
 @c *****************  Architecure Overview  *****************
 @c **********************************************************
 @node Architecture
@@ -5529,9 +5747,9 @@ that system and is the only gathering module available for that OS.
 
 @item rndhw
 Extra module to collect additional entropy by utilizing a hardware
-random number generator.  As of now the only supported hardware RNG is
-the Padlock engine of VIA (Centaur) CPUs.  It is not available in FIPS
-mode.
+random number generator.  As of now the supported hardware RNG is
+the Padlock engine of VIA (Centaur) CPUs and x86 CPUs with the RDRAND
+instruction.  It is not available in FIPS mode.
 
 @end table
 
@@ -5551,7 +5769,7 @@ Practically Strong Random Numbers".@footnote{Also described in chapter
 6 of his book "Cryptographic Security Architecture", New York, 2004,
 ISBN 0-387-95387-6.}
 
-A pool of 600 bytes is used and mixed using the core RIPE-MD160 hash
+A pool of 600 bytes is used and mixed using the core SHA-1 hash
 transform function.  Several extra features are used to make the
 robust against a wide variety of attacks and to protect against
 failures of subsystems.  The state of the generator may be saved to a
index c058a72..d33ce9f 100644 (file)
@@ -1,7 +1,7 @@
 %!PS-Adobe-3.0 EPSF-3.0
 %%Title: /home/wk/s/libgcrypt/doc/libgcrypt-modules.fig
-%%Creator: fig2dev Version 3.2 Patchlevel 5d
-%%CreationDate: Wed Jan 29 11:42:20 2014
+%%Creator: fig2dev Version 3.2 Patchlevel 5e
+%%CreationDate: Tue Jan  6 19:07:13 2015
 %%BoundingBox: 0 0 488 300
 %Magnification: 1.0000
 %%EndComments
index 117e246..d340c9e 100644 (file)
Binary files a/doc/libgcrypt-modules.pdf and b/doc/libgcrypt-modules.pdf differ
index 2f45552..fea7b18 100644 (file)
Binary files a/doc/libgcrypt-modules.png and b/doc/libgcrypt-modules.png differ
index daa148f..2118a53 100644 (file)
@@ -1,4 +1,4 @@
-@set UPDATED 21 August 2014
-@set UPDATED-MONTH August 2014
-@set EDITION 1.6.2
-@set VERSION 1.6.2
+@set UPDATED 15 June 2016
+@set UPDATED-MONTH June 2016
+@set EDITION 1.7.1
+@set VERSION 1.7.1
index daa148f..2118a53 100644 (file)
@@ -1,4 +1,4 @@
-@set UPDATED 21 August 2014
-@set UPDATED-MONTH August 2014
-@set EDITION 1.6.2
-@set VERSION 1.6.2
+@set UPDATED 15 June 2016
+@set UPDATED-MONTH June 2016
+@set EDITION 1.7.1
+@set VERSION 1.7.1
index 2ac4390..86c3c70 100644 (file)
     detects the number of white spaces in front of an @item and remove
     this number of spaces from all following lines until a new @item
     is found or there are less spaces than for the last @item.
+
+    Note that @* does only work correctly if used at the end of an
+    input line.
+
 */
 
 #include <stdio.h>
@@ -136,6 +140,9 @@ typedef struct macro_s *macro_t;
 /* List of all defined macros. */
 static macro_t macrolist;
 
+/* List of variables set by @set. */
+static macro_t variablelist;
+
 /* List of global macro names.  The value part is not used.  */
 static macro_t predefinedmacrolist;
 
@@ -375,8 +382,44 @@ set_macro (const char *macroname, char *macrovalue)
 }
 
 
-/* Return true if the macro NAME is set, i.e. not the empty string and
-   not evaluating to 0.  */
+/* Create or update a variable with name and value given in NAMEANDVALUE.  */
+static void
+set_variable (char *nameandvalue)
+{
+  macro_t m;
+  const char *value;
+  char *p;
+
+  for (p = nameandvalue; *p && *p != ' ' && *p != '\t'; p++)
+    ;
+  if (!*p)
+    value = "";
+  else
+    {
+      *p++ = 0;
+      while (*p == ' ' || *p == '\t')
+        p++;
+      value = p;
+    }
+
+  for (m=variablelist; m; m = m->next)
+    if (!strcmp (m->name, nameandvalue))
+      break;
+  if (m)
+    free (m->value);
+  else
+    {
+      m = xcalloc (1, sizeof *m + strlen (nameandvalue));
+      strcpy (m->name, nameandvalue);
+      m->next = variablelist;
+      variablelist = m;
+    }
+  m->value = xstrdup (value);
+}
+
+
+/* Return true if the macro or variable NAME is set, i.e. not the
+   empty string and not evaluating to 0.  */
 static int
 macro_set_p (const char *name)
 {
@@ -385,6 +428,10 @@ macro_set_p (const char *name)
   for (m = macrolist; m ; m = m->next)
     if (!strcmp (m->name, name))
       break;
+  if (!m)
+    for (m = variablelist; m ; m = m->next)
+      if (!strcmp (m->name, name))
+        break;
   if (!m || !m->value || !*m->value)
     return 0;
   if ((*m->value & 0x80) || !isdigit (*m->value))
@@ -609,6 +656,7 @@ write_th (FILE *fp)
   *p++ = 0;
   fprintf (fp, ".TH %s %s %s \"%s\" \"%s\"\n",
            name, p, isodatestring (), opt_release, opt_source);
+  free (name);
   return 0;
 }
 
@@ -664,8 +712,11 @@ proc_texi_cmd (FILE *fp, const char *command, const char *rest, size_t len,
     { "table",   3 },
     { "itemize",   3 },
     { "bullet",  0, "* " },
+    { "*",       0, "\n.br"},
+    { "/",       0 },
     { "end",     4 },
     { "quotation",1, ".RS\n\\fB" },
+    { "value", 8 },
     { NULL }
   };
   size_t n;
@@ -741,11 +792,46 @@ proc_texi_cmd (FILE *fp, const char *command, const char *rest, size_t len,
         case 7:
           ignore_args = 1;
           break;
+        case 8:
+          ignore_args = 1;
+          if (*rest != '{')
+            {
+              err ("opening brace for command '%s' missing", command);
+              return len;
+            }
+          else
+            {
+              /* Find closing brace.  */
+              for (s=rest+1, n=1; *s && n < len; s++, n++)
+                if (*s == '}')
+                  break;
+              if (*s != '}')
+                {
+                  err ("closing brace for command '%s' not found", command);
+                  return len;
+                }
+              else
+                {
+                  size_t len = s - (rest + 1);
+                  macro_t m;
+
+                  for (m = variablelist; m; m = m->next)
+                    if (strlen (m->name) == len
+                        &&!strncmp (m->name, rest+1, len))
+                      break;
+                  if (m)
+                    fputs (m->value, fp);
+                  else
+                    inf ("texinfo variable '%.*s' is not set",
+                         (int)len, rest+1);
+                }
+            }
+          break;
         default:
           break;
         }
     }
-  else
+  else /* macro */
     {
       macro_t m;
 
@@ -1215,6 +1301,10 @@ parse_file (const char *fname, FILE *fp, char **section_name, int in_pause)
               macrovalue = xmalloc ((macrovaluesize = 1024));
               macrovalueused = 0;
             }
+          else if (n == 4 && !memcmp (line, "@set", 4))
+            {
+              set_variable (p);
+            }
           else if (n == 8 && !memcmp (line, "@manpage", 8))
             {
               free (*section_name);
@@ -1325,6 +1415,13 @@ top_parse_file (const char *fname, FILE *fp)
       free (macrolist);
       macrolist = next;
     }
+  while (variablelist)
+    {
+      macro_t next = variablelist->next;
+      free (variablelist->value);
+      free (variablelist);
+      variablelist = next;
+    }
   for (m=predefinedmacrolist; m; m = m->next)
     set_macro (m->name, xstrdup ("1"));
   cond_is_active = 1;
index 0ee9ba7..0c90875 100644 (file)
@@ -1,2 +1,2 @@
 EXTRA_DIST = libtool.m4 onceonly.m4 socklen.m4 sys_socket_h.m4 noexecstack.m4
-EXTRA_DIST += gpg-error.m4 lock.m4 threadlib.m4
+EXTRA_DIST += gpg-error.m4
index fea19c7..08fe8f1 100644 (file)
@@ -1,9 +1,8 @@
-# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
-# Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
 @SET_MAKE@
 VPATH = @srcdir@
-am__make_dryrun = \
-  { \
-    am__dry=no; \
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
     case $$MAKEFLAGS in \
       *\\[\ \  ]*) \
-        echo 'am--echo: ; @echo "AM"  OK' | $(MAKE) -f - 2>/dev/null \
-          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
-      *) \
-        for am__flg in $$MAKEFLAGS; do \
-          case $$am__flg in \
-            *=*|--*) ;; \
-            *n*) am__dry=yes; break;; \
-          esac; \
-        done;; \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs  ]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
     esac; \
-    test $$am__dry = yes; \
-  }
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -51,28 +78,33 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = m4
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/gpg-error.m4 \
-       $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/lock.m4 \
-       $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
-       $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+       $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+       $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+       $(top_srcdir)/m4/lt~obsolete.m4 \
        $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \
        $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
-       $(top_srcdir)/m4/threadlib.m4 $(top_srcdir)/acinclude.m4 \
-       $(top_srcdir)/configure.ac
+       $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
 AM_V_GEN = $(am__v_GEN_@AM_V@)
 am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
-am__v_GEN_0 = @echo "  GEN   " $@;
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
 AM_V_at = $(am__v_at_@AM_V@)
 am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
 am__v_at_0 = @
+am__v_at_1 = 
 SOURCES =
 DIST_SOURCES =
 am__can_run_installinfo = \
@@ -80,6 +112,7 @@ am__can_run_installinfo = \
     n|no|NO) false;; \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -125,6 +158,8 @@ GCRYPT_RANDOM = @GCRYPT_RANDOM@
 GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
 GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
 GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GPG_ERROR_MT_CFLAGS = @GPG_ERROR_MT_CFLAGS@
+GPG_ERROR_MT_LIBS = @GPG_ERROR_MT_LIBS@
 GREP = @GREP@
 INSERT_SYS_SELECT_H = @INSERT_SYS_SELECT_H@
 INSTALL = @INSTALL@
@@ -145,16 +180,12 @@ LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@
 LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@
 LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@
 LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@
-LIBMULTITHREAD = @LIBMULTITHREAD@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
-LIBTHREAD = @LIBTHREAD@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
-LTLIBMULTITHREAD = @LTLIBMULTITHREAD@
 LTLIBOBJS = @LTLIBOBJS@
-LTLIBTHREAD = @LTLIBTHREAD@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
@@ -185,6 +216,7 @@ SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
+SYSROOT = @SYSROOT@
 SYS_SOCKET_H = @SYS_SOCKET_H@
 VERSION = @VERSION@
 VERSION_NUMBER = @VERSION_NUMBER@
@@ -244,7 +276,7 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 EXTRA_DIST = libtool.m4 onceonly.m4 socklen.m4 sys_socket_h.m4 \
-       noexecstack.m4 gpg-error.m4 lock.m4 threadlib.m4
+       noexecstack.m4 gpg-error.m4
 all: all-am
 
 .SUFFIXES:
@@ -284,11 +316,11 @@ mostlyclean-libtool:
 
 clean-libtool:
        -rm -rf .libs _libs
-tags: TAGS
-TAGS:
+tags TAGS:
+
+ctags CTAGS:
 
-ctags: CTAGS
-CTAGS:
+cscope cscopelist:
 
 
 distdir: $(DISTFILES)
@@ -424,15 +456,16 @@ uninstall-am:
 .MAKE: install-am install-strip
 
 .PHONY: all all-am check check-am clean clean-generic clean-libtool \
-       distclean distclean-generic distclean-libtool distdir dvi \
-       dvi-am html html-am info info-am install install-am \
-       install-data install-data-am install-dvi install-dvi-am \
-       install-exec install-exec-am install-html install-html-am \
-       install-info install-info-am install-man install-pdf \
-       install-pdf-am install-ps install-ps-am install-strip \
-       installcheck installcheck-am installdirs maintainer-clean \
-       maintainer-clean-generic mostlyclean mostlyclean-generic \
-       mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am
+       cscopelist-am ctags-am distclean distclean-generic \
+       distclean-libtool distdir dvi dvi-am html html-am info info-am \
+       install install-am install-data install-data-am install-dvi \
+       install-dvi-am install-exec install-exec-am install-html \
+       install-html-am install-info install-info-am install-man \
+       install-pdf install-pdf-am install-ps install-ps-am \
+       install-strip installcheck installcheck-am installdirs \
+       maintainer-clean maintainer-clean-generic mostlyclean \
+       mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+       tags-am uninstall uninstall-am
 
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
index eb5d7c4..1661204 100644 (file)
@@ -1,5 +1,5 @@
 # gpg-error.m4 - autoconf macro to detect libgpg-error.
-# Copyright (C) 2002, 2003, 2004 g10 Code GmbH
+# Copyright (C) 2002, 2003, 2004, 2011, 2014 g10 Code GmbH
 #
 # This file is free software; as a special exception the author gives
 # unlimited permission to copy and/or distribute it, with or without
@@ -8,38 +8,64 @@
 # This file is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
 # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Last-changed: 2014-10-02
+
 
 dnl AM_PATH_GPG_ERROR([MINIMUM-VERSION,
 dnl                   [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
-dnl Test for libgpg-error and define GPG_ERROR_CFLAGS and GPG_ERROR_LIBS
+dnl
+dnl Test for libgpg-error and define GPG_ERROR_CFLAGS, GPG_ERROR_LIBS,
+dnl GPG_ERROR_MT_CFLAGS, and GPG_ERROR_MT_LIBS.  The _MT_ variants are
+dnl used for programs requireing real multi thread support.
+dnl
+dnl If a prefix option is not used, the config script is first
+dnl searched in $SYSROOT/bin and then along $PATH.  If the used
+dnl config script does not match the host specification the script
+dnl is added to the gpg_config_script_warn variable.
 dnl
 AC_DEFUN([AM_PATH_GPG_ERROR],
-[
+[ AC_REQUIRE([AC_CANONICAL_HOST])
+  gpg_error_config_prefix=""
   dnl --with-libgpg-error-prefix=PFX is the preferred name for this option,
   dnl since that is consistent with how our three siblings use the directory/
   dnl package name in --with-$dir_name-prefix=PFX.
   AC_ARG_WITH(libgpg-error-prefix,
-            AC_HELP_STRING([--with-libgpg-error-prefix=PFX],
-                           [prefix where GPG Error is installed (optional)]),
-     gpg_error_config_prefix="$withval", gpg_error_config_prefix="")
+              AC_HELP_STRING([--with-libgpg-error-prefix=PFX],
+                             [prefix where GPG Error is installed (optional)]),
+              [gpg_error_config_prefix="$withval"])
 
   dnl Accept --with-gpg-error-prefix and make it work the same as
   dnl --with-libgpg-error-prefix above, for backwards compatibility,
   dnl but do not document this old, inconsistently-named option.
   AC_ARG_WITH(gpg-error-prefix,,
-     gpg_error_config_prefix="$withval", gpg_error_config_prefix="")
+              [gpg_error_config_prefix="$withval"])
 
-  if test x$gpg_error_config_prefix != x ; then
-     if test x${GPG_ERROR_CONFIG+set} != xset ; then
-        GPG_ERROR_CONFIG=$gpg_error_config_prefix/bin/gpg-error-config
+  if test x"${GPG_ERROR_CONFIG}" = x ; then
+     if test x"${gpg_error_config_prefix}" != x ; then
+        GPG_ERROR_CONFIG="${gpg_error_config_prefix}/bin/gpg-error-config"
+     else
+       case "${SYSROOT}" in
+         /*)
+           if test -x "${SYSROOT}/bin/gpg-error-config" ; then
+             GPG_ERROR_CONFIG="${SYSROOT}/bin/gpg-error-config"
+           fi
+           ;;
+         '')
+           ;;
+          *)
+           AC_MSG_WARN([Ignoring \$SYSROOT as it is not an absolute path.])
+           ;;
+       esac
      fi
   fi
 
-  AC_PATH_TOOL(GPG_ERROR_CONFIG, gpg-error-config, no)
+  AC_PATH_PROG(GPG_ERROR_CONFIG, gpg-error-config, no)
   min_gpg_error_version=ifelse([$1], ,0.0,$1)
   AC_MSG_CHECKING(for GPG Error - version >= $min_gpg_error_version)
   ok=no
-  if test "$GPG_ERROR_CONFIG" != "no" ; then
+  if test "$GPG_ERROR_CONFIG" != "no" \
+     && test -f "$GPG_ERROR_CONFIG" ; then
     req_major=`echo $min_gpg_error_version | \
                sed 's/\([[0-9]]*\)\.\([[0-9]]*\)/\1/'`
     req_minor=`echo $min_gpg_error_version | \
@@ -62,29 +88,34 @@ AC_DEFUN([AM_PATH_GPG_ERROR],
   if test $ok = yes; then
     GPG_ERROR_CFLAGS=`$GPG_ERROR_CONFIG $gpg_error_config_args --cflags`
     GPG_ERROR_LIBS=`$GPG_ERROR_CONFIG $gpg_error_config_args --libs`
+    GPG_ERROR_MT_CFLAGS=`$GPG_ERROR_CONFIG $gpg_error_config_args --mt --cflags 2>/dev/null`
+    GPG_ERROR_MT_LIBS=`$GPG_ERROR_CONFIG $gpg_error_config_args --mt --libs 2>/dev/null`
     AC_MSG_RESULT([yes ($gpg_error_config_version)])
     ifelse([$2], , :, [$2])
-    if test x"$host" != x ; then
-      gpg_error_config_host=`$GPG_ERROR_CONFIG $gpg_error_config_args --host 2>/dev/null || echo none`
-      if test x"$gpg_error_config_host" != xnone ; then
-        if test x"$gpg_error_config_host" != x"$host" ; then
+    gpg_error_config_host=`$GPG_ERROR_CONFIG $gpg_error_config_args --host 2>/dev/null || echo none`
+    if test x"$gpg_error_config_host" != xnone ; then
+      if test x"$gpg_error_config_host" != x"$host" ; then
   AC_MSG_WARN([[
 ***
 *** The config script $GPG_ERROR_CONFIG was
 *** built for $gpg_error_config_host and thus may not match the
 *** used host $host.
 *** You may want to use the configure option --with-gpg-error-prefix
-*** to specify a matching config script.
+*** to specify a matching config script or use \$SYSROOT.
 ***]])
-        fi
+        gpg_config_script_warn="$gpg_config_script_warn libgpg-error"
       fi
     fi
   else
     GPG_ERROR_CFLAGS=""
     GPG_ERROR_LIBS=""
+    GPG_ERROR_MT_CFLAGS=""
+    GPG_ERROR_MT_LIBS=""
     AC_MSG_RESULT(no)
     ifelse([$3], , :, [$3])
   fi
   AC_SUBST(GPG_ERROR_CFLAGS)
   AC_SUBST(GPG_ERROR_LIBS)
+  AC_SUBST(GPG_ERROR_MT_CFLAGS)
+  AC_SUBST(GPG_ERROR_MT_LIBS)
 ])
diff --git a/m4/lock.m4 b/m4/lock.m4
deleted file mode 100644 (file)
index 73a3c54..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-# lock.m4 serial 13 (gettext-0.18.2)
-dnl Copyright (C) 2005-2014 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-
-dnl From Bruno Haible.
-
-AC_DEFUN([gl_LOCK],
-[
-  AC_REQUIRE([gl_THREADLIB])
-  if test "$gl_threads_api" = posix; then
-    # OSF/1 4.0 and Mac OS X 10.1 lack the pthread_rwlock_t type and the
-    # pthread_rwlock_* functions.
-    AC_CHECK_TYPE([pthread_rwlock_t],
-      [AC_DEFINE([HAVE_PTHREAD_RWLOCK], [1],
-         [Define if the POSIX multithreading library has read/write locks.])],
-      [],
-      [#include <pthread.h>])
-    # glibc defines PTHREAD_MUTEX_RECURSIVE as enum, not as a macro.
-    AC_COMPILE_IFELSE([
-      AC_LANG_PROGRAM(
-        [[#include <pthread.h>]],
-        [[
-#if __FreeBSD__ == 4
-error "No, in FreeBSD 4.0 recursive mutexes actually don't work."
-#elif (defined __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ \
-       && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070)
-error "No, in Mac OS X < 10.7 recursive mutexes actually don't work."
-#else
-int x = (int)PTHREAD_MUTEX_RECURSIVE;
-return !x;
-#endif
-        ]])],
-      [AC_DEFINE([HAVE_PTHREAD_MUTEX_RECURSIVE], [1],
-         [Define if the <pthread.h> defines PTHREAD_MUTEX_RECURSIVE.])])
-  fi
-  gl_PREREQ_LOCK
-])
-
-# Prerequisites of lib/glthread/lock.c.
-AC_DEFUN([gl_PREREQ_LOCK], [:])
diff --git a/m4/threadlib.m4 b/m4/threadlib.m4
deleted file mode 100644 (file)
index b015365..0000000
+++ /dev/null
@@ -1,349 +0,0 @@
-# threadlib.m4 serial 10 (gettext-0.18.2) modified by wk 2014-01-24.
-dnl Copyright (C) 2005-2014 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-
-dnl From Bruno Haible.
-
-dnl gl_THREADLIB
-dnl ------------
-dnl Tests for a multithreading library to be used.
-dnl If the configure.ac contains a definition of the gl_THREADLIB_DEFAULT_NO
-dnl (it must be placed before the invocation of gl_THREADLIB_EARLY!), then the
-dnl default is 'no', otherwise it is system dependent. In both cases, the user
-dnl can change the choice through the options --enable-threads=choice or
-dnl --disable-threads.
-dnl Defines at most one of the macros USE_POSIX_THREADS, USE_SOLARIS_THREADS,
-dnl USE_WINDOWS_THREADS
-dnl Sets the variables LIBTHREAD and LTLIBTHREAD to the linker options for use
-dnl in a Makefile (LIBTHREAD for use without libtool, LTLIBTHREAD for use with
-dnl libtool).
-dnl Sets the variables LIBMULTITHREAD and LTLIBMULTITHREAD similarly, for
-dnl programs that really need multithread functionality. The difference
-dnl between LIBTHREAD and LIBMULTITHREAD is that on platforms supporting weak
-dnl symbols, typically LIBTHREAD="" whereas LIBMULTITHREAD="-lpthread".
-dnl Sets THREADLIB_CPPFLAGS to -D_REENTRANT or -D_THREAD_SAFE if needed for
-dnl multithread-safe programs and adds THREADLIB_CPPFLAGS to CPPFLAGS.
-
-AC_DEFUN([gl_THREADLIB_EARLY],
-[
-  AC_REQUIRE([gl_THREADLIB_EARLY_BODY])
-])
-
-dnl The guts of gl_THREADLIB_EARLY. Needs to be expanded only once.
-
-AC_DEFUN([gl_THREADLIB_EARLY_BODY],
-[
-  dnl Ordering constraints: This macro modifies CPPFLAGS in a way that
-  dnl influences the result of the autoconf tests that test for *_unlocked
-  dnl declarations, on AIX 5 at least. Therefore it must come early.
-  AC_BEFORE([$0], [gl_FUNC_GLIBC_UNLOCKED_IO])dnl
-  AC_BEFORE([$0], [gl_ARGP])dnl
-
-  AC_REQUIRE([AC_CANONICAL_HOST])
-  dnl _GNU_SOURCE is needed for pthread_rwlock_t on glibc systems.
-  dnl AC_USE_SYSTEM_EXTENSIONS was introduced in autoconf 2.60 and obsoletes
-  dnl AC_GNU_SOURCE.
-  m4_ifdef([AC_USE_SYSTEM_EXTENSIONS],
-    [AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])],
-    [AC_REQUIRE([AC_GNU_SOURCE])])
-  dnl Check for multithreading.
-  THREADLIB_CPPFLAGS=""
-  m4_ifdef([gl_THREADLIB_DEFAULT_NO],
-    [m4_divert_text([DEFAULTS], [gl_use_threads_default=no])],
-    [m4_divert_text([DEFAULTS], [gl_use_threads_default=])])
-  AC_ARG_ENABLE([threads],
-AC_HELP_STRING([--enable-threads={posix|solaris|windows}], [specify multithreading API])m4_ifdef([gl_THREADLIB_DEFAULT_NO], [], [
-AC_HELP_STRING([--disable-threads], [build without multithread safety])]),
-    [gl_use_threads=$enableval],
-    [if test -n "$gl_use_threads_default"; then
-       gl_use_threads="$gl_use_threads_default"
-     else
-changequote(,)dnl
-       case "$host_os" in
-         dnl Disable multithreading by default on OSF/1, because it interferes
-         dnl with fork()/exec(): When msgexec is linked with -lpthread, its
-         dnl child process gets an endless segmentation fault inside execvp().
-         dnl Disable multithreading by default on Cygwin 1.5.x, because it has
-         dnl bugs that lead to endless loops or crashes. See
-         dnl <http://cygwin.com/ml/cygwin/2009-08/msg00283.html>.
-         osf*) gl_use_threads=no ;;
-         cygwin*)
-               case `uname -r` in
-                 1.[0-5].*) gl_use_threads=no ;;
-                 *)         gl_use_threads=yes ;;
-               esac
-               ;;
-         *)    gl_use_threads=yes ;;
-       esac
-changequote([,])dnl
-     fi
-    ])
-  if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then
-    # For using <pthread.h>:
-    case "$host_os" in
-      osf*)
-        # On OSF/1, the compiler needs the flag -D_REENTRANT so that it
-        # groks <pthread.h>. cc also understands the flag -pthread, but
-        # we don't use it because 1. gcc-2.95 doesn't understand -pthread,
-        # 2. putting a flag into CPPFLAGS that has an effect on the linker
-        # causes the AC_LINK_IFELSE test below to succeed unexpectedly,
-        # leading to wrong values of LIBTHREAD and LTLIBTHREAD.
-        THREADLIB_CPPFLAGS="$THREADLIB_CPPFLAGS -D_REENTRANT"
-        ;;
-    esac
-    # Some systems optimize for single-threaded programs by default, and
-    # need special flags to disable these optimizations. For example, the
-    # definition of 'errno' in <errno.h>.
-    case "$host_os" in
-      aix* | freebsd*)
-           THREADLIB_CPPFLAGS="$THREADLIB_CPPFLAGS -D_THREAD_SAFE"
-           ;;
-      solaris*)
-           THREADLIB_CPPFLAGS="$THREADLIB_CPPFLAGS -D_REENTRANT"
-           ;;
-    esac
-  fi
-  if test x"$THREADLIB_CPPFLAGS" != x ; then
-      CPPFLAGS="$CPPFLAGS $THREADLIB_CPPFLAGS"
-  fi
-])
-
-dnl The guts of gl_THREADLIB. Needs to be expanded only once.
-
-AC_DEFUN([gl_THREADLIB_BODY],
-[
-  AC_REQUIRE([gl_THREADLIB_EARLY_BODY])
-  gl_threads_api=none
-  LIBTHREAD=
-  LTLIBTHREAD=
-  LIBMULTITHREAD=
-  LTLIBMULTITHREAD=
-  if test "$gl_use_threads" != no; then
-    dnl Check whether the compiler and linker support weak declarations.
-    AC_CACHE_CHECK([whether imported symbols can be declared weak],
-      [gl_cv_have_weak],
-      [gl_cv_have_weak=no
-       dnl First, test whether the compiler accepts it syntactically.
-       AC_LINK_IFELSE(
-         [AC_LANG_PROGRAM(
-            [[extern void xyzzy ();
-#pragma weak xyzzy]],
-            [[xyzzy();]])],
-         [gl_cv_have_weak=maybe])
-       if test $gl_cv_have_weak = maybe; then
-         dnl Second, test whether it actually works. On Cygwin 1.7.2, with
-         dnl gcc 4.3, symbols declared weak always evaluate to the address 0.
-         AC_RUN_IFELSE(
-           [AC_LANG_SOURCE([[
-#include <stdio.h>
-#pragma weak fputs
-int main ()
-{
-  return (fputs == NULL);
-}]])],
-           [gl_cv_have_weak=yes],
-           [gl_cv_have_weak=no],
-           [dnl When cross-compiling, assume that only ELF platforms support
-            dnl weak symbols.
-            AC_EGREP_CPP([Extensible Linking Format],
-              [#ifdef __ELF__
-               Extensible Linking Format
-               #endif
-              ],
-              [gl_cv_have_weak="guessing yes"],
-              [gl_cv_have_weak="guessing no"])
-           ])
-       fi
-      ])
-    if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then
-      # On OSF/1, the compiler needs the flag -pthread or -D_REENTRANT so that
-      # it groks <pthread.h>. It's added above, in gl_THREADLIB_EARLY_BODY.
-      AC_CHECK_HEADER([pthread.h],
-        [gl_have_pthread_h=yes], [gl_have_pthread_h=no])
-      if test "$gl_have_pthread_h" = yes; then
-        # Other possible tests:
-        #   -lpthreads (FSU threads, PCthreads)
-        #   -lgthreads
-        gl_have_pthread=
-        # Test whether both pthread_mutex_lock and pthread_mutexattr_init exist
-        # in libc. IRIX 6.5 has the first one in both libc and libpthread, but
-        # the second one only in libpthread, and lock.c needs it.
-        AC_LINK_IFELSE(
-          [AC_LANG_PROGRAM(
-             [[#include <pthread.h>]],
-             [[pthread_mutex_lock((pthread_mutex_t*)0);
-               pthread_mutexattr_init((pthread_mutexattr_t*)0);]])],
-          [gl_have_pthread=yes])
-        # Test for libpthread by looking for pthread_kill. (Not pthread_self,
-        # since it is defined as a macro on OSF/1.)
-        if test -n "$gl_have_pthread"; then
-          # The program links fine without libpthread. But it may actually
-          # need to link with libpthread in order to create multiple threads.
-          AC_CHECK_LIB([pthread], [pthread_kill],
-            [LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread
-             # On Solaris and HP-UX, most pthread functions exist also in libc.
-             # Therefore pthread_in_use() needs to actually try to create a
-             # thread: pthread_create from libc will fail, whereas
-             # pthread_create will actually create a thread.
-             case "$host_os" in
-               solaris* | hpux*)
-                 AC_DEFINE([PTHREAD_IN_USE_DETECTION_HARD], [1],
-                   [Define if the pthread_in_use() detection is hard.])
-             esac
-            ])
-        else
-          # Some library is needed. Try libpthread and libc_r.
-          AC_CHECK_LIB([pthread], [pthread_kill],
-            [gl_have_pthread=yes
-             LIBTHREAD=-lpthread LTLIBTHREAD=-lpthread
-             LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread])
-          if test -z "$gl_have_pthread"; then
-            # For FreeBSD 4.
-            AC_CHECK_LIB([c_r], [pthread_kill],
-              [gl_have_pthread=yes
-               LIBTHREAD=-lc_r LTLIBTHREAD=-lc_r
-               LIBMULTITHREAD=-lc_r LTLIBMULTITHREAD=-lc_r])
-          fi
-        fi
-        if test -n "$gl_have_pthread"; then
-          gl_threads_api=posix
-          AC_DEFINE([USE_POSIX_THREADS], [1],
-            [Define if the POSIX multithreading library can be used.])
-          if test -n "$LIBMULTITHREAD" || test -n "$LTLIBMULTITHREAD"; then
-            if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then
-              AC_DEFINE([USE_POSIX_THREADS_WEAK], [1],
-                [Define if references to the POSIX multithreading library should be made weak.])
-              LIBTHREAD=
-              LTLIBTHREAD=
-            fi
-          fi
-        fi
-      fi
-    fi
-    if test -z "$gl_have_pthread"; then
-      if test "$gl_use_threads" = yes || test "$gl_use_threads" = solaris; then
-        gl_have_solaristhread=
-        gl_save_LIBS="$LIBS"
-        LIBS="$LIBS -lthread"
-        AC_LINK_IFELSE(
-          [AC_LANG_PROGRAM(
-             [[
-#include <thread.h>
-#include <synch.h>
-             ]],
-             [[thr_self();]])],
-          [gl_have_solaristhread=yes])
-        LIBS="$gl_save_LIBS"
-        if test -n "$gl_have_solaristhread"; then
-          gl_threads_api=solaris
-          LIBTHREAD=-lthread
-          LTLIBTHREAD=-lthread
-          LIBMULTITHREAD="$LIBTHREAD"
-          LTLIBMULTITHREAD="$LTLIBTHREAD"
-          AC_DEFINE([USE_SOLARIS_THREADS], [1],
-            [Define if the old Solaris multithreading library can be used.])
-          if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then
-            AC_DEFINE([USE_SOLARIS_THREADS_WEAK], [1],
-              [Define if references to the old Solaris multithreading library should be made weak.])
-            LIBTHREAD=
-            LTLIBTHREAD=
-          fi
-        fi
-      fi
-    fi
-    if test -z "$gl_have_pthread"; then
-      case "$gl_use_threads" in
-        yes | windows | win32) # The 'win32' is for backward compatibility.
-          if { case "$host_os" in
-                 mingw*) true;;
-                 *) false;;
-               esac
-             }; then
-            gl_threads_api=windows
-            AC_DEFINE([USE_WINDOWS_THREADS], [1],
-              [Define if the native Windows multithreading API can be used.])
-          fi
-          ;;
-      esac
-    fi
-  fi
-  AC_MSG_CHECKING([for multithread API to use])
-  AC_MSG_RESULT([$gl_threads_api])
-  AC_SUBST([LIBTHREAD])
-  AC_SUBST([LTLIBTHREAD])
-  AC_SUBST([LIBMULTITHREAD])
-  AC_SUBST([LTLIBMULTITHREAD])
-])
-
-AC_DEFUN([gl_THREADLIB],
-[
-  AC_REQUIRE([gl_THREADLIB_EARLY])
-  AC_REQUIRE([gl_THREADLIB_BODY])
-])
-
-
-dnl gl_DISABLE_THREADS
-dnl ------------------
-dnl Sets the gl_THREADLIB default so that threads are not used by default.
-dnl The user can still override it at installation time, by using the
-dnl configure option '--enable-threads'.
-
-AC_DEFUN([gl_DISABLE_THREADS], [
-  m4_divert_text([INIT_PREPARE], [gl_use_threads_default=no])
-])
-
-
-dnl Survey of platforms:
-dnl
-dnl Platform           Available  Compiler    Supports   test-lock
-dnl                    flavours   option      weak       result
-dnl ---------------    ---------  ---------   --------   ---------
-dnl Linux 2.4/glibc    posix      -lpthread       Y      OK
-dnl
-dnl GNU Hurd/glibc     posix
-dnl
-dnl FreeBSD 5.3        posix      -lc_r           Y
-dnl                    posix      -lkse ?         Y
-dnl                    posix      -lpthread ?     Y
-dnl                    posix      -lthr           Y
-dnl
-dnl FreeBSD 5.2        posix      -lc_r           Y
-dnl                    posix      -lkse           Y
-dnl                    posix      -lthr           Y
-dnl
-dnl FreeBSD 4.0,4.10   posix      -lc_r           Y      OK
-dnl
-dnl NetBSD 1.6         --
-dnl
-dnl OpenBSD 3.4        posix      -lpthread       Y      OK
-dnl
-dnl Mac OS X 10.[123]  posix      -lpthread       Y      OK
-dnl
-dnl Solaris 7,8,9      posix      -lpthread       Y      Sol 7,8: 0.0; Sol 9: OK
-dnl                    solaris    -lthread        Y      Sol 7,8: 0.0; Sol 9: OK
-dnl
-dnl HP-UX 11           posix      -lpthread       N (cc) OK
-dnl                                               Y (gcc)
-dnl
-dnl IRIX 6.5           posix      -lpthread       Y      0.5
-dnl
-dnl AIX 4.3,5.1        posix      -lpthread       N      AIX 4: 0.5; AIX 5: OK
-dnl
-dnl OSF/1 4.0,5.1      posix      -pthread (cc)   N      OK
-dnl                               -lpthread (gcc) Y
-dnl
-dnl Cygwin             posix      -lpthread       Y      OK
-dnl
-dnl Any of the above   pth        -lpth                  0.0
-dnl
-dnl Mingw              windows                    N      OK
-dnl
-dnl BeOS 5             --
-dnl
-dnl The test-lock result shows what happens if in test-lock.c EXPLICIT_YIELD is
-dnl turned off:
-dnl   OK if all three tests terminate OK,
-dnl   0.5 if the first test terminates OK but the second one loops endlessly,
-dnl   0.0 if the first test already loops endlessly.
index c41b1ea..8f39ee7 100644 (file)
@@ -29,7 +29,7 @@ AM_CFLAGS = $(GPG_ERROR_CFLAGS)
 AM_ASFLAGS = $(MPI_SFLAGS)
 AM_CCASFLAGS = $(NOEXECSTACK_FLAGS)
 
-EXTRA_DIST = Manifest config.links
+EXTRA_DIST = config.links
 DISTCLEANFILES = mpi-asm-defs.h \
                  mpih-add1-asm.S mpih-mul1-asm.S mpih-mul2-asm.S mpih-mul3-asm.S  \
                 mpih-lshift-asm.S mpih-rshift-asm.S mpih-sub1-asm.S asm-syntax.h \
index dc0798d..3102b5c 100644 (file)
@@ -1,9 +1,8 @@
-# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
-# Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 # not anymore required: AUTOMAKE_OPTIONS = 1.6
 
 VPATH = @srcdir@
-am__make_dryrun = \
-  { \
-    am__dry=no; \
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
     case $$MAKEFLAGS in \
       *\\[\ \  ]*) \
-        echo 'am--echo: ; @echo "AM"  OK' | $(MAKE) -f - 2>/dev/null \
-          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
-      *) \
-        for am__flg in $$MAKEFLAGS; do \
-          case $$am__flg in \
-            *=*|--*) ;; \
-            *n*) am__dry=yes; break;; \
-          esac; \
-        done;; \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs  ]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
     esac; \
-    test $$am__dry = yes; \
-  }
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -74,16 +101,16 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = mpi
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+       $(top_srcdir)/build-aux/depcomp
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/gpg-error.m4 \
-       $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/lock.m4 \
-       $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
-       $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+       $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+       $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+       $(top_srcdir)/m4/lt~obsolete.m4 \
        $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \
        $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
-       $(top_srcdir)/m4/threadlib.m4 $(top_srcdir)/acinclude.m4 \
-       $(top_srcdir)/configure.ac
+       $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -123,9 +150,22 @@ libmpi_la_OBJECTS = $(am_libmpi_la_OBJECTS) \
 AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
 am__v_lt_0 = --silent
+am__v_lt_1 = 
 libmpi_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
        $(libmpi_la_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
 depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
 am__depfiles_maybe = depfiles
@@ -138,10 +178,8 @@ LTCPPASCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \
        $(AM_CCASFLAGS) $(CCASFLAGS)
 AM_V_CPPAS = $(am__v_CPPAS_@AM_V@)
 am__v_CPPAS_ = $(am__v_CPPAS_@AM_DEFAULT_V@)
-am__v_CPPAS_0 = @echo "  CPPAS " $@;
-AM_V_at = $(am__v_at_@AM_V@)
-am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
-am__v_at_0 = @
+am__v_CPPAS_0 = @echo "  CPPAS   " $@;
+am__v_CPPAS_1 = 
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
        $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
@@ -150,17 +188,16 @@ LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(AM_CFLAGS) $(CFLAGS)
 AM_V_CC = $(am__v_CC_@AM_V@)
 am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
-am__v_CC_0 = @echo "  CC    " $@;
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
 CCLD = $(CC)
 LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
        $(AM_LDFLAGS) $(LDFLAGS) -o $@
 AM_V_CCLD = $(am__v_CCLD_@AM_V@)
 am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
-am__v_CCLD_0 = @echo "  CCLD  " $@;
-AM_V_GEN = $(am__v_GEN_@AM_V@)
-am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
-am__v_GEN_0 = @echo "  GEN   " $@;
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
 SOURCES = $(libmpi_la_SOURCES) $(nodist_libmpi_la_SOURCES)
 DIST_SOURCES = $(libmpi_la_SOURCES)
 am__can_run_installinfo = \
@@ -168,6 +205,23 @@ am__can_run_installinfo = \
     n|no|NO) false;; \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -215,6 +269,8 @@ GCRYPT_RANDOM = @GCRYPT_RANDOM@
 GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
 GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
 GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GPG_ERROR_MT_CFLAGS = @GPG_ERROR_MT_CFLAGS@
+GPG_ERROR_MT_LIBS = @GPG_ERROR_MT_LIBS@
 GREP = @GREP@
 INSERT_SYS_SELECT_H = @INSERT_SYS_SELECT_H@
 INSTALL = @INSTALL@
@@ -235,16 +291,12 @@ LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@
 LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@
 LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@
 LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@
-LIBMULTITHREAD = @LIBMULTITHREAD@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
-LIBTHREAD = @LIBTHREAD@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
-LTLIBMULTITHREAD = @LTLIBMULTITHREAD@
 LTLIBOBJS = @LTLIBOBJS@
-LTLIBTHREAD = @LTLIBTHREAD@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
@@ -275,6 +327,7 @@ SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
+SYSROOT = @SYSROOT@
 SYS_SOCKET_H = @SYS_SOCKET_H@
 VERSION = @VERSION@
 VERSION_NUMBER = @VERSION_NUMBER@
@@ -340,7 +393,7 @@ AM_CPPFLAGS = -I../src -I$(top_srcdir)/src
 AM_CFLAGS = $(GPG_ERROR_CFLAGS)
 AM_ASFLAGS = $(MPI_SFLAGS)
 AM_CCASFLAGS = $(NOEXECSTACK_FLAGS)
-EXTRA_DIST = Manifest config.links
+EXTRA_DIST = config.links
 DISTCLEANFILES = mpi-asm-defs.h \
                  mpih-add1-asm.S mpih-mul1-asm.S mpih-mul2-asm.S mpih-mul3-asm.S  \
                 mpih-lshift-asm.S mpih-rshift-asm.S mpih-sub1-asm.S asm-syntax.h \
@@ -462,12 +515,15 @@ $(am__aclocal_m4_deps):
 
 clean-noinstLTLIBRARIES:
        -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
-       @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
-         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
-         test "$$dir" != "$$p" || dir=.; \
-         echo "rm -f \"$${dir}/so_locations\""; \
-         rm -f "$${dir}/so_locations"; \
-       done
+       @list='$(noinst_LTLIBRARIES)'; \
+       locs=`for p in $$list; do echo $$p; done | \
+             sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+             sort -u`; \
+       test -z "$$locs" || { \
+         echo rm -f $${locs}; \
+         rm -f $${locs}; \
+       }
+
 libmpi.la: $(libmpi_la_OBJECTS) $(libmpi_la_DEPENDENCIES) $(EXTRA_libmpi_la_DEPENDENCIES) 
        $(AM_V_CCLD)$(libmpi_la_LINK)  $(libmpi_la_OBJECTS) $(libmpi_la_LIBADD) $(LIBS)
 
@@ -540,14 +596,14 @@ distclean-compile:
 @am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
 
 .c.obj:
 @am__fastdepCC_TRUE@   $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
 @am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
 
 .c.lo:
 @am__fastdepCC_TRUE@   $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -562,26 +618,15 @@ mostlyclean-libtool:
 clean-libtool:
        -rm -rf .libs _libs
 
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
-       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
-       unique=`for i in $$list; do \
-           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-         done | \
-         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-             END { if (nonempty) { for (i in files) print i; }; }'`; \
-       mkid -fID $$unique
-tags: TAGS
-
-TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-               $(TAGS_FILES) $(LISP)
+ID: $(am__tagged_files)
+       $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
        set x; \
        here=`pwd`; \
-       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-       unique=`for i in $$list; do \
-           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-         done | \
-         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-             END { if (nonempty) { for (i in files) print i; }; }'`; \
+       $(am__define_uniq_tagged_files); \
        shift; \
        if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
@@ -593,15 +638,11 @@ TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
              $$unique; \
          fi; \
        fi
-ctags: CTAGS
-CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-               $(TAGS_FILES) $(LISP)
-       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-       unique=`for i in $$list; do \
-           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-         done | \
-         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-             END { if (nonempty) { for (i in files) print i; }; }'`; \
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+       $(am__define_uniq_tagged_files); \
        test -z "$(CTAGS_ARGS)$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$unique
@@ -610,6 +651,21 @@ GTAGS:
        here=`$(am__cd) $(top_builddir) && pwd` \
          && $(am__cd) $(top_srcdir) \
          && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+       list='$(am__tagged_files)'; \
+       case "$(srcdir)" in \
+         [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+         *) sdir=$(subdir)/$(srcdir) ;; \
+       esac; \
+       for i in $$list; do \
+         if test -f "$$i"; then \
+           echo "$(subdir)/$$i"; \
+         else \
+           echo "$$sdir/$$i"; \
+         fi; \
+       done >> $(top_builddir)/cscope.files
 
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
@@ -752,18 +808,19 @@ uninstall-am:
 
 .MAKE: install-am install-strip
 
-.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
-       clean-libtool clean-noinstLTLIBRARIES ctags distclean \
-       distclean-compile distclean-generic distclean-libtool \
-       distclean-tags distdir dvi dvi-am html html-am info info-am \
-       install install-am install-data install-data-am install-dvi \
-       install-dvi-am install-exec install-exec-am install-html \
-       install-html-am install-info install-info-am install-man \
-       install-pdf install-pdf-am install-ps install-ps-am \
-       install-strip installcheck installcheck-am installdirs \
-       maintainer-clean maintainer-clean-generic mostlyclean \
-       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
-       pdf pdf-am ps ps-am tags uninstall uninstall-am
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+       clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \
+       ctags-am distclean distclean-compile distclean-generic \
+       distclean-libtool distclean-tags distdir dvi dvi-am html \
+       html-am info info-am install install-am install-data \
+       install-data-am install-dvi install-dvi-am install-exec \
+       install-exec-am install-html install-html-am install-info \
+       install-info-am install-man install-pdf install-pdf-am \
+       install-ps install-ps-am install-strip installcheck \
+       installcheck-am installdirs maintainer-clean \
+       maintainer-clean-generic mostlyclean mostlyclean-compile \
+       mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+       tags tags-am uninstall uninstall-am
 
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/mpi/Manifest b/mpi/Manifest
deleted file mode 100644 (file)
index 3b0d673..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-# Manifest - checksums of the mpi directory
-# Copyright 2003 Free Software Foundation, Inc.
-#
-# This file is part of Libgcrypt.
-#
-# Libgcrypt is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser general Public License as
-# published by the Free Software Foundation; either version 2.1 of
-# the License, or (at your option) any later version.
-#
-# Libgcrypt is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
-Makefile.am
-config.links
-longlong.h
-mpi-add.c
-mpi-bit.c
-mpi-cmp.c
-mpi-div.c
-mpi-gcd.c
-mpi-inline.c
-mpi-inline.h
-mpi-internal.h
-mpi-inv.c
-mpi-mpow.c
-mpi-mul.c
-mpi-pow.c
-mpi-scan.c
-mpicoder.c
-mpih-div.c
-mpih-mul.c
-mpiutil.c
-$names$ iQCVAwUAP+LmfDEAnp832S/7AQKZJQQAkR/gQITUM+6Ygy9WAOAO17btyKAlCtGTXp5XSZ+J3X0o/rYneRdSCW89IJvwFRJjAOcFJd52MXs6ZVFF/RQBC8MvJzuQChbEzvihK8o2VgK34YWjU+6XH9sFgRMIgzkHs/51ZZxeQUOPy1XF7TyKB0WE7YBUVisFiRaqB1qGIOs==Z3qB
-
index e664c8d..e7f92c8 100644 (file)
@@ -1,3 +1,4 @@
+func_abi.h
 mpih-add1.S
 mpih-lshift.S
 mpih-mul1.S
diff --git a/mpi/amd64/func_abi.h b/mpi/amd64/func_abi.h
new file mode 100644 (file)
index 0000000..ce44674
--- /dev/null
@@ -0,0 +1,19 @@
+#ifdef USE_MS_ABI
+ /* Store registers and move four first input arguments from MS ABI to
+  * SYSV ABI.  */
+ #define FUNC_ENTRY() \
+       pushq %rsi; \
+       pushq %rdi; \
+       movq %rdx, %rsi; \
+       movq %rcx, %rdi; \
+       movq %r8, %rdx; \
+       movq %r9, %rcx;
+
+ /* Restore registers.  */
+ #define FUNC_EXIT() \
+       popq %rdi; \
+       popq %rsi;
+#else
+ #define FUNC_ENTRY() /**/
+ #define FUNC_EXIT() /**/
+#endif
index f0ec89c..6a90262 100644 (file)
@@ -43,6 +43,7 @@
 .text
        .globl C_SYMBOL_NAME(_gcry_mpih_add_n)
 C_SYMBOL_NAME(_gcry_mpih_add_n:)
+       FUNC_ENTRY()
        leaq    (%rsi,%rcx,8), %rsi
        leaq    (%rdi,%rcx,8), %rdi
        leaq    (%rdx,%rcx,8), %rdx
@@ -59,5 +60,6 @@ C_SYMBOL_NAME(_gcry_mpih_add_n:)
 
        movq    %rcx, %rax              /* zero %rax */
        adcq    %rax, %rax
+       FUNC_EXIT()
        ret
        
\ No newline at end of file
index e87dd1a..9e8979b 100644 (file)
@@ -42,6 +42,7 @@
 .text
        .globl C_SYMBOL_NAME(_gcry_mpih_lshift)
 C_SYMBOL_NAME(_gcry_mpih_lshift:)
+       FUNC_ENTRY()
        movq    -8(%rsi,%rdx,8), %mm7
        movd    %ecx, %mm1
        movl    $64, %eax
@@ -74,4 +75,5 @@ C_SYMBOL_NAME(_gcry_mpih_lshift:)
 .Lende:        psllq   %mm1, %mm2
        movq    %mm2, (%rdi)
        emms
+       FUNC_EXIT()
        ret
index 54b0ab4..67ab47e 100644 (file)
@@ -46,6 +46,7 @@
        GLOBL   C_SYMBOL_NAME(_gcry_mpih_mul_1)
 C_SYMBOL_NAME(_gcry_mpih_mul_1:)
 
+       FUNC_ENTRY()
        movq    %rdx, %r11
        leaq    (%rsi,%rdx,8), %rsi
        leaq    (%rdi,%rdx,8), %rdi
@@ -62,4 +63,5 @@ C_SYMBOL_NAME(_gcry_mpih_mul_1:)
        jne     .Loop
 
        movq    %r8, %rax
+       FUNC_EXIT()
        ret
index a332a1d..1aa4fa0 100644 (file)
@@ -41,6 +41,7 @@
        TEXT
        GLOBL   C_SYMBOL_NAME(_gcry_mpih_addmul_1)
 C_SYMBOL_NAME(_gcry_mpih_addmul_1:)
+       FUNC_ENTRY()
        movq    %rdx, %r11
        leaq    (%rsi,%rdx,8), %rsi
        leaq    (%rdi,%rdx,8), %rdi
@@ -61,4 +62,5 @@ C_SYMBOL_NAME(_gcry_mpih_addmul_1:)
        jne     .Loop
 
        movq    %r8, %rax
+       FUNC_EXIT()
        ret
index 4d458a7..bc41c4e 100644 (file)
@@ -42,7 +42,7 @@
        TEXT
        GLOBL   C_SYMBOL_NAME(_gcry_mpih_submul_1)
 C_SYMBOL_NAME(_gcry_mpih_submul_1:)
-
+       FUNC_ENTRY()
        movq    %rdx, %r11
        leaq    (%rsi,%r11,8), %rsi
        leaq    (%rdi,%r11,8), %rdi
@@ -63,4 +63,5 @@ C_SYMBOL_NAME(_gcry_mpih_submul_1:)
        jne     .Loop
 
        movq    %r8, %rax
+       FUNC_EXIT()
        ret
index 4cfc8f6..311b85b 100644 (file)
@@ -42,6 +42,7 @@
 .text
        .globl C_SYMBOL_NAME(_gcry_mpih_rshift)
 C_SYMBOL_NAME(_gcry_mpih_rshift:)
+       FUNC_ENTRY()
        movq    (%rsi), %mm7
        movd    %ecx, %mm1
        movl    $64, %eax
@@ -77,4 +78,5 @@ C_SYMBOL_NAME(_gcry_mpih_rshift:)
 .Lende:        psrlq   %mm1, %mm2
        movq    %mm2, -8(%rdi)
        emms
+       FUNC_EXIT()
        ret
index b3609b0..ccf6496 100644 (file)
@@ -42,6 +42,7 @@
 .text
        .globl C_SYMBOL_NAME(_gcry_mpih_sub_n)
 C_SYMBOL_NAME(_gcry_mpih_sub_n:)
+       FUNC_ENTRY()
        leaq    (%rsi,%rcx,8), %rsi
        leaq    (%rdi,%rcx,8), %rdi
        leaq    (%rdx,%rcx,8), %rdx
@@ -58,4 +59,5 @@ C_SYMBOL_NAME(_gcry_mpih_sub_n:)
 
        movq    %rcx, %rax              /* zero %rax */
        adcq    %rax, %rax
+       FUNC_EXIT()
        ret
index f44299d..3ead4f0 100644 (file)
@@ -50,11 +50,12 @@ case "${host}" in
        path=""
        mpi_cpu_arch="x86"
        ;;
-    i[3467]86*-*-openbsd*      | \
-    i[3467]86*-*-freebsd*-elf  | \
-    i[3467]86*-*-freebsd[3-9]* | \
-    i[3467]86*-*-freebsdelf*   | \
-    i[3467]86*-*-netbsd*       | \
+    i[3467]86*-*-openbsd*         | \
+    i[3467]86*-*-freebsd*-elf     | \
+    i[3467]86*-*-freebsd[3-9]*    | \
+    i[3467]86*-*-freebsd[12][0-9]*| \
+    i[3467]86*-*-freebsdelf*      | \
+    i[3467]86*-*-netbsd*          | \
     i[3467]86*-*-k*bsd*)
        echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
        cat  $srcdir/mpi/i386/syntax.h     >>./mpi/asm-syntax.h
@@ -64,6 +65,7 @@ case "${host}" in
     i586*-*-openbsd*         | \
     i586*-*-freebsd*-elf     | \
     i586*-*-freebsd[3-9]*    | \
+    i586*-*-freebsd[12][0-9]*| \
     i586*-*-freebsdelf*      | \
     i586*-*-netbsd*         | \
     i586*-*-k*bsd*          | \
@@ -129,12 +131,22 @@ case "${host}" in
     x86_64-apple-darwin*)
        echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h
        cat  $srcdir/mpi/i386/syntax.h      >>./mpi/asm-syntax.h
+       cat  $srcdir/mpi/amd64/func_abi.h   >>./mpi/asm-syntax.h
        path="amd64"
         mpi_cpu_arch="x86"
        ;;
+    x86_64-*mingw32*)
+       echo '#define USE_MS_ABI' >>./mpi/asm-syntax.h
+       echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+       cat  $srcdir/mpi/i386/syntax.h      >>./mpi/asm-syntax.h
+       cat  $srcdir/mpi/amd64/func_abi.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
+       cat  $srcdir/mpi/amd64/func_abi.h   >>./mpi/asm-syntax.h
        path="amd64"
         mpi_cpu_arch="x86"
        ;;
@@ -309,7 +321,7 @@ case "${host}" in
        echo '#define ELF_SYNTAX'               >>./mpi/asm-syntax.h
        cat   $srcdir/mpi/powerpc32/syntax.h    >>./mpi/asm-syntax.h
        path="powerpc32"
-       mpi_cpu_arch="ppc"
+       mpi_cpu_arch="ppc"
        ;;
 
     rs6000-*-aix[456789]*    | \
index 168076f..26dd947 100644 (file)
--- a/mpi/ec.c
+++ b/mpi/ec.c
@@ -139,6 +139,34 @@ point_set (mpi_point_t d, mpi_point_t s)
 }
 
 
+static void
+point_resize (mpi_point_t p, mpi_ec_t ctx)
+{
+  /*
+   * For now, we allocate enough limbs for our EC computation of ec_*.
+   * Once we will improve ec_* to be constant size (and constant
+   * time), NLIMBS can be ctx->p->nlimbs.
+   */
+  size_t nlimbs = 2*ctx->p->nlimbs+1;
+
+  mpi_resize (p->x, nlimbs);
+  if (ctx->model != MPI_EC_MONTGOMERY)
+    mpi_resize (p->y, nlimbs);
+  mpi_resize (p->z, nlimbs);
+}
+
+
+static void
+point_swap_cond (mpi_point_t d, mpi_point_t s, unsigned long swap,
+                 mpi_ec_t ctx)
+{
+  mpi_swap_cond (d->x, s->x, swap);
+  if (ctx->model != MPI_EC_MONTGOMERY)
+    mpi_swap_cond (d->y, s->y, swap);
+  mpi_swap_cond (d->z, s->z, swap);
+}
+
+
 /* Set the projective coordinates from POINT into X, Y, and Z.  If a
    coordinate is not required, X, Y, or Z may be passed as NULL.  */
 void
@@ -247,8 +275,9 @@ ec_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx)
 static void
 ec_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ec)
 {
-  (void)ec;
   mpi_sub (w, u, v);
+  while (w->sign)
+    mpi_add (w, w, ec->p);
   /*ec_mod (w, ec);*/
 }
 
@@ -429,6 +458,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);
@@ -495,7 +525,7 @@ _gcry_mpi_ec_p_new (gcry_ctx_t *r_ctx,
   mpi_ec_t ec;
 
   *r_ctx = NULL;
-  if (!p || !a || !mpi_cmp_ui (a, 0))
+  if (!p || !a)
     return GPG_ERR_EINVAL;
 
   ctx = _gcry_ctx_alloc (CONTEXT_TYPE_EC, sizeof *ec, ec_deinit);
@@ -560,6 +590,27 @@ _gcry_mpi_ec_set_point (const char *name, gcry_mpi_point_t newvalue,
 }
 
 
+/* Given an encoded point in the MPI VALUE and a context EC, decode
+ * the point according to the context and store it in RESULT.  On
+ * error an error code is return but RESULT might have been changed.
+ * If no context is given the function tries to decode VALUE by
+ * assuming a 0x04 prefixed uncompressed encoding.  */
+gpg_err_code_t
+_gcry_mpi_ec_decode_point (mpi_point_t result, gcry_mpi_t value, mpi_ec_t ec)
+{
+  gcry_err_code_t rc;
+
+  if (ec && ec->dialect == ECC_DIALECT_ED25519)
+    rc = _gcry_ecc_eddsa_decodepoint (value, ec, result, NULL, NULL);
+  else if (ec && ec->model == MPI_EC_MONTGOMERY)
+    rc = _gcry_ecc_mont_decodepoint (value, ec, result);
+  else
+    rc = _gcry_ecc_os2ec (result, value);
+
+  return rc;
+}
+
+
 /* Compute the affine coordinates from the projective coordinates in
    POINT.  Set them into X and Y.  If one coordinate is not required,
    X or Y may be passed as NULL.  CTX is the usual context. Returns: 0
@@ -600,12 +651,19 @@ _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_TWISTEDEDWARDS:
+    case MPI_EC_EDWARDS:
       {
         gcry_mpi_t z;
 
@@ -725,7 +783,7 @@ dup_point_montgomery (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx)
 
 /*  RESULT = 2 * POINT  (Twisted Edwards version). */
 static void
-dup_point_twistededwards (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx)
+dup_point_edwards (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx)
 {
 #define X1 (point->x)
 #define Y1 (point->y)
@@ -754,10 +812,7 @@ dup_point_twistededwards (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx)
 
   /* E = aC */
   if (ctx->dialect == ECC_DIALECT_ED25519)
-    {
-      mpi_set (E, C);
-      _gcry_mpi_neg (E, E);
-    }
+    mpi_sub (E, ctx->p, C);
   else
     ec_mulm (E, ctx->a, C, ctx);
 
@@ -811,8 +866,8 @@ _gcry_mpi_ec_dup_point (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx)
     case MPI_EC_MONTGOMERY:
       dup_point_montgomery (result, point, ctx);
       break;
-    case MPI_EC_TWISTEDEDWARDS:
-      dup_point_twistededwards (result, point, ctx);
+    case MPI_EC_EDWARDS:
+      dup_point_edwards (result, point, ctx);
       break;
     }
 }
@@ -977,9 +1032,9 @@ add_points_montgomery (mpi_point_t result,
 
 /* RESULT = P1 + P2  (Twisted Edwards version).*/
 static void
-add_points_twistededwards (mpi_point_t result,
-                           mpi_point_t p1, mpi_point_t p2,
-                           mpi_ec_t ctx)
+add_points_edwards (mpi_point_t result,
+                    mpi_point_t p1, mpi_point_t p2,
+                    mpi_ec_t ctx)
 {
 #define X1 (p1->x)
 #define Y1 (p1->y)
@@ -1035,11 +1090,7 @@ add_points_twistededwards (mpi_point_t result,
   /* Y_3 = A · G · (D - aC) */
   if (ctx->dialect == ECC_DIALECT_ED25519)
     {
-      /* Using ec_addm (Y3, D, C, ctx) is possible but a litte bit
-         slower because a subm does currently skip the mod step.  */
-      mpi_set (Y3, C);
-      _gcry_mpi_neg (Y3, Y3);
-      ec_subm (Y3, D, Y3, ctx);
+      ec_addm (Y3, D, C, ctx);
     }
   else
     {
@@ -1073,6 +1124,35 @@ add_points_twistededwards (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,
@@ -1087,8 +1167,73 @@ _gcry_mpi_ec_add_points (mpi_point_t result,
     case MPI_EC_MONTGOMERY:
       add_points_montgomery (result, p1, p2, ctx);
       break;
-    case MPI_EC_TWISTEDEDWARDS:
-      add_points_twistededwards (result, p1, p2, ctx);
+    case MPI_EC_EDWARDS:
+      add_points_edwards (result, p1, p2, ctx);
+      break;
+    }
+}
+
+
+/* RESULT = P1 - P2  (Weierstrass version).*/
+static void
+sub_points_weierstrass (mpi_point_t result,
+                        mpi_point_t p1, mpi_point_t p2,
+                        mpi_ec_t ctx)
+{
+  (void)result;
+  (void)p1;
+  (void)p2;
+  (void)ctx;
+  log_fatal ("%s: %s not yet supported\n",
+             "_gcry_mpi_ec_sub_points", "Weierstrass");
+}
+
+
+/* RESULT = P1 - P2  (Montgomery version).*/
+static void
+sub_points_montgomery (mpi_point_t result,
+                       mpi_point_t p1, mpi_point_t p2,
+                       mpi_ec_t ctx)
+{
+  (void)result;
+  (void)p1;
+  (void)p2;
+  (void)ctx;
+  log_fatal ("%s: %s not yet supported\n",
+             "_gcry_mpi_ec_sub_points", "Montgomery");
+}
+
+
+/* RESULT = P1 - P2  (Twisted Edwards version).*/
+static void
+sub_points_edwards (mpi_point_t result,
+                    mpi_point_t p1, mpi_point_t p2,
+                    mpi_ec_t ctx)
+{
+  mpi_point_t p2i = _gcry_mpi_point_new (0);
+  point_set (p2i, p2);
+  mpi_sub (p2i->x, ctx->p, p2i->x);
+  add_points_edwards (result, p1, p2i, ctx);
+  _gcry_mpi_point_release (p2i);
+}
+
+
+/* RESULT = P1 - P2 */
+void
+_gcry_mpi_ec_sub_points (mpi_point_t result,
+                         mpi_point_t p1, mpi_point_t p2,
+                         mpi_ec_t ctx)
+{
+  switch (ctx->model)
+    {
+    case MPI_EC_WEIERSTRASS:
+      sub_points_weierstrass (result, p1, p2, ctx);
+      break;
+    case MPI_EC_MONTGOMERY:
+      sub_points_montgomery (result, p1, p2, ctx);
+      break;
+    case MPI_EC_EDWARDS:
+      sub_points_edwards (result, p1, p2, ctx);
       break;
     }
 }
@@ -1106,16 +1251,27 @@ _gcry_mpi_ec_mul_point (mpi_point_t result,
   unsigned int i, loops;
   mpi_point_struct p1, p2, p1inv;
 
-  if (ctx->model == MPI_EC_TWISTEDEDWARDS)
+  if (ctx->model == MPI_EC_EDWARDS
+      || (ctx->model == MPI_EC_WEIERSTRASS
+          && mpi_is_secure (scalar)))
     {
       /* Simple left to right binary method.  GECC Algorithm 3.27 */
       unsigned int nbits;
       int j;
 
       nbits = mpi_get_nbits (scalar);
-      mpi_set_ui (result->x, 0);
-      mpi_set_ui (result->y, 1);
-      mpi_set_ui (result->z, 1);
+      if (ctx->model == MPI_EC_WEIERSTRASS)
+        {
+          mpi_set_ui (result->x, 1);
+          mpi_set_ui (result->y, 1);
+          mpi_set_ui (result->z, 0);
+        }
+      else
+        {
+          mpi_set_ui (result->x, 0);
+          mpi_set_ui (result->y, 1);
+          mpi_set_ui (result->z, 1);
+        }
 
       if (mpi_is_secure (scalar))
         {
@@ -1124,12 +1280,13 @@ _gcry_mpi_ec_mul_point (mpi_point_t result,
           mpi_point_struct tmppnt;
 
           point_init (&tmppnt);
+          point_resize (result, ctx);
+          point_resize (&tmppnt, ctx);
           for (j=nbits-1; j >= 0; j--)
             {
               _gcry_mpi_ec_dup_point (result, result, ctx);
               _gcry_mpi_ec_add_points (&tmppnt, result, point, ctx);
-              if (mpi_test_bit (scalar, j))
-                point_set (result, &tmppnt);
+              point_swap_cond (result, &tmppnt, mpi_test_bit (scalar, j), ctx);
             }
           point_free (&tmppnt);
         }
@@ -1144,6 +1301,74 @@ _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_;
+      mpi_point_t q1, q2, prd, sum;
+      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);
+
+      point_resize (&p1, ctx);
+      point_resize (&p2, ctx);
+      point_resize (&p1_, ctx);
+      point_resize (&p2_, ctx);
+
+      q1 = &p1;
+      q2 = &p2;
+      prd = &p1_;
+      sum = &p2_;
+
+      for (j=nbits-1; j >= 0; j--)
+        {
+          mpi_point_t t;
+
+          sw = mpi_test_bit (scalar, j);
+          point_swap_cond (q1, q2, sw, ctx);
+          montgomery_ladder (prd, sum, q1, q2, point->x, ctx);
+          point_swap_cond (prd, sum, sw, ctx);
+          t = q1;  q1 = prd;  prd = t;
+          t = q2;  q2 = sum;  sum = t;
+        }
+
+      mpi_clear (result->y);
+      sw = (nbits & 1);
+      point_swap_cond (&p1, &p1_, sw, ctx);
+
+      if (p1.z->nlimbs == 0)
+        {
+          mpi_set_ui (result->x, 1);
+          mpi_set_ui (result->z, 0);
+        }
+      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);
+        }
+
+      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);
@@ -1205,6 +1430,10 @@ _gcry_mpi_ec_mul_point (mpi_point_t result,
   point_init (&p2);
   point_init (&p1inv);
 
+  /* Invert point: y = p - y mod p  */
+  point_set (&p1inv, &p1);
+  ec_subm (p1inv.y, ctx->p, p1inv.y, ctx);
+
   for (i=loops-2; i > 0; i--)
     {
       _gcry_mpi_ec_dup_point (result, result, ctx);
@@ -1216,9 +1445,6 @@ _gcry_mpi_ec_mul_point (mpi_point_t result,
       if (mpi_test_bit (h, i) == 0 && mpi_test_bit (k, i) == 1)
         {
           point_set (&p2, result);
-          /* Invert point: y = p - y mod p  */
-          point_set (&p1inv, &p1);
-          ec_subm (p1inv.y, ctx->p, p1inv.y, ctx);
           _gcry_mpi_ec_add_points (result, &p2, &p1inv, ctx);
         }
     }
@@ -1242,14 +1468,16 @@ _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);
+        gcry_mpi_t xxx;
+
+        if (_gcry_mpi_ec_get_affine (x, y, point, ctx))
+          goto leave;
+
+        xxx = mpi_new (0);
 
         /* y^2 == x^3 + a·x + b */
         ec_pow2 (y, y, ctx);
@@ -1266,19 +1494,45 @@ _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))
+          goto leave;
+
+        /* 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_TWISTEDEDWARDS:
+    case MPI_EC_EDWARDS:
       {
+        if (_gcry_mpi_ec_get_affine (x, y, point, ctx))
+          goto leave;
+
         /* a · x^2 + y^2 - 1 - b · x^2 · y^2 == 0 */
         ec_pow2 (x, x, ctx);
         ec_pow2 (y, y, ctx);
         if (ctx->dialect == ECC_DIALECT_ED25519)
-          {
-            mpi_set (w, x);
-            _gcry_mpi_neg (w, w);
-          }
+          mpi_sub (w, ctx->p, x);
         else
           ec_mulm (w, ctx->a, x, ctx);
         ec_addm (w, w, y, ctx);
@@ -1292,6 +1546,7 @@ _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx)
       break;
     }
 
+ leave:
   _gcry_mpi_release (w);
   _gcry_mpi_release (x);
   _gcry_mpi_release (y);
diff --git a/mpi/generic/Manifest b/mpi/generic/Manifest
deleted file mode 100644 (file)
index c429fde..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-# Manifest - checksums 
-# Copyright 2003 Free Software Foundation, Inc.
-#
-# This file is part of Libgcrypt.
-#
-# Libgcrypt is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser general Public License as
-# published by the Free Software Foundation; either version 2.1 of
-# the License, or (at your option) any later version.
-#
-# Libgcrypt is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
-mpih-add1.c iQCVAwUAP+Lj2DEAnp832S/7AQKn/AQAwQLWggl6zNQ5EZ+lE+jKV8W3FsogW3/6tp9T5rrSR5JnlWyoHQ9/Pu4knOcLjS6nIfVOiAEifu3nuIysQr9jDSSSJA2LylSUBSXKLKDamPsOCwXOLxiZODslJT3CCGAUtLvXJrWDbTZQrkEuwnLnjQFDzuA7iY9JLrG9kAoXD6Q==WoWm
-mpih-mul1.c iQCVAwUAP+LkCTEAnp832S/7AQKFVQP+MhBNjcY73JtnsHZfnaVZq3TiKwN151cWV51nDc1RnTaMhSIFeuNlj3vNML2W0Gn8n+GnyiWE2XXdQEaik6BL02eekUn9aq7I/rdpnTHuOjQPK1uwjuNl8RuJ9YrERBAxq4oB71f+iwMab8dsMSUlVC+NdeAocRqLLgnR/efkdLc==2Tkb
-mpih-mul2.c iQCVAwUAP+LkMjEAnp832S/7AQLPeAQAqmRzxFe/mDqTdZr/pTXT8RVyB1vKB0Ei2THV05BxmI4OPv39uysfFpLMt/INsX7AGqdOlj4jOZ/qNaFXR1ceMrlSXvo8u/epk6rCXFp82kM7Qs983LjoP//PrMCkYkXwblaVrgUGiBUCbuPMliWTK6qKkxxXtEfqZ7nVbEWdBx8==Kwhl
-mpih-mul3.c iQCVAwUAP+LkVDEAnp832S/7AQL91gP/Qd5iZWxRiN5DdEIVHAedoNvl23NPrT2UUdXvnSK49DpplTxkLiMBj0WqCayG/YIET2NpMRCeLvAZNcSt6lOm0bSZDYo1Hv/N+UoqD3V1McjY16REBv/nnPaMWMZcx7rl5yKTVZiX2PgV6oQOL7Yfrt5ZIOlrHBRs9S2/zcCaVz0==9BQe
-mpih-lshift.c iQCVAwUAP+LlATEAnp832S/7AQIACAQAhMrpx0SRXE/LN1NkjMO9n74nMrvmzYJyru0gw2O4BYrUPvD/LWGju2FZaggKV0IBjmi0cDoCrNeK9EGjKOO1lfgODbX2IZ1LUhr9jDuMj0QRqj6T9YkAFYTNUk4GfpwIf7T6Ybo7c78Jx93PidCJt7d39eMMEalooC7LZ4IU3NM==nZ4k
-mpih-rshift.c iQCVAwUAP+LlIjEAnp832S/7AQKiuAP/eYC2ZScd+taBx/kNzRvGjA0eAXvORMkMLV6Ot+OXVzVUi04eoP2yXdxSNFKwUj12p8GWXkdoMG3aOGBKg2a7bY5Q5RUho3hUWb9UsVYVUfXLf7IOTt/3a6MLh2CmV5dFPWJmSlbCyQRcn6n/fLDeJ3A2bWTS/BhqGfpOXUIU1ws==jCf8
-mpih-sub1.c iQCVAwUAP+LlZzEAnp832S/7AQIEPgP/dLHTDRbPrYJhsLp9SjGstU1M8/IC5XytcDtO3NQeu4mx6vaXjpujtsTvKIbX4QL5IahNntVVKv1xFLEm2yFg7L2ns0uD/mfwGgOhCG1j2o/SaTAWP5KxP7ae5UDcZl2w6NWvEuMj9t32zmziAZjP8W73A37FUspeRDYiL9sQzkI==QQzk
-udiv-w-sdiv.c iQCVAwUAP+Lk0TEAnp832S/7AQICXAQAsxe1SQD4+xZaZTqBC0V9Cyuo0mrdccnRFzthOtm0ARwKFXU2cuLW/ZBOkmeWOVmOFhBp22/I8dEGYnMA3gcfmOMCpNu9i9zk/XHfptdunA1MnOe3GsoWgfHL0rhpAyPhp/X043ICB41NElnnuxADuQQlD4Z1fca5ygYxMr2crJg==EI/6
-mpi-asm-defs.h iQCVAwUAP+LkgDEAnp832S/7AQK0FgQAxJZ7xvXhoZa33GWe23LRb3asrno/loZSyAIXrntqtVH8M3pEsCY0OyW4ry4hX2RnxpuhRCM/PdRNLG3xXyMSVIhkHU8WVRLqzF2LLjEkyU3cAmHnnTQ9aO/XpUWtJGTZ8q2bv7ZsAEi4aPl0p6KhPXcPgM9vQ2XcyOPn3Dl0d6Q==xpjI
-$names$ iQCVAwUAP+LmNDEAnp832S/7AQJa+gP+KQNJpbNOgc+s2UX+Ya2gDaOFcAROImIllhg3ej8EaBF8xxdHmWT1zaKwTwi3moEEleykMR104YAGWyQeMbFYiuPPBW+ohrT6KxRBVJpIA9auOOqqJMyglZyoR3Hv7gduVYUW1h/DebnqiKXKEfzQDFqYuT0ayuteoOR4B5NICbE==nLSh
index 9810eef..649e829 100644 (file)
@@ -1,4 +1,3 @@
-Manifest
 mpih-add1.c
 mpih-mul1.c
 mpih-mul2.c
diff --git a/mpi/i386/Manifest b/mpi/i386/Manifest
deleted file mode 100644 (file)
index 812bc8a..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-# Manifest - checksums 
-# Copyright 2003 Free Software Foundation, Inc.
-#
-# This file is part of Libgcrypt.
-#
-# Libgcrypt is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser general Public License as
-# published by the Free Software Foundation; either version 2.1 of
-# the License, or (at your option) any later version.
-#
-# Libgcrypt is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
-mpih-add1.S
-mpih-mul1.S
-mpih-mul2.S
-mpih-mul3.S
-mpih-lshift.S
-mpih-rshift.S
-mpih-sub1.S
-syntax.h
-$names$ iQCVAwUAP+LmOTEAnp832S/7AQJZmgQA1+GIl7rXiEY00y5xD2kG5Lm2QD6c9aBME8hTl812OEcj0ul/QSpdv8E2NEKooifr4SiLVhEVfLNaLqAgN3cIsttn3rRX3/pMC5JwSKHDJPsUbpN9tzb5dr2YC9GG9m8xngAQrN11IQPnGfvFLJK+oDnEMIAeHDpOnX9NeQPDAQA==bnOy
index 22b9979..88d2a30 100644 (file)
@@ -1,4 +1,3 @@
-Manifest
 mpih-add1.S
 mpih-mul1.S
 mpih-mul2.S
diff --git a/mpi/i586/Manifest b/mpi/i586/Manifest
deleted file mode 100644 (file)
index 6d1d7f8..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-# Manifest - checksums 
-# Copyright 2003 Free Software Foundation, Inc.
-#
-# This file is part of Libgcrypt.
-#
-# Libgcrypt is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser general Public License as
-# published by the Free Software Foundation; either version 2.1 of
-# the License, or (at your option) any later version.
-#
-# Libgcrypt is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
-mpih-add1.S
-mpih-mul1.S
-mpih-mul2.S
-mpih-mul3.S
-mpih-lshift.S
-mpih-rshift.S
-mpih-sub1.S
-$names$ iQCVAwUAP+LmQDEAnp832S/7AQKCmgQAhG+E7X0KB4qdVf3sMb6Qr+Iv5Jlehzoub/5vxTRgePKzRuOHidCnTzSSoyzA++UcHrOjHQQDMsXnO6PqpS1d/TKkxjnGN7rE8mvMYlFAT8RsawTozSfh14mCzI0HTDbaKL9Z8pcMJtadB3XqAuqWJNO8kyECJFwurt3DRWXSWS8==Rug5
index 546f777..8f821fb 100644 (file)
@@ -1,4 +1,3 @@
-Manifest
 mpih-add1.S
 mpih-mul1.S
 mpih-mul2.S
index 4f33937..0a5acb6 100644 (file)
@@ -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__) || defined(__sparcv8)
 /* 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  *********
+ ***************************************/
diff --git a/mpi/m68k/Manifest b/mpi/m68k/Manifest
deleted file mode 100644 (file)
index 8e0538a..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# Manifest - checksums 
-# Copyright 2003 Free Software Foundation, Inc.
-#
-# This file is part of Libgcrypt.
-#
-# Libgcrypt is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser general Public License as
-# published by the Free Software Foundation; either version 2.1 of
-# the License, or (at your option) any later version.
-#
-# Libgcrypt is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
-syntax.h
-mpih-lshift.S
-mpih-rshift.S
-mpih-add1.S
-mpih-sub1.S
-$names$ iQCVAwUAP+LmTDEAnp832S/7AQJHUAP/dxfq2U0pDc5ZLoEizoqgjjcnHIyb9EjMG3YjvgK6jQ62yoAOCuo/jFYlJS+Mdve6bgfdTzYMrnKV7BG2SEcwb263pVnIntS7ZhKQPiMCbFgXWR2VjN3+a1v8yjQDZtgqEgm8OlQ+u7jKBY13Oryiuq5nPNxsXZqJpelG6Zkdg9M==PIee
index 1e2e36f..4c0967b 100644 (file)
@@ -1,4 +1,3 @@
-Manifest
 syntax.h
 mpih-lshift.S
 mpih-rshift.S
diff --git a/mpi/m68k/mc68020/Manifest b/mpi/m68k/mc68020/Manifest
deleted file mode 100644 (file)
index bcb2768..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-# Manifest - checksums 
-# Copyright 2003 Free Software Foundation, Inc.
-#
-# This file is part of Libgcrypt.
-#
-# Libgcrypt is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser general Public License as
-# published by the Free Software Foundation; either version 2.1 of
-# the License, or (at your option) any later version.
-#
-# Libgcrypt is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
-mpih-mul1.S
-mpih-mul2.S
-mpih-mul3.S
-$names$ iQCVAwUAP+LmRTEAnp832S/7AQK3rwP/TyGBbii5HCrjDiLCVJHiDNeOdENx6AicRXnu4vuJmMmPZ0y+i7MPusDaeTbIUA0w6RaJx+Ep41nIvthmNDnFePY5Mw0pIUJcpI7AJR4vYqpwNQA6nlEdn/m1jg6sPLKZXUXNUkhroEzcHzoU+12BPS+nvSXlwSksg6rXEGOJ+Ms==XCXP
index 6b96433..fc7df9f 100644 (file)
@@ -1,4 +1,3 @@
-Manifest
 mpih-mul1.S
 mpih-mul2.S
 mpih-mul3.S
diff --git a/mpi/mips3/Manifest b/mpi/mips3/Manifest
deleted file mode 100644 (file)
index e191184..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-# Manifest - checksums 
-# Copyright 2003 Free Software Foundation, Inc.
-#
-# This file is part of Libgcrypt.
-#
-# Libgcrypt is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser general Public License as
-# published by the Free Software Foundation; either version 2.1 of
-# the License, or (at your option) any later version.
-#
-# Libgcrypt is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
-mpih-add1.S
-mpih-sub1.S
-mpih-mul1.S
-mpih-mul2.S
-mpih-mul3.S
-mpih-lshift.S
-mpih-rshift.S
-mpi-asm-defs.h
-$names$ iQCVAwUAP+LmUTEAnp832S/7AQLm/gP/RHR2aLMwHPxsq0mGO5H0kneVn8a9l9yDNEZBefkYcOJMb7MZGKxbGspyENiU04Mc2TFnA1wS9gjNHlRWtUYxxn/wyuV6BIRgfstXt2nXGgEQrK07GIz8ETFcYqcxu7JKiICIuXZgnIgdwBJswbBV1zaMUDXeg5B8vkkEeRWj8hQ==IQVO
index ef9b6fe..85260fc 100644 (file)
@@ -1,4 +1,3 @@
-Manifest
 README
 mpih-add1.S
 mpih-sub1.S
index 0f0947f..a780ebd 100644 (file)
@@ -83,6 +83,7 @@ _gcry_mpi_powm (gcry_mpi_t res,
 
   rp = res->d;
   ep = expo->d;
+  MPN_NORMALIZE(ep, esize);
 
   if (!msize)
     _gcry_divide_by_zero();
@@ -381,7 +382,7 @@ mul_mod (mpi_ptr_t xp, mpi_size_t *xsize_p,
      *xsize_p = rsize + ssize;
 }
 
-#define SIZE_B_2I3 ((1 << (5 - 1)) - 1)
+#define SIZE_PRECOMP ((1 << (5 - 1)))
 
 /****************
  * RES = BASE ^ EXPO mod MOD
@@ -417,17 +418,21 @@ _gcry_mpi_powm (gcry_mpi_t res,
   unsigned int bp_nlimbs = 0;
   unsigned int ep_nlimbs = 0;
   unsigned int xp_nlimbs = 0;
-  mpi_ptr_t b_2i3[SIZE_B_2I3]; /* Pre-computed array: BASE^3, ^5, ^7, ... */
-  mpi_size_t b_2i3size[SIZE_B_2I3];
+  mpi_ptr_t precomp[SIZE_PRECOMP]; /* Pre-computed array: BASE^1, ^3, ^5, ... */
+  mpi_size_t precomp_size[SIZE_PRECOMP];
   mpi_size_t W;
   mpi_ptr_t base_u;
   mpi_size_t base_u_size;
+  mpi_size_t max_u_size;
 
   esize = expo->nlimbs;
   msize = mod->nlimbs;
   size = 2 * msize;
   msign = mod->sign;
 
+  ep = expo->d;
+  MPN_NORMALIZE(ep, esize);
+
   if (esize * BITS_PER_MPI_LIMB > 512)
     W = 5;
   else if (esize * BITS_PER_MPI_LIMB > 256)
@@ -444,7 +449,6 @@ _gcry_mpi_powm (gcry_mpi_t res,
   bsec = mpi_is_secure(base);
 
   rp = res->d;
-  ep = expo->d;
 
   if (!msize)
     _gcry_divide_by_zero();
@@ -506,7 +510,8 @@ _gcry_mpi_powm (gcry_mpi_t res,
     }
 
 
-  /* Make BASE, EXPO and MOD not overlap with RES.  */
+  /* Make BASE, EXPO not overlap with RES.  We don't need to check MOD
+     because that has already been copied to the MP var.  */
   if ( rp == bp )
     {
       /* RES and BASE are identical.  Allocate temp. space for BASE.  */
@@ -522,14 +527,6 @@ _gcry_mpi_powm (gcry_mpi_t res,
       ep = ep_marker = mpi_alloc_limb_space( esize, esec );
       MPN_COPY(ep, rp, esize);
     }
-  if ( rp == mp )
-    {
-      /* RES and MOD are identical.  Allocate temporary space for MOD.*/
-      gcry_assert (!mp_marker);
-      mp_nlimbs = msec?msize:0;
-      mp = mp_marker = mpi_alloc_limb_space( msize, msec );
-      MPN_COPY(mp, rp, msize);
-    }
 
   /* Copy base to the result.  */
   if (res->alloced < size)
@@ -540,7 +537,7 @@ _gcry_mpi_powm (gcry_mpi_t res,
 
   /* Main processing.  */
   {
-    mpi_size_t i, j;
+    mpi_size_t i, j, k;
     mpi_ptr_t xp;
     mpi_size_t xsize;
     int c;
@@ -555,33 +552,30 @@ _gcry_mpi_powm (gcry_mpi_t res,
     memset( &karactx, 0, sizeof karactx );
     negative_result = (ep[0] & 1) && bsign;
 
-    /* Precompute B_2I3[], BASE^(2 * i + 3), BASE^3, ^5, ^7, ... */
+    /* Precompute PRECOMP[], BASE^(2 * i + 1), BASE^1, ^3, ^5, ... */
     if (W > 1)                  /* X := BASE^2 */
       mul_mod (xp, &xsize, bp, bsize, bp, bsize, mp, msize, &karactx);
-    for (i = 0; i < (1 << (W - 1)) - 1; i++)
-      {                         /* B_2I3[i] = BASE^(2 * i + 3) */
-        if (i == 0)
-          {
-            base_u = bp;
-            base_u_size = bsize;
-          }
-        else
-          {
-            base_u = b_2i3[i-1];
-            base_u_size = b_2i3size[i-1];
-          }
-
+    base_u = precomp[0] = mpi_alloc_limb_space (bsize, esec);
+    base_u_size = max_u_size = precomp_size[0] = bsize;
+    MPN_COPY (precomp[0], bp, bsize);
+    for (i = 1; i < (1 << (W - 1)); i++)
+      {                         /* PRECOMP[i] = BASE^(2 * i + 1) */
         if (xsize >= base_u_size)
           mul_mod (rp, &rsize, xp, xsize, base_u, base_u_size,
                    mp, msize, &karactx);
         else
           mul_mod (rp, &rsize, base_u, base_u_size, xp, xsize,
                    mp, msize, &karactx);
-        b_2i3[i] = mpi_alloc_limb_space (rsize, esec);
-        b_2i3size[i] = rsize;
-        MPN_COPY (b_2i3[i], rp, rsize);
+        base_u = precomp[i] = mpi_alloc_limb_space (rsize, esec);
+        base_u_size = precomp_size[i] = rsize;
+        if (max_u_size < base_u_size)
+          max_u_size = base_u_size;
+        MPN_COPY (precomp[i], rp, rsize);
       }
 
+    base_u = mpi_alloc_limb_space (max_u_size, esec);
+    MPN_ZERO (base_u, max_u_size);
+
     i = esize - 1;
 
     /* Main loop.
@@ -667,15 +661,23 @@ _gcry_mpi_powm (gcry_mpi_t res,
               rsize = xsize;
             }
 
-          if (e0 == 0)
+          /*
+           *  base_u <= precomp[e0]
+           *  base_u_size <= precomp_size[e0]
+           */
+          base_u_size = 0;
+          for (k = 0; k < (1<< (W - 1)); k++)
             {
-              base_u = bp;
-              base_u_size = bsize;
-            }
-          else
-            {
-              base_u = b_2i3[e0 - 1];
-              base_u_size = b_2i3size[e0 -1];
+              struct gcry_mpi w, u;
+              w.alloced = w.nlimbs = precomp_size[k];
+              u.alloced = u.nlimbs = precomp_size[k];
+              w.sign = u.sign = 0;
+              w.flags = u.flags = 0;
+              w.d = base_u;
+              u.d = precomp[k];
+
+              mpi_set_cond (&w, &u, k == e0);
+              base_u_size |= (precomp_size[k] & ((mpi_size_t)0 - (k == e0)) );
             }
 
           mul_mod (xp, &xsize, rp, rsize, base_u, base_u_size,
@@ -703,15 +705,23 @@ _gcry_mpi_powm (gcry_mpi_t res,
 
     if (e != 0)
       {
-        if ((e>>1) == 0)
-          {
-            base_u = bp;
-            base_u_size = bsize;
-          }
-        else
+        /*
+         * base_u <= precomp[(e>>1)]
+         * base_u_size <= precomp_size[(e>>1)]
+         */
+        base_u_size = 0;
+        for (k = 0; k < (1<< (W - 1)); k++)
           {
-            base_u = b_2i3[(e>>1) - 1];
-            base_u_size = b_2i3size[(e>>1) -1];
+            struct gcry_mpi w, u;
+            w.alloced = w.nlimbs = precomp_size[k];
+            u.alloced = u.nlimbs = precomp_size[k];
+            w.sign = u.sign = 0;
+            w.flags = u.flags = 0;
+            w.d = base_u;
+            u.d = precomp[k];
+
+            mpi_set_cond (&w, &u, k == (e>>1));
+            base_u_size |= (precomp_size[k] & ((mpi_size_t)0 - (k == (e>>1))) );
           }
 
         mul_mod (xp, &xsize, rp, rsize, base_u, base_u_size,
@@ -761,8 +771,9 @@ _gcry_mpi_powm (gcry_mpi_t res,
     MPN_NORMALIZE (rp, rsize);
 
     _gcry_mpih_release_karatsuba_ctx (&karactx );
-    for (i = 0; i < (1 << (W - 1)) - 1; i++)
-      _gcry_mpi_free_limb_space( b_2i3[i], esec ? b_2i3size[i] : 0 );
+    for (i = 0; i < (1 << (W - 1)); i++)
+      _gcry_mpi_free_limb_space( precomp[i], esec ? precomp_size[i] : 0 );
+    _gcry_mpi_free_limb_space (base_u, esec ? max_u_size : 0);
   }
 
   /* Fixup for negative results.  */
index 896dda1..e315576 100644 (file)
 #include "mpi-internal.h"
 #include "g10lib.h"
 
+/* The maximum length we support in the functions converting an
+ * external representation to an MPI.  This limit is used to catch
+ * programming errors and to avoid DoS due to insane long allocations.
+ * The 16 MiB limit is actually ridiculous large but some of those PQC
+ * algorithms use quite large keys and they might end up using MPIs
+ * for that.  */
+#define MAX_EXTERN_SCAN_BYTES (16*1024*1024)
+
+/* The maximum length (in bits) we support for OpenPGP MPIs.  Note
+ * that OpenPGP's MPI format uses only two bytes and thus would be
+ * limited to 64k anyway.  Note that this limit matches that used by
+ * GnuPG.  */
 #define MAX_EXTERN_MPI_BITS 16384
 
+
 /* Helper used to scan PGP style MPIs.  Returns NULL on failure. */
 static gcry_mpi_t
 mpi_read_from_buffer (const unsigned char *buffer, unsigned *ret_nread,
@@ -104,7 +117,13 @@ mpi_fromstr (gcry_mpi_t val, const char *str)
   if ( *str == '0' && str[1] == 'x' )
     str += 2;
 
-  nbits = 4 * strlen (str);
+  nbits = strlen (str);
+  if (nbits > MAX_EXTERN_SCAN_BYTES)
+    {
+      mpi_clear (val);
+      return 1;  /* Error.  */
+    }
+  nbits *= 4;
   if ((nbits % 8))
     prepend_zero = 1;
 
@@ -438,9 +457,9 @@ twocompl (unsigned char *p, unsigned int n)
 
 
 /* Convert the external representation of an integer stored in BUFFER
  with a length of BUFLEN into a newly create MPI returned in
  RET_MPI.  If NBYTES is not NULL, it will receive the number of
  bytes actually scanned after a successful operation.  */
* with a length of BUFLEN into a newly create MPI returned in
* RET_MPI.  If NSCANNED is not NULL, it will receive the number of
* bytes actually scanned after a successful operation.  */
 gcry_err_code_t
 _gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
                 const void *buffer_arg, size_t buflen, size_t *nscanned)
@@ -450,6 +469,13 @@ _gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
   unsigned int len;
   int secure = (buffer && _gcry_is_secure (buffer));
 
+  if (buflen > MAX_EXTERN_SCAN_BYTES)
+    {
+      if (nscanned)
+        *nscanned = 0;
+      return GPG_ERR_INV_OBJ;
+    }
+
   if (format == GCRYMPI_FMT_SSH)
     len = 0;
   else
index fdce578..6dee0b9 100644 (file)
@@ -211,7 +211,12 @@ _gcry_mpi_free( gcry_mpi_t a )
   if (!a )
     return;
   if ((a->flags & 32))
+  {
+#if GPGRT_VERSION_NUMBER >= 0x011600  /* 1.22 */
+    gpgrt_annotate_leaked_object(a);
+#endif
     return; /* Never release a constant. */
+  }
   if ((a->flags & 4))
     xfree( a->d );
   else
@@ -343,7 +348,8 @@ _gcry_mpi_copy (gcry_mpi_t a)
     if( a && (a->flags & 4) ) {
        void *p = _gcry_is_secure(a->d)? xmalloc_secure ((a->sign+7)/8)
                                        : xmalloc ((a->sign+7)/8);
-       memcpy( p, a->d, (a->sign+7)/8 );
+        if (a->d)
+          memcpy( p, a->d, (a->sign+7)/8 );
        b = mpi_set_opaque( NULL, p, a->sign );
         b->flags &= ~(16|32); /* Reset the immutable and constant flags.  */
     }
@@ -482,6 +488,36 @@ _gcry_mpi_set (gcry_mpi_t w, gcry_mpi_t u)
   return w;
 }
 
+/****************
+ * Set the value of W by the one of U, when SET is 1.
+ * Leave the value when SET is 0.
+ * This implementation should be constant-time regardless of SET.
+ */
+gcry_mpi_t
+_gcry_mpi_set_cond (gcry_mpi_t w, const gcry_mpi_t u, unsigned long set)
+{
+  mpi_size_t i;
+  mpi_size_t nlimbs = u->alloced;
+  mpi_limb_t mask = ((mpi_limb_t)0) - set;
+  mpi_limb_t x;
+
+  if (w->alloced != u->alloced)
+    log_bug ("mpi_set_cond: different sizes\n");
+
+  for (i = 0; i < nlimbs; i++)
+    {
+      x = mask & (w->d[i] ^ u->d[i]);
+      w->d[i] = w->d[i] ^ x;
+    }
+
+  x = mask & (w->nlimbs ^ u->nlimbs);
+  w->nlimbs = w->nlimbs ^ x;
+
+  x = mask & (w->sign ^ u->sign);
+  w->sign = w->sign ^ x;
+  return w;
+}
+
 
 gcry_mpi_t
 _gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u)
@@ -542,6 +578,43 @@ _gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b)
 }
 
 
+/****************
+ * Swap the value of A and B, when SWAP is 1.
+ * Leave the value when SWAP is 0.
+ * This implementation should be constant-time regardless of SWAP.
+ */
+void
+_gcry_mpi_swap_cond (gcry_mpi_t a, gcry_mpi_t b, unsigned long swap)
+{
+  mpi_size_t i;
+  mpi_size_t nlimbs;
+  mpi_limb_t mask = ((mpi_limb_t)0) - swap;
+  mpi_limb_t x;
+
+  if (a->alloced > b->alloced)
+    nlimbs = b->alloced;
+  else
+    nlimbs = a->alloced;
+  if (a->nlimbs > nlimbs || b->nlimbs > nlimbs)
+    log_bug ("mpi_swap_cond: different sizes\n");
+
+  for (i = 0; i < nlimbs; i++)
+    {
+      x = mask & (a->d[i] ^ b->d[i]);
+      a->d[i] = a->d[i] ^ x;
+      b->d[i] = b->d[i] ^ x;
+    }
+
+  x = mask & (a->nlimbs ^ b->nlimbs);
+  a->nlimbs = a->nlimbs ^ x;
+  b->nlimbs = b->nlimbs ^ x;
+
+  x = mask & (a->sign ^ b->sign);
+  a->sign = a->sign ^ x;
+  b->sign = b->sign ^ x;
+}
+
+
 gcry_mpi_t
 _gcry_mpi_new (unsigned int nbits)
 {
diff --git a/mpi/pa7100/Manifest b/mpi/pa7100/Manifest
deleted file mode 100644 (file)
index f075ab0..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-# Manifest - checksums 
-# Copyright 2003 Free Software Foundation, Inc.
-#
-# This file is part of Libgcrypt.
-#
-# Libgcrypt is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as
-# published by the Free Software Foundation; either version 2.1 of
-# the License, or (at your option) any later version.
-#
-# Libgcrypt is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
-mpih-lshift.S
-mpih-rshift.S
-$names$ iQCVAwUAP+LmVjEAnp832S/7AQKlEQQAv2+x/d+Z0t8FwwHlxKpIKOJDr9e+Y2i8y8orcIEa3dnwU5LMOH3EzFoNSD9crc31FMokgm/X5xeLjqRTdcmGHyJJQJDPJVJyuaOm6qHJaFzzfJjrfMW66nJxfNSXIiIm4DgpP20NmumaorLCkiIZ5Z81KGAc8FiRggbRVYx+wxo==Vjh9
index e1cde4d..fece943 100644 (file)
@@ -1,4 +1,3 @@
-Manifest
 mpih-lshift.S
 mpih-rshift.S
 
diff --git a/mpi/power/Manifest b/mpi/power/Manifest
deleted file mode 100644 (file)
index c60fc23..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-# Manifest - checksums 
-# Copyright 2003 Free Software Foundation, Inc.
-#
-# This file is part of Libgcrypt.
-#
-# Libgcrypt is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as
-# published by the Free Software Foundation; either version 2.1 of
-# the License, or (at your option) any later version.
-#
-# Libgcrypt is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
-mpih-add1.S
-mpih-lshift.S
-mpih-mul1.S
-mpih-mul2.S
-mpih-mul3.S
-mpih-rshift.S
-mpih-sub1.S
-$names$ iQCVAwUAP+LmXTEAnp832S/7AQJ+ngP/XYr5Fvl/8WGVHcIKaehxvnKcSD2ILTWZNGubgnWp8ebIxVijjQCxYneTTy+zO0sNaB002neyscyiwaJj/JQIwZXfr06uGweIqlSpwpj9ndkoJc8E4/FZu+5NTO+E3RaBDAD+Tpo+MTfbC1s18p5i+an93VrSTgNck5PPYQrUcPA==sl3t
index e1bc008..e664c8d 100644 (file)
@@ -1,4 +1,3 @@
-Manifest
 mpih-add1.S
 mpih-lshift.S
 mpih-mul1.S
diff --git a/mpi/powerpc32/Manifest b/mpi/powerpc32/Manifest
deleted file mode 100644 (file)
index 26ab6ea..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-# Manifest - checksums 
-# Copyright 2003 Free Software Foundation, Inc.
-#
-# This file is part of Libgcrypt.
-#
-# Libgcrypt is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as
-# published by the Free Software Foundation; either version 2.1 of
-# the License, or (at your option) any later version.
-#
-# Libgcrypt is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
-mpih-add1.S
-mpih-sub1.S
-mpih-mul1.S
-mpih-mul2.S
-mpih-mul3.S
-mpih-lshift.S
-mpih-rshift.S
-syntax.h
-$names$ iQCVAwUAP+LmYzEAnp832S/7AQI/cQP+Mcg9rF/c/bJTY48PE1/ARt7vCMtpIlv9alZSSSrU3WHzCtv9nVczFmwHU3DdKFawigY2DljQcK92dZ5ZlOfpFNMz4PKlVMWaKDk+jKlqm2dxvlHuqEvXPpjFAE2gHrhq5qLXS5ZHeMLJIEK84GYC6fjfLUMdZU3altXTUBvoXhA==Yax+
index a086614..af10d79 100644 (file)
@@ -1,4 +1,3 @@
-Manifest
 mpih-add1.S
 mpih-sub1.S
 mpih-mul1.S
diff --git a/mpi/sparc32/Manifest b/mpi/sparc32/Manifest
deleted file mode 100644 (file)
index d279229..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-# Manifest - checksums 
-# Copyright 2003 Free Software Foundation, Inc.
-#
-# This file is part of Libgcrypt.
-#
-# Libgcrypt is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as
-# published by the Free Software Foundation; either version 2.1 of
-# the License, or (at your option) any later version.
-#
-# Libgcrypt is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
-mpih-lshift.S
-mpih-rshift.S
-mpih-add1.S
-udiv.S
-$names$ iQCVAwUAP+LmaDEAnp832S/7AQISHgP/Z5orU+CPKBeRFCogSQDm4p7J2VpDovU6mtfMTdjhqWuZG0U6y8WqH0aj3USfziOhtc8YjQHQ+97g3+EnIWZgLjKacWC6pScY/QbATEpF1D0Wrcea5rk3qR1t7isdBVVOrxedZ5vuj5Op2zx/0OlPI+wt6fTtW88BdG/a6w/ZU/8==Py6h
index a20f18e..51329db 100644 (file)
@@ -1,4 +1,3 @@
-Manifest
 mpih-lshift.S
 mpih-rshift.S
 mpih-add1.S
diff --git a/mpi/sparc32v8/Manifest b/mpi/sparc32v8/Manifest
deleted file mode 100644 (file)
index dc1ce6a..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-# Manifest - checksums 
-# Copyright 2003 Free Software Foundation, Inc.
-#
-# This file is part of Libgcrypt.
-#
-# Libgcrypt is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as
-# published by the Free Software Foundation; either version 2.1 of
-# the License, or (at your option) any later version.
-#
-# Libgcrypt is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
-mpih-mul1.S
-mpih-mul2.S
-mpih-mul3.S
-$names$ iQCVAwUAP+LmbjEAnp832S/7AQKQ2gQAotpCpY9rOJUCdZHbDLXXB9i1UUMraRKbVWimtKq493Y2d2wcqXCK2WaGs1AePK3K6Qk6msxZ0PL5Ho7KgHMkzsZ+wG0EUziiuX0yZRTWNm0r3TYerP6SdWH5GOVdSXn7ckkppk2sVOokfQTy+Tmrnah3+dlYJoujan+fmXWN6Us==DolM
index 6e9a530..2fcb0d1 100644 (file)
@@ -1,4 +1,3 @@
-Manifest
 mpih-mul1.S
 mpih-mul2.S
 mpih-mul3.S
diff --git a/mpi/supersparc/Manifest b/mpi/supersparc/Manifest
deleted file mode 100644 (file)
index 869b97b..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-# Manifest - checksums 
-# Copyright 2003 Free Software Foundation, Inc.
-#
-# This file is part of Libgcrypt.
-#
-# Libgcrypt is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as
-# published by the Free Software Foundation; either version 2.1 of
-# the License, or (at your option) any later version.
-#
-# Libgcrypt is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
-udiv.S
-$names$ iQCVAwUAP+LmdjEAnp832S/7AQIrUgQA3YmurZhK7r20DqRvg0gwNe9jMDcFfUY4ZPhW5HkGzMbmrxXtj5Dx50RIPteum72bXE+IhcngljQb/cskiN5Hi9oc2a2CPhyTqVFEeGyF+kJ170GI1pVfFOfzbVG0F4nEwm5lGHgv/nvFsvrjmmAXVW1v/yk5N35wbiLviOFrLOQ==byFc
index c9d587a..92aba20 100644 (file)
@@ -34,7 +34,7 @@ librandom_la_SOURCES = \
 random.c random.h \
 rand-internal.h \
 random-csprng.c \
-random-fips.c \
+random-drbg.c \
 random-system.c \
 rndhw.c
 
index 215441f..3307190 100644 (file)
@@ -1,9 +1,8 @@
-# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
-# Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 # Process this file with automake to produce Makefile.in
 
 VPATH = @srcdir@
-am__make_dryrun = \
-  { \
-    am__dry=no; \
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
     case $$MAKEFLAGS in \
       *\\[\ \  ]*) \
-        echo 'am--echo: ; @echo "AM"  OK' | $(MAKE) -f - 2>/dev/null \
-          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
-      *) \
-        for am__flg in $$MAKEFLAGS; do \
-          case $$am__flg in \
-            *=*|--*) ;; \
-            *n*) am__dry=yes; break;; \
-          esac; \
-        done;; \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs  ]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
     esac; \
-    test $$am__dry = yes; \
-  }
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -73,16 +100,16 @@ build_triplet = @build@
 host_triplet = @host@
 @USE_RANDOM_DAEMON_TRUE@am__append_1 = random-daemon.c
 subdir = random
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+       $(top_srcdir)/build-aux/depcomp
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/gpg-error.m4 \
-       $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/lock.m4 \
-       $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
-       $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+       $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+       $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+       $(top_srcdir)/m4/lt~obsolete.m4 \
        $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \
        $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
-       $(top_srcdir)/m4/threadlib.m4 $(top_srcdir)/acinclude.m4 \
-       $(top_srcdir)/configure.ac
+       $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -92,15 +119,28 @@ CONFIG_CLEAN_VPATH_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 am__DEPENDENCIES_1 =
 am__librandom_la_SOURCES_DIST = random.c random.h rand-internal.h \
-       random-csprng.c random-fips.c random-system.c rndhw.c \
+       random-csprng.c random-drbg.c random-system.c rndhw.c \
        random-daemon.c
 @USE_RANDOM_DAEMON_TRUE@am__objects_1 = random-daemon.lo
-am_librandom_la_OBJECTS = random.lo random-csprng.lo random-fips.lo \
+am_librandom_la_OBJECTS = random.lo random-csprng.lo random-drbg.lo \
        random-system.lo rndhw.lo $(am__objects_1)
 librandom_la_OBJECTS = $(am_librandom_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
 am__v_lt_0 = --silent
+am__v_lt_1 = 
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
 depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
 am__depfiles_maybe = depfiles
@@ -113,20 +153,16 @@ LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(AM_CFLAGS) $(CFLAGS)
 AM_V_CC = $(am__v_CC_@AM_V@)
 am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
-am__v_CC_0 = @echo "  CC    " $@;
-AM_V_at = $(am__v_at_@AM_V@)
-am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
-am__v_at_0 = @
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
 CCLD = $(CC)
 LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
        $(AM_LDFLAGS) $(LDFLAGS) -o $@
 AM_V_CCLD = $(am__v_CCLD_@AM_V@)
 am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
-am__v_CCLD_0 = @echo "  CCLD  " $@;
-AM_V_GEN = $(am__v_GEN_@AM_V@)
-am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
-am__v_GEN_0 = @echo "  GEN   " $@;
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
 SOURCES = $(librandom_la_SOURCES) $(EXTRA_librandom_la_SOURCES)
 DIST_SOURCES = $(am__librandom_la_SOURCES_DIST) \
        $(EXTRA_librandom_la_SOURCES)
@@ -135,6 +171,23 @@ am__can_run_installinfo = \
     n|no|NO) false;; \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -182,6 +235,8 @@ GCRYPT_RANDOM = @GCRYPT_RANDOM@
 GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
 GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
 GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GPG_ERROR_MT_CFLAGS = @GPG_ERROR_MT_CFLAGS@
+GPG_ERROR_MT_LIBS = @GPG_ERROR_MT_LIBS@
 GREP = @GREP@
 INSERT_SYS_SELECT_H = @INSERT_SYS_SELECT_H@
 INSTALL = @INSTALL@
@@ -202,16 +257,12 @@ LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@
 LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@
 LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@
 LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@
-LIBMULTITHREAD = @LIBMULTITHREAD@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
-LIBTHREAD = @LIBTHREAD@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
-LTLIBMULTITHREAD = @LTLIBMULTITHREAD@
 LTLIBOBJS = @LTLIBOBJS@
-LTLIBTHREAD = @LTLIBTHREAD@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
@@ -242,6 +293,7 @@ SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
+SYSROOT = @SYSROOT@
 SYS_SOCKET_H = @SYS_SOCKET_H@
 VERSION = @VERSION@
 VERSION_NUMBER = @VERSION_NUMBER@
@@ -310,7 +362,7 @@ GCRYPT_MODULES = @GCRYPT_RANDOM@
 librandom_la_DEPENDENCIES = $(GCRYPT_MODULES)
 librandom_la_LIBADD = $(GCRYPT_MODULES)
 librandom_la_SOURCES = random.c random.h rand-internal.h \
-       random-csprng.c random-fips.c random-system.c rndhw.c \
+       random-csprng.c random-drbg.c random-system.c rndhw.c \
        $(am__append_1)
 EXTRA_librandom_la_SOURCES = \
 rndlinux.c \
@@ -356,12 +408,15 @@ $(am__aclocal_m4_deps):
 
 clean-noinstLTLIBRARIES:
        -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
-       @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
-         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
-         test "$$dir" != "$$p" || dir=.; \
-         echo "rm -f \"$${dir}/so_locations\""; \
-         rm -f "$${dir}/so_locations"; \
-       done
+       @list='$(noinst_LTLIBRARIES)'; \
+       locs=`for p in $$list; do echo $$p; done | \
+             sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+             sort -u`; \
+       test -z "$$locs" || { \
+         echo rm -f $${locs}; \
+         rm -f $${locs}; \
+       }
+
 librandom.la: $(librandom_la_OBJECTS) $(librandom_la_DEPENDENCIES) $(EXTRA_librandom_la_DEPENDENCIES) 
        $(AM_V_CCLD)$(LINK)  $(librandom_la_OBJECTS) $(librandom_la_LIBADD) $(LIBS)
 
@@ -373,7 +428,7 @@ distclean-compile:
 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-csprng.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-daemon.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-fips.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-drbg.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-system.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rndegd.Plo@am__quote@
@@ -388,14 +443,14 @@ distclean-compile:
 @am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
 
 .c.obj:
 @am__fastdepCC_TRUE@   $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
 @am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
 
 .c.lo:
 @am__fastdepCC_TRUE@   $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -410,26 +465,15 @@ mostlyclean-libtool:
 clean-libtool:
        -rm -rf .libs _libs
 
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
-       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
-       unique=`for i in $$list; do \
-           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-         done | \
-         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-             END { if (nonempty) { for (i in files) print i; }; }'`; \
-       mkid -fID $$unique
-tags: TAGS
-
-TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-               $(TAGS_FILES) $(LISP)
+ID: $(am__tagged_files)
+       $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
        set x; \
        here=`pwd`; \
-       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-       unique=`for i in $$list; do \
-           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-         done | \
-         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-             END { if (nonempty) { for (i in files) print i; }; }'`; \
+       $(am__define_uniq_tagged_files); \
        shift; \
        if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
@@ -441,15 +485,11 @@ TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
              $$unique; \
          fi; \
        fi
-ctags: CTAGS
-CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-               $(TAGS_FILES) $(LISP)
-       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-       unique=`for i in $$list; do \
-           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-         done | \
-         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-             END { if (nonempty) { for (i in files) print i; }; }'`; \
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+       $(am__define_uniq_tagged_files); \
        test -z "$(CTAGS_ARGS)$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$unique
@@ -458,6 +498,21 @@ GTAGS:
        here=`$(am__cd) $(top_builddir) && pwd` \
          && $(am__cd) $(top_srcdir) \
          && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+       list='$(am__tagged_files)'; \
+       case "$(srcdir)" in \
+         [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+         *) sdir=$(subdir)/$(srcdir) ;; \
+       esac; \
+       for i in $$list; do \
+         if test -f "$$i"; then \
+           echo "$(subdir)/$$i"; \
+         else \
+           echo "$$sdir/$$i"; \
+         fi; \
+       done >> $(top_builddir)/cscope.files
 
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
@@ -599,18 +654,19 @@ uninstall-am:
 
 .MAKE: install-am install-strip
 
-.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
-       clean-libtool clean-noinstLTLIBRARIES ctags distclean \
-       distclean-compile distclean-generic distclean-libtool \
-       distclean-tags distdir dvi dvi-am html html-am info info-am \
-       install install-am install-data install-data-am install-dvi \
-       install-dvi-am install-exec install-exec-am install-html \
-       install-html-am install-info install-info-am install-man \
-       install-pdf install-pdf-am install-ps install-ps-am \
-       install-strip installcheck installcheck-am installdirs \
-       maintainer-clean maintainer-clean-generic mostlyclean \
-       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
-       pdf pdf-am ps ps-am tags uninstall uninstall-am
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+       clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \
+       ctags-am distclean distclean-compile distclean-generic \
+       distclean-libtool distclean-tags distdir dvi dvi-am html \
+       html-am info info-am install install-am install-data \
+       install-data-am install-dvi install-dvi-am install-exec \
+       install-exec-am install-html install-html-am install-info \
+       install-info-am install-man install-pdf install-pdf-am \
+       install-ps install-ps-am install-strip installcheck \
+       installcheck-am installdirs maintainer-clean \
+       maintainer-clean-generic mostlyclean mostlyclean-compile \
+       mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+       tags tags-am uninstall uninstall-am
 
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
index 79b23ac..8c8623e 100644 (file)
@@ -63,31 +63,16 @@ void _gcry_rngcsprng_set_seed_file (const char *name);
 void _gcry_rngcsprng_update_seed_file (void);
 void _gcry_rngcsprng_fast_poll (void);
 
-/*-- random-fips.c --*/
-void _gcry_rngfips_initialize (int full);
-void _gcry_rngfips_close_fds (void);
-void _gcry_rngfips_dump_stats (void);
-int  _gcry_rngfips_is_faked (void);
-gcry_error_t _gcry_rngfips_add_bytes (const void *buf, size_t buflen,
-                                        int quality);
-void _gcry_rngfips_randomize (void *buffer, size_t length,
-                                enum gcry_random_level level);
-void _gcry_rngfips_create_nonce (void *buffer, size_t length);
-
-gcry_error_t _gcry_rngfips_selftest (selftest_report_func_t report);
-
-gcry_err_code_t _gcry_rngfips_init_external_test (void **r_context,
-                                                  unsigned int flags,
-                                                  const void *key,
-                                                  size_t keylen,
-                                                  const void *seed,
-                                                  size_t seedlen,
-                                                  const void *dt,
-                                                  size_t dtlen);
-gcry_err_code_t _gcry_rngfips_run_external_test (void *context,
-                                                 char *buffer, size_t buflen);
-void _gcry_rngfips_deinit_external_test (void *context);
-
+/*-- random-drbg.c --*/
+void _gcry_rngdrbg_inititialize (int full);
+void _gcry_rngdrbg_close_fds (void);
+void _gcry_rngdrbg_dump_stats (void);
+int  _gcry_rngdrbg_is_faked (void);
+gcry_error_t _gcry_rngdrbg_add_bytes (const void *buf, size_t buflen,
+                                      int quality);
+void _gcry_rngdrbg_randomize (void *buffer, size_t length,
+                              enum gcry_random_level level);
+gcry_error_t _gcry_rngdrbg_selftest (selftest_report_func_t report);
 
 /*-- random-system.c --*/
 void _gcry_rngsystem_initialize (int full);
index 87235d8..a0bfc78 100644 (file)
 #include <process.h>
 #endif
 #include "g10lib.h"
-#include "../cipher/rmd.h"
 #include "random.h"
 #include "rand-internal.h"
-#include "cipher.h" /* Required for the rmd160_hash_buffer() prototype.  */
-#include "ath.h"
+#include "cipher.h"         /* _gcry_sha1_hash_buffer  */
+#include "../cipher/sha1.h" /* _gcry_sha1_mixblock     */
 
 #ifndef RAND_MAX   /* For SunOS. */
 #define RAND_MAX 32767
@@ -84,7 +83,7 @@
 
 /* Contstants pertaining to the hash pool. */
 #define BLOCKLEN  64   /* Hash this amount of bytes... */
-#define DIGESTLEN 20   /* ... into a digest of this length (rmd160). */
+#define DIGESTLEN 20   /* ... into a digest of this length (sha-1). */
 /* POOLBLOCKS is the number of digests which make up the pool.  */
 #define POOLBLOCKS 30
 /* POOLSIZE must be a multiple of the digest length to make the AND
@@ -174,14 +173,8 @@ static void (*fast_gather_fnc)(void (*)(const void*, size_t,
    used by regular applications.  */
 static int quick_test;
 
-/* On systems without entropy gathering modules, this flag is set to
-   indicate that the random generator is not working properly.  A
-   warning message is issued as well.  This is useful only for
-   debugging and during development.  */
-static int faked_rng;
-
 /* This is the lock we use to protect all pool operations.  */
-static ath_mutex_t pool_lock;
+GPGRT_LOCK_DEFINE (pool_lock);
 
 /* This is a helper for assert calls.  These calls are used to assert
    that functions are called in a locked state.  It is not meant to be
@@ -242,8 +235,6 @@ static void (*getfnc_fast_random_poll (void))(void (*)(const void*, size_t,
                                               enum random_origins);
 static void read_random_source (enum random_origins origin,
                                 size_t length, int level);
-static int gather_faked (void (*add)(const void*, size_t, enum random_origins),
-                         enum random_origins, size_t length, int level );
 
 
 \f
@@ -259,14 +250,10 @@ static void
 initialize_basics(void)
 {
   static int initialized;
-  int err;
 
   if (!initialized)
     {
       initialized = 1;
-      err = ath_mutex_init (&pool_lock);
-      if (err)
-        log_fatal ("failed to create the pool lock: %s\n", strerror (err) );
 
 #ifdef USE_RANDOM_DAEMON
       _gcry_daemon_initialize_basics ();
@@ -286,9 +273,9 @@ lock_pool (void)
 {
   int err;
 
-  err = ath_mutex_lock (&pool_lock);
+  err = gpgrt_lock_lock (&pool_lock);
   if (err)
-    log_fatal ("failed to acquire the pool lock: %s\n", strerror (err));
+    log_fatal ("failed to acquire the pool lock: %s\n", gpg_strerror (err));
   pool_is_locked = 1;
 }
 
@@ -299,9 +286,9 @@ unlock_pool (void)
   int err;
 
   pool_is_locked = 0;
-  err = ath_mutex_unlock (&pool_lock);
+  err = gpgrt_lock_unlock (&pool_lock);
   if (err)
-    log_fatal ("failed to release the pool lock: %s\n", strerror (err));
+    log_fatal ("failed to release the pool lock: %s\n", gpg_strerror (err));
 }
 
 
@@ -331,11 +318,6 @@ initialize(void)
       /* Setup the slow entropy gathering function.  The code requires
          that this function exists. */
       slow_gather_fnc = getfnc_gather_random ();
-      if (!slow_gather_fnc)
-        {
-          faked_rng = 1;
-          slow_gather_fnc = gather_faked;
-       }
 
       /* Setup the fast entropy gathering function.  */
       fast_gather_fnc = getfnc_fast_random_poll ();
@@ -458,7 +440,7 @@ _gcry_rngcsprng_is_faked (void)
   /* We need to initialize due to the runtime determination of
      available entropy gather modules.  */
   initialize();
-  return (faked_rng || quick_test);
+  return quick_test;
 }
 
 
@@ -611,20 +593,21 @@ mix_pool(unsigned char *pool)
   unsigned char *hashbuf = pool + POOLSIZE;
   unsigned char *p, *pend;
   int i, n;
-  RMD160_CONTEXT md;
+  SHA1_CONTEXT md;
+  unsigned int nburn;
 
 #if DIGESTLEN != 20
-#error must have a digest length of 20 for ripe-md-160
+#error must have a digest length of 20 for SHA-1
 #endif
 
   gcry_assert (pool_is_locked);
-  _gcry_rmd160_init( &md );
+  _gcry_sha1_mixblock_init (&md);
 
   /* Loop over the pool.  */
   pend = pool + POOLSIZE;
   memcpy(hashbuf, pend - DIGESTLEN, DIGESTLEN );
   memcpy(hashbuf+DIGESTLEN, pool, BLOCKLEN-DIGESTLEN);
-  _gcry_rmd160_mixblock( &md, hashbuf);
+  nburn = _gcry_sha1_mixblock (&md, hashbuf);
   memcpy(pool, hashbuf, 20 );
 
   if (failsafe_digest_valid && pool == rndpool)
@@ -653,21 +636,21 @@ mix_pool(unsigned char *pool)
            }
        }
 
-      _gcry_rmd160_mixblock ( &md, hashbuf);
+      _gcry_sha1_mixblock (&md, hashbuf);
       memcpy(p, hashbuf, 20 );
     }
 
-    /* Our hash implementation does only leave small parts (64 bytes)
-       of the pool on the stack, so it is okay not to require secure
-       memory here.  Before we use this pool, it will be copied to the
-       help buffer anyway. */
-    if ( pool == rndpool)
-      {
-        _gcry_rmd160_hash_buffer (failsafe_digest, pool, POOLSIZE);
-        failsafe_digest_valid = 1;
-      }
-
-    _gcry_burn_stack (384); /* for the rmd160_mixblock(), rmd160_hash_buffer */
+  /* Our hash implementation does only leave small parts (64 bytes)
+     of the pool on the stack, so it is okay not to require secure
+     memory here.  Before we use this pool, it will be copied to the
+     help buffer anyway. */
+  if ( pool == rndpool)
+    {
+      _gcry_sha1_hash_buffer (failsafe_digest, pool, POOLSIZE);
+      failsafe_digest_valid = 1;
+    }
+
+  _gcry_burn_stack (nburn);
 }
 
 
@@ -869,7 +852,7 @@ _gcry_rngcsprng_update_seed_file (void)
 
 
   /* Copy the entropy pool to a scratch pool and mix both of them. */
-  for (i=0,dp=(unsigned long*)keypool, sp=(unsigned long*)rndpool;
+  for (i=0,dp=(unsigned long*)(void*)keypool, sp=(unsigned long*)(void*)rndpool;
        i < POOLWORDS; i++, dp++, sp++ )
     {
       *dp = *sp + ADD_VALUE;
@@ -978,8 +961,8 @@ read_pool (byte *buffer, size_t length, int level)
 
       pool_balance = 0;
       needed = length - pool_balance;
-      if (needed < POOLSIZE/2)
-        needed = POOLSIZE/2;
+      if (needed < 16)  /* At least 128 bits.  */
+        needed = 16;
       else if( needed > POOLSIZE )
         BUG ();
       read_random_source (RANDOM_ORIGIN_EXTRAPOLL, needed,
@@ -1025,7 +1008,7 @@ read_pool (byte *buffer, size_t length, int level)
     }
 
   /* Create a new pool. */
-  for(i=0,dp=(unsigned long*)keypool, sp=(unsigned long*)rndpool;
+  for(i=0,dp=(unsigned long*)(void*)keypool, sp=(unsigned long*)(void*)rndpool;
       i < POOLWORDS; i++, dp++, sp++ )
     *dp = *sp + ADD_VALUE;
 
@@ -1239,7 +1222,7 @@ do_fast_random_poll (void)
 # endif /*!RUSAGE_SELF*/
 #endif /*HAVE_GETRUSAGE*/
 
-  /* Time and clock are availabe on all systems - so we better do it
+  /* Time and clock are available on all systems - so we better do it
      just in case one of the above functions didn't work.  */
   {
     time_t x = time(NULL);
@@ -1280,48 +1263,11 @@ _gcry_rngcsprng_fast_poll (void)
 
 
 static void
-read_random_source (enum random_origins orgin, size_t length, int level )
+read_random_source (enum random_origins origin, size_t length, int level)
 {
   if ( !slow_gather_fnc )
     log_fatal ("Slow entropy gathering module not yet initialized\n");
 
-  if ( slow_gather_fnc (add_randomness, orgin, length, level) < 0)
+  if (slow_gather_fnc (add_randomness, origin, length, level) < 0)
     log_fatal ("No way to gather entropy for the RNG\n");
 }
-
-
-static int
-gather_faked (void (*add)(const void*, size_t, enum random_origins),
-              enum random_origins origin, size_t length, int level )
-{
-  static int initialized=0;
-  size_t n;
-  char *buffer, *p;
-
-  (void)add;
-  (void)level;
-
-  if ( !initialized )
-    {
-      log_info(_("WARNING: using insecure random number generator!!\n"));
-      initialized=1;
-#ifdef HAVE_RAND
-      srand( time(NULL)*getpid());
-#else
-      srandom( time(NULL)*getpid());
-#endif
-    }
-
-  p = buffer = xmalloc( length );
-  n = length;
-#ifdef HAVE_RAND
-  while ( n-- )
-    *p++ = ((unsigned)(1 + (int) (256.0*rand()/(RAND_MAX+1.0)))-1);
-#else
-  while ( n-- )
-    *p++ = ((unsigned)(1 + (int) (256.0*random()/(RAND_MAX+1.0)))-1);
-#endif
-  add_randomness ( buffer, length, origin );
-  xfree (buffer);
-  return 0; /* okay */
-}
index 98a0153..8ea4df2 100644 (file)
@@ -28,8 +28,6 @@
    sensitive data.
  */
 
-#error This dameon needs to be fixed due to the ath changes
-
 #include <config.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -42,7 +40,6 @@
 
 #include "g10lib.h"
 #include "random.h"
-#include "ath.h"
 
 \f
 
@@ -51,7 +48,7 @@
 #define RANDOM_DAEMON_SOCKET "/var/run/libgcrypt/S.gcryptrnd"
 
 /* The lock serializing access to the daemon.  */
-static ath_mutex_t daemon_lock = ATH_MUTEX_INITIALIZER;
+GPGRT_LOCK_DEFINE (daemon_lock);
 
 /* The socket connected to the daemon.  */
 static int daemon_socket = -1;
@@ -129,16 +126,7 @@ connect_to_socket (const char *socketname, int *sock)
 void
 _gcry_daemon_initialize_basics (void)
 {
-  static int initialized;
-  int err;
-
-  if (!initialized)
-    {
-      initialized = 1;
-      err = ath_mutex_init (&daemon_lock);
-      if (err)
-        log_fatal ("failed to create the daemon lock: %s\n", strerror (err) );
-    }
+  /* Not anymore required.  */
 }
 
 
@@ -213,7 +201,7 @@ call_daemon (const char *socketname,
   if (!req_nbytes)
     return 0;
 
-  ath_mutex_lock (&daemon_lock);
+  gpgrt_lock_lock (&daemon_lock);
 
   /* Open the socket if that has not been done. */
   if (!initialized)
@@ -225,7 +213,7 @@ call_daemon (const char *socketname,
         {
           daemon_socket = -1;
           log_info ("not using random daemon\n");
-          ath_mutex_unlock (&daemon_lock);
+          gpgrt_lock_unlock (&daemon_lock);
           return err;
         }
     }
@@ -233,7 +221,7 @@ call_daemon (const char *socketname,
   /* Check that we have a valid socket descriptor. */
   if ( daemon_socket == -1 )
     {
-      ath_mutex_unlock (&daemon_lock);
+      gpgrt_lock_unlock (&daemon_lock);
       return gcry_error (GPG_ERR_INTERNAL);
     }
 
@@ -325,7 +313,7 @@ call_daemon (const char *socketname,
     }
   while (req_nbytes);
 
-  ath_mutex_unlock (&daemon_lock);
+  gpgrt_lock_unlock (&daemon_lock);
 
   return err;
 }
diff --git a/random/random-drbg.c b/random/random-drbg.c
new file mode 100644 (file)
index 0000000..f9d11a3
--- /dev/null
@@ -0,0 +1,2623 @@
+/* random-drbg.c - Deterministic Random Bits Generator
+ * Copyright 2014 Stephan Mueller <smueller@chronox.de>
+ *
+ * DRBG: Deterministic Random Bits Generator
+ *       Based on NIST Recommended DRBG from NIST SP800-90A with the following
+ *       properties:
+ *             * CTR DRBG with DF with AES-128, AES-192, AES-256 cores
+ *             * Hash DRBG with DF with SHA-1, SHA-256, SHA-384, SHA-512 cores
+ *             * HMAC DRBG with DF with SHA-1, SHA-256, SHA-384, SHA-512 cores
+ *             * with and without prediction resistance
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, and the entire permission notice in its entirety,
+ *    including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * LGPLv2+, in which case the provisions of the LGPL are
+ * required INSTEAD OF the above restrictions.  (This clause is
+ * necessary due to a potential bad interaction between the LGPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+ * WHICH ARE HEREBY DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ *
+ * gcry_control GCRYCTL_DRBG_REINIT
+ * ================================
+ * This control request re-initializes the DRBG completely, i.e. the entire
+ * state of the DRBG is zeroized (with two exceptions listed in
+ * GCRYCTL_DRBG_SET_ENTROPY).
+ *
+ * The control request takes the following values which influences how
+ * the DRBG is re-initialized:
+ *
+ *  - const char *flagstr
+ *
+ *      This variable specifies the DRBG type to be used for the next
+ *     initialization.  If set to NULL, the previous DRBG type is
+ *     used for the initialization.  If not NULL a space separated
+ *     list of tokens with associated flag values is expected which
+ *     are ORed to form the mandatory flags of the requested DRBG
+ *     strength and cipher type.  Optionally, the prediction
+ *     resistance flag can be ORed into the flags variable.
+ *
+ *      | String token | Flag value             |
+ *      |--------------+------------------------|
+ *      | aes          | DRBG_CTRAES            |
+ *      | serpent      | DRBG_CTRSERPENT        |
+ *      | twofish      | DRBG_CTRTWOFISH        |
+ *      | sha1         | DRBG_HASHSHA1          |
+ *      | sha256       | DRBG_HASHSHA256        |
+ *      | sha512       | DRBG_HASHSHA512        |
+ *      | hmac         | DRBG_HMAC              |
+ *      | sym128       | DRBG_SYM128            |
+ *      | sym192       | DRBG_SYM192            |
+ *      | sym256       | DRBG_SYM256            |
+ *      | pr           | DRBG_PREDICTION_RESIST |
+ *
+ *    For example:
+ *
+ *     - CTR-DRBG with AES-128 without prediction resistance:
+ *         "aes sym128"
+ *     - HMAC-DRBG with SHA-512 with prediction resistance:
+ *         "hmac sha512 pr"
+ *
+ *  - gcry_buffer_t *pers
+ *
+ *      NULL terminated array with personalization strings to be used
+ *     for initialization.
+ *
+ *  - int npers
+ *
+ *     Size of PERS.
+ *
+ *  - void *guard
+ *
+ *      A value of NULL must be passed for this.
+ *
+ * The variable of flags is independent from the pers/perslen variables. If
+ * flags is set to 0 and perslen is set to 0, the current DRBG type is
+ * completely reset without using a personalization string.
+ *
+ * DRBG Usage
+ * ==========
+ * The SP 800-90A DRBG allows the user to specify a personalization string
+ * for initialization as well as an additional information string for each
+ * random number request.  The following code fragments show how a caller
+ * uses the API to use the full functionality of the DRBG.
+ *
+ * Usage without any additional data
+ * ---------------------------------
+ * gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM);
+ *
+ *
+ * Usage with personalization string during initialization
+ * -------------------------------------------------------
+ * drbg_string_t pers;
+ * char personalization[11] = "some-string";
+ *
+ * drbg_string_fill(&pers, personalization, strlen(personalization));
+ * // The reset completely re-initializes the DRBG with the provided
+ * // personalization string without changing the DRBG type
+ * ret = gcry_control(GCRYCTL_DRBG_REINIT, 0, &pers);
+ * gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM);
+ *
+ *
+ * Usage with additional information string during random number request
+ * ---------------------------------------------------------------------
+ * drbg_string_t addtl;
+ * char addtl_string[11] = "some-string";
+ *
+ * drbg_string_fill(&addtl, addtl_string, strlen(addtl_string));
+ * // The following call is a wrapper to gcry_randomize() and returns
+ * // the same error codes.
+ * gcry_randomize_drbg(outbuf, OUTLEN, GCRY_STRONG_RANDOM, &addtl);
+ *
+ *
+ * Usage with personalization and additional information strings
+ * -------------------------------------------------------------
+ * Just mix both scenarios above.
+ *
+ *
+ * Switch the DRBG type to some other type
+ * ---------------------------------------
+ * // Switch to CTR DRBG AES-128 without prediction resistance
+ * ret = gcry_control(GCRYCTL_DRBG_REINIT, DRBG_NOPR_CTRAES128, NULL);
+ * gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM);
+ */
+
+#include <string.h>
+#include <unistd.h>
+#include <stdint.h>
+
+#include <config.h>
+
+#include "g10lib.h"
+#include "random.h"
+#include "rand-internal.h"
+#include "../cipher/bithelp.h"
+
+
+\f
+/******************************************************************
+ * Constants
+ ******************************************************************/
+
+/*
+ * DRBG flags bitmasks
+ *
+ * 31 (B) 28      19         (A)         0
+ *  +-+-+-+--------+---+-----------+-----+
+ *  |~|~|u|~~~~~~~~| 3 |     2     |  1  |
+ *  +-+-+-+--------+- -+-----------+-----+
+ * ctl flg|        |drbg use selection flags
+ *
+ */
+
+/* Internal state control flags (B) */
+#define DRBG_PREDICTION_RESIST ((u32)1<<28)
+
+/* CTR type modifiers (A.1)*/
+#define DRBG_CTRAES            ((u32)1<<0)
+#define DRBG_CTRSERPENT                ((u32)1<<1)
+#define DRBG_CTRTWOFISH                ((u32)1<<2)
+#define DRBG_CTR_MASK          (DRBG_CTRAES | DRBG_CTRSERPENT \
+                                 | DRBG_CTRTWOFISH)
+
+/* HASH type modifiers (A.2)*/
+#define DRBG_HASHSHA1          ((u32)1<<4)
+#define DRBG_HASHSHA224                ((u32)1<<5)
+#define DRBG_HASHSHA256                ((u32)1<<6)
+#define DRBG_HASHSHA384                ((u32)1<<7)
+#define DRBG_HASHSHA512                ((u32)1<<8)
+#define DRBG_HASH_MASK         (DRBG_HASHSHA1 | DRBG_HASHSHA224 \
+                                | DRBG_HASHSHA256 | DRBG_HASHSHA384 \
+                                | DRBG_HASHSHA512)
+/* type modifiers (A.3)*/
+#define DRBG_HMAC              ((u32)1<<12)
+#define DRBG_SYM128            ((u32)1<<13)
+#define DRBG_SYM192            ((u32)1<<14)
+#define DRBG_SYM256            ((u32)1<<15)
+#define DRBG_TYPE_MASK         (DRBG_HMAC | DRBG_SYM128 | DRBG_SYM192 \
+                                | DRBG_SYM256)
+#define DRBG_CIPHER_MASK        (DRBG_CTR_MASK | DRBG_HASH_MASK \
+                                 | DRBG_TYPE_MASK)
+
+#define DRBG_PR_CTRAES128   (DRBG_PREDICTION_RESIST | DRBG_CTRAES | DRBG_SYM128)
+#define DRBG_PR_CTRAES192   (DRBG_PREDICTION_RESIST | DRBG_CTRAES | DRBG_SYM192)
+#define DRBG_PR_CTRAES256   (DRBG_PREDICTION_RESIST | DRBG_CTRAES | DRBG_SYM256)
+#define DRBG_NOPR_CTRAES128 (DRBG_CTRAES | DRBG_SYM128)
+#define DRBG_NOPR_CTRAES192 (DRBG_CTRAES | DRBG_SYM192)
+#define DRBG_NOPR_CTRAES256 (DRBG_CTRAES | DRBG_SYM256)
+#define DRBG_PR_HASHSHA1     (DRBG_PREDICTION_RESIST | DRBG_HASHSHA1)
+#define DRBG_PR_HASHSHA256   (DRBG_PREDICTION_RESIST | DRBG_HASHSHA256)
+#define DRBG_PR_HASHSHA384   (DRBG_PREDICTION_RESIST | DRBG_HASHSHA384)
+#define DRBG_PR_HASHSHA512   (DRBG_PREDICTION_RESIST | DRBG_HASHSHA512)
+#define DRBG_NOPR_HASHSHA1   (DRBG_HASHSHA1)
+#define DRBG_NOPR_HASHSHA256 (DRBG_HASHSHA256)
+#define DRBG_NOPR_HASHSHA384 (DRBG_HASHSHA384)
+#define DRBG_NOPR_HASHSHA512 (DRBG_HASHSHA512)
+#define DRBG_PR_HMACSHA1     (DRBG_PREDICTION_RESIST | DRBG_HASHSHA1 \
+                              | DRBG_HMAC)
+#define DRBG_PR_HMACSHA256   (DRBG_PREDICTION_RESIST | DRBG_HASHSHA256 \
+                              | DRBG_HMAC)
+#define DRBG_PR_HMACSHA384   (DRBG_PREDICTION_RESIST | DRBG_HASHSHA384 \
+                              | DRBG_HMAC)
+#define DRBG_PR_HMACSHA512   (DRBG_PREDICTION_RESIST | DRBG_HASHSHA512 \
+                              | DRBG_HMAC)
+#define DRBG_NOPR_HMACSHA1   (DRBG_HASHSHA1 | DRBG_HMAC)
+#define DRBG_NOPR_HMACSHA256 (DRBG_HASHSHA256 | DRBG_HMAC)
+#define DRBG_NOPR_HMACSHA384 (DRBG_HASHSHA384 | DRBG_HMAC)
+#define DRBG_NOPR_HMACSHA512 (DRBG_HASHSHA512 | DRBG_HMAC)
+
+
+/* The default DRGB type.  */
+#define DRBG_DEFAULT_TYPE    DRBG_NOPR_HMACSHA256
+
+
+\f
+/******************************************************************
+ * Common data structures
+ ******************************************************************/
+
+/*
+ * SP800-90A requires the concatenation of different data. To avoid copying
+ * buffers around or allocate additional memory, the following data structure
+ * is used to point to the original memory with its size. In addition, it
+ * is used to build a linked list. The linked list defines the concatenation
+ * of individual buffers. The order of memory block referenced in that
+ * linked list determines the order of concatenation.
+ */
+struct drbg_string_s
+{
+  const unsigned char *buf;
+  size_t len;
+  struct drbg_string_s *next;
+};
+typedef struct drbg_string_s drbg_string_t;
+
+
+/* DRBG input data structure for DRBG generate with additional
+ * information string.  */
+struct drbg_gen_s
+{
+  unsigned char *outbuf;       /* output buffer for random numbers */
+  unsigned int outlen;         /* size of output buffer */
+  drbg_string_t *addtl;                /* input buffer for
+                                * additional information string */
+};
+typedef struct drbg_gen_s drbg_gen_t;
+
+
+/* Forward declaration of the state object pointer.  */
+struct drbg_state_s;
+typedef struct drbg_state_s *drbg_state_t;
+
+
+struct drbg_core_s
+{
+  u32 flags;                   /* flags for the cipher */
+  ushort statelen;             /* maximum state length */
+  ushort blocklen_bytes;       /* block size of output in bytes */
+  int backend_cipher;          /* libgcrypt backend cipher */
+};
+
+struct drbg_state_ops_s
+{
+  gpg_err_code_t (*update) (drbg_state_t drbg,
+                           drbg_string_t *seed, int reseed);
+  gpg_err_code_t (*generate) (drbg_state_t drbg,
+                             unsigned char *buf, unsigned int buflen,
+                             drbg_string_t *addtl);
+};
+
+struct drbg_test_data_s
+{
+  drbg_string_t *testentropy;  /* TEST PARAMETER: test entropy */
+  int fail_seed_source:1;      /* If set, the seed function will
+                                 * return an error. */
+};
+
+
+/* This state object keeps the state of an DRBG instance.  */
+struct drbg_state_s
+{
+  unsigned char *V;            /* internal state 10.1.1.1 1a) */
+  unsigned char *C;            /* hash: static value 10.1.1.1 1b)
+                                * hmac / ctr: key */
+  size_t reseed_ctr;           /* Number of RNG requests since last reseed --
+                                * 10.1.1.1 1c) */
+  unsigned char *scratchpad;   /* some memory the DRBG can use for its
+                                * operation -- allocated during init */
+  int seeded:1;                        /* DRBG fully seeded? */
+  int pr:1;                    /* Prediction resistance enabled? */
+  /* Taken from libgcrypt ANSI X9.31 DRNG: We need to keep track of the
+   * process which did the initialization so that we can detect a fork.
+   * The volatile modifier is required so that the compiler does not
+   * optimize it away in case the getpid function is badly attributed. */
+  pid_t seed_init_pid;
+  const struct drbg_state_ops_s *d_ops;
+  const struct drbg_core_s *core;
+  struct drbg_test_data_s *test_data;
+};
+
+enum drbg_prefixes
+{
+  DRBG_PREFIX0 = 0x00,
+  DRBG_PREFIX1,
+  DRBG_PREFIX2,
+  DRBG_PREFIX3
+};
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+/***************************************************************
+ * Global variables
+ ***************************************************************/
+
+/* Global state variable holding the current instance of the DRBG.  */
+static drbg_state_t drbg_state;
+
+/* This is the lock variable we use to serialize access to this RNG. */
+GPGRT_LOCK_DEFINE(drbg_lock_var);
+
+
+/***************************************************************
+ * Backend cipher definitions available to DRBG
+ ***************************************************************/
+
+static const struct drbg_core_s drbg_cores[] = {
+  /* Hash DRBGs */
+  {DRBG_HASHSHA1, 55, 20, GCRY_MD_SHA1},
+  {DRBG_HASHSHA256, 55, 32, GCRY_MD_SHA256},
+  {DRBG_HASHSHA384, 111, 48, GCRY_MD_SHA384},
+  {DRBG_HASHSHA512, 111, 64, GCRY_MD_SHA512},
+  /* HMAC DRBGs */
+  {DRBG_HASHSHA1   | DRBG_HMAC, 20, 20, GCRY_MD_SHA1},
+  {DRBG_HASHSHA256 | DRBG_HMAC, 32, 32, GCRY_MD_SHA256},
+  {DRBG_HASHSHA384 | DRBG_HMAC, 48, 48, GCRY_MD_SHA384},
+  {DRBG_HASHSHA512 | DRBG_HMAC, 64, 64, GCRY_MD_SHA512},
+  /* block ciphers */
+  {DRBG_CTRAES | DRBG_SYM128, 32, 16, GCRY_CIPHER_AES128},
+  {DRBG_CTRAES | DRBG_SYM192, 40, 16, GCRY_CIPHER_AES192},
+  {DRBG_CTRAES | DRBG_SYM256, 48, 16, GCRY_CIPHER_AES256}
+};
+
+static gpg_err_code_t drbg_sym (drbg_state_t drbg,
+                                const unsigned char *key,
+                                unsigned char *outval,
+                                const drbg_string_t *buf);
+static gpg_err_code_t drbg_hmac (drbg_state_t drbg,
+                                 const unsigned char *key,
+                                 unsigned char *outval,
+                                 const drbg_string_t *buf);
+
+/******************************************************************
+ ******************************************************************
+ ******************************************************************
+ * Generic DRBG code
+ ******************************************************************
+ ******************************************************************
+ ******************************************************************/
+
+/******************************************************************
+ * Generic helper functions
+ ******************************************************************/
+
+#if 0
+#define dbg(x) do { log_debug x; } while(0)
+#else
+#define dbg(x)
+#endif
+
+/*
+ * Parse a string of flags and store the flag values at R_FLAGS.
+ * Return 0 on success.
+ */
+static gpg_err_code_t
+parse_flag_string (const char *string, u32 *r_flags)
+{
+  struct {
+    const char *name;
+    u32 flag;
+  } table[] = {
+    { "aes",     DRBG_CTRAES            },
+    { "serpent", DRBG_CTRSERPENT        },
+    { "twofish", DRBG_CTRTWOFISH        },
+    { "sha1",    DRBG_HASHSHA1          },
+    { "sha256",  DRBG_HASHSHA256        },
+    { "sha512",  DRBG_HASHSHA512        },
+    { "hmac",    DRBG_HMAC              },
+    { "sym128",  DRBG_SYM128            },
+    { "sym192",  DRBG_SYM192            },
+    { "sym256",  DRBG_SYM256            },
+    { "pr",      DRBG_PREDICTION_RESIST }
+  };
+
+  *r_flags = 0;
+  if (string)
+    {
+      char **tl;
+      const char *s;
+      int i, j;
+
+      tl = _gcry_strtokenize (string, NULL);
+      if (!tl)
+        return gpg_err_code_from_syserror ();
+      for (i=0; (s=tl[i]); i++)
+        {
+          for (j=0; j < DIM (table); j++)
+            if (!strcmp (s, table[j].name))
+              {
+                *r_flags |= table[j].flag;
+                break;
+              }
+          if (!(j < DIM (table)))
+            {
+              xfree (tl);
+              return GPG_ERR_INV_FLAG;
+            }
+        }
+      xfree (tl);
+    }
+
+  return 0;
+}
+
+static inline void
+drbg_string_fill (drbg_string_t *string,
+                       const unsigned char *buf, size_t len)
+{
+  string->buf = buf;
+  string->len = len;
+  string->next = NULL;
+}
+
+static inline ushort
+drbg_statelen (drbg_state_t drbg)
+{
+  if (drbg && drbg->core)
+    return drbg->core->statelen;
+  return 0;
+}
+
+static inline ushort
+drbg_blocklen (drbg_state_t drbg)
+{
+  if (drbg && drbg->core)
+    return drbg->core->blocklen_bytes;
+  return 0;
+}
+
+static inline ushort
+drbg_keylen (drbg_state_t drbg)
+{
+  if (drbg && drbg->core)
+    return (drbg->core->statelen - drbg->core->blocklen_bytes);
+  return 0;
+}
+
+static inline size_t
+drbg_max_request_bytes (void)
+{
+  /* SP800-90A requires the limit 2**19 bits, but we return bytes */
+  return (1 << 16);
+}
+
+static inline size_t
+drbg_max_addtl (void)
+{
+  /* SP800-90A requires 2**35 bytes additional info str / pers str */
+#ifdef __LP64__
+  return (1UL << 35);
+#else
+  /*
+   * SP800-90A allows smaller maximum numbers to be returned -- we
+   * return SIZE_MAX - 1 to allow the verification of the enforcement
+   * of this value in drbg_healthcheck_sanity.
+   */
+  return (SIZE_MAX - 1);
+#endif
+}
+
+static inline size_t
+drbg_max_requests (void)
+{
+  /* SP800-90A requires 2**48 maximum requests before reseeding */
+#ifdef __LP64__
+  return (1UL << 48);
+#else
+  return SIZE_MAX;
+#endif
+}
+
+/*
+ * Return strength of DRBG according to SP800-90A section 8.4
+ *
+ * flags: DRBG flags reference
+ *
+ * Return: normalized strength value or 32 as a default to counter
+ *        programming errors
+ */
+static inline unsigned short
+drbg_sec_strength (u32 flags)
+{
+  if ((flags & DRBG_HASHSHA1) || (flags & DRBG_SYM128))
+    return 16;
+  else if (flags & DRBG_SYM192)
+    return 24;
+  else if ((flags & DRBG_SYM256) || (flags & DRBG_HASHSHA256) ||
+          (flags & DRBG_HASHSHA384) || (flags & DRBG_HASHSHA512))
+    return 32;
+  else
+    return 32;
+}
+
+/*
+ * Convert an integer into a byte representation of this integer.
+ * The byte representation is big-endian
+ *
+ * @val value to be converted
+ * @buf buffer holding the converted integer -- caller must ensure that
+ *      buffer size is at least 32 bit
+ */
+static inline void
+drbg_cpu_to_be32 (u32 val, unsigned char *buf)
+{
+  /* FIXME: This may raise a bus error.  */
+  struct s
+  {
+    u32 conv;
+  };
+  struct s *conversion = (struct s *) buf;
+
+  conversion->conv = be_bswap32 (val);
+}
+
+static void
+drbg_add_buf (unsigned char *dst, size_t dstlen,
+              unsigned char *add, size_t addlen)
+{
+  /* implied: dstlen > addlen */
+  unsigned char *dstptr, *addptr;
+  unsigned int remainder = 0;
+  size_t len = addlen;
+
+  dstptr = dst + (dstlen - 1);
+  addptr = add + (addlen - 1);
+  while (len)
+    {
+      remainder += *dstptr + *addptr;
+      *dstptr = remainder & 0xff;
+      remainder >>= 8;
+      len--;
+      dstptr--;
+      addptr--;
+    }
+  len = dstlen - addlen;
+  while (len && remainder > 0)
+    {
+      remainder = *dstptr + 1;
+      *dstptr = remainder & 0xff;
+      remainder >>= 8;
+      len--;
+      dstptr--;
+    }
+}
+
+/* Helper variables for read_cb().
+ *
+ *   The _gcry_rnd*_gather_random interface does not allow to provide a
+ *   data pointer.  Thus we need to use a global variable for
+ *   communication.  However, the then required locking is anyway a good
+ *   idea because it does not make sense to have several readers of (say
+ *   /dev/random).  It is easier to serve them one after the other.
+ */
+static unsigned char *read_cb_buffer;  /* The buffer.  */
+static size_t read_cb_size;            /* Size of the buffer.  */
+static size_t read_cb_len;             /* Used length.  */
+
+/* Callback for generating seed from kernel device. */
+static void
+drbg_read_cb (const void *buffer, size_t length,
+              enum random_origins origin)
+{
+  const unsigned char *p = buffer;
+
+  (void) origin;
+  gcry_assert (read_cb_buffer);
+
+  /* Note that we need to protect against gatherers returning more
+   * than the requested bytes (e.g. rndw32).  */
+  while (length-- && read_cb_len < read_cb_size)
+    read_cb_buffer[read_cb_len++] = *p++;
+}
+
+static inline int
+drbg_get_entropy (drbg_state_t drbg, unsigned char *buffer,
+                      size_t len)
+{
+  int rc = 0;
+
+  /* Perform testing as defined in 11.3.2 */
+  if (drbg->test_data && drbg->test_data->fail_seed_source)
+    return -1;
+
+  read_cb_buffer = buffer;
+  read_cb_size = len;
+  read_cb_len = 0;
+#if USE_RNDLINUX
+  rc = _gcry_rndlinux_gather_random (drbg_read_cb, 0, len,
+                                    GCRY_VERY_STRONG_RANDOM);
+#elif USE_RNDUNIX
+  rc = _gcry_rndunix_gather_random (drbg_read_cb, 0, len,
+                                   GCRY_VERY_STRONG_RANDOM);
+#elif USE_RNDW32
+  do
+    {
+      rc = _gcry_rndw32_gather_random (drbg_read_cb, 0, len,
+                                      GCRY_VERY_STRONG_RANDOM);
+    }
+  while (rc >= 0 && read_cb_len < read_cb_size);
+#else
+  rc = -1;
+#endif
+  return rc;
+}
+
+/******************************************************************
+ * CTR DRBG callback functions
+ ******************************************************************/
+
+/* BCC function for CTR DRBG as defined in 10.4.3 */
+static gpg_err_code_t
+drbg_ctr_bcc (drbg_state_t drbg,
+              unsigned char *out, const unsigned char *key,
+              drbg_string_t *in)
+{
+  gpg_err_code_t ret = GPG_ERR_GENERAL;
+  drbg_string_t *curr = in;
+  size_t inpos = curr->len;
+  const unsigned char *pos = curr->buf;
+  drbg_string_t data;
+
+  drbg_string_fill (&data, out, drbg_blocklen (drbg));
+
+  /* 10.4.3 step 1 */
+  memset (out, 0, drbg_blocklen (drbg));
+
+  /* 10.4.3 step 2 / 4 */
+  while (inpos)
+    {
+      short cnt = 0;
+      /* 10.4.3 step 4.1 */
+      for (cnt = 0; cnt < drbg_blocklen (drbg); cnt++)
+       {
+         out[cnt] ^= *pos;
+         pos++;
+         inpos--;
+         /* the following branch implements the linked list
+          * iteration. If we are at the end of the current data
+          * set, we have to start using the next data set if
+          * available -- the inpos value always points to the
+          * current byte and will be zero if we have processed
+          * the last byte of the last linked list member */
+         if (0 == inpos)
+           {
+             curr = curr->next;
+             if (NULL != curr)
+               {
+                 pos = curr->buf;
+                 inpos = curr->len;
+               }
+             else
+               {
+                 inpos = 0;
+                 break;
+               }
+           }
+       }
+      /* 10.4.3 step 4.2 */
+      ret = drbg_sym (drbg, key, out, &data);
+      if (ret)
+       return ret;
+      /* 10.4.3 step 2 */
+    }
+  return 0;
+}
+
+
+/*
+ * scratchpad usage: drbg_ctr_update is interlinked with drbg_ctr_df
+ * (and drbg_ctr_bcc, but this function does not need any temporary buffers),
+ * the scratchpad is used as follows:
+ * drbg_ctr_update:
+ *     temp
+ *             start: drbg->scratchpad
+ *             length: drbg_statelen(drbg) + drbg_blocklen(drbg)
+ *                     note: the cipher writing into this variable works
+ *                     blocklen-wise. Now, when the statelen is not a multiple
+ *                     of blocklen, the generateion loop below "spills over"
+ *                     by at most blocklen. Thus, we need to give sufficient
+ *                     memory.
+ *     df_data
+ *             start: drbg->scratchpad +
+ *                             drbg_statelen(drbg) +
+ *                             drbg_blocklen(drbg)
+ *             length: drbg_statelen(drbg)
+ *
+ * drbg_ctr_df:
+ *     pad
+ *             start: df_data + drbg_statelen(drbg)
+ *             length: drbg_blocklen(drbg)
+ *     iv
+ *             start: pad + drbg_blocklen(drbg)
+ *             length: drbg_blocklen(drbg)
+ *     temp
+ *             start: iv + drbg_blocklen(drbg)
+ *             length: drbg_satelen(drbg) + drbg_blocklen(drbg)
+ *                     note: temp is the buffer that the BCC function operates
+ *                     on. BCC operates blockwise. drbg_statelen(drbg)
+ *                     is sufficient when the DRBG state length is a multiple
+ *                     of the block size. For AES192 (and maybe other ciphers)
+ *                     this is not correct and the length for temp is
+ *                     insufficient (yes, that also means for such ciphers,
+ *                     the final output of all BCC rounds are truncated).
+ *                     Therefore, add drbg_blocklen(drbg) to cover all
+ *                     possibilities.
+ */
+
+/* Derivation Function for CTR DRBG as defined in 10.4.2 */
+static gpg_err_code_t
+drbg_ctr_df (drbg_state_t drbg, unsigned char *df_data,
+             size_t bytes_to_return, drbg_string_t *addtl)
+{
+  gpg_err_code_t ret = GPG_ERR_GENERAL;
+  unsigned char L_N[8];
+  /* S3 is input */
+  drbg_string_t S1, S2, S4, cipherin;
+  drbg_string_t *tempstr = addtl;
+  unsigned char *pad = df_data + drbg_statelen (drbg);
+  unsigned char *iv = pad + drbg_blocklen (drbg);
+  unsigned char *temp = iv + drbg_blocklen (drbg);
+  size_t padlen = 0;
+  unsigned int templen = 0;
+  /* 10.4.2 step 7 */
+  unsigned int i = 0;
+  /* 10.4.2 step 8 */
+  const unsigned char *K = (unsigned char *)
+    "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+    "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f";
+  unsigned char *X;
+  size_t generated_len = 0;
+  size_t inputlen = 0;
+
+  memset (pad, 0, drbg_blocklen (drbg));
+  memset (iv, 0, drbg_blocklen (drbg));
+  memset (temp, 0, drbg_statelen (drbg));
+
+  /* 10.4.2 step 1 is implicit as we work byte-wise */
+
+  /* 10.4.2 step 2 */
+  if ((512 / 8) < bytes_to_return)
+    return GPG_ERR_INV_ARG;
+
+  /* 10.4.2 step 2 -- calculate the entire length of all input data */
+  for (; NULL != tempstr; tempstr = tempstr->next)
+    inputlen += tempstr->len;
+  drbg_cpu_to_be32 (inputlen, &L_N[0]);
+
+  /* 10.4.2 step 3 */
+  drbg_cpu_to_be32 (bytes_to_return, &L_N[4]);
+
+  /* 10.4.2 step 5: length is size of L_N, input_string, one byte, padding */
+  padlen = (inputlen + sizeof (L_N) + 1) % (drbg_blocklen (drbg));
+  /* wrap the padlen appropriately */
+  if (padlen)
+    padlen = drbg_blocklen (drbg) - padlen;
+  /* pad / padlen contains the 0x80 byte and the following zero bytes, so
+   * add one for byte for 0x80 */
+  padlen++;
+  pad[0] = 0x80;
+
+  /* 10.4.2 step 4 -- first fill the linked list and then order it */
+  drbg_string_fill (&S1, iv, drbg_blocklen (drbg));
+  drbg_string_fill (&S2, L_N, sizeof (L_N));
+  drbg_string_fill (&S4, pad, padlen);
+  S1.next = &S2;
+  S2.next = addtl;
+
+  /* Splice in addtl between S2 and S4 -- we place S4 at the end of the
+   * input data chain. As this code is only triggered when addtl is not
+   * NULL, no NULL checks are necessary.*/
+  tempstr = addtl;
+  while (tempstr->next)
+    tempstr = tempstr->next;
+  tempstr->next = &S4;
+
+  /* 10.4.2 step 9 */
+  while (templen < (drbg_keylen (drbg) + (drbg_blocklen (drbg))))
+    {
+      /* 10.4.2 step 9.1 - the padding is implicit as the buffer
+       * holds zeros after allocation -- even the increment of i
+       * is irrelevant as the increment remains within length of i */
+      drbg_cpu_to_be32 (i, iv);
+      /* 10.4.2 step 9.2 -- BCC and concatenation with temp */
+      ret = drbg_ctr_bcc (drbg, temp + templen, K, &S1);
+      if (ret)
+       goto out;
+      /* 10.4.2 step 9.3 */
+      i++;
+      templen += drbg_blocklen (drbg);
+    }
+
+  /* 10.4.2 step 11 */
+  /* implicit key len with seedlen - blocklen according to table 3 */
+  X = temp + (drbg_keylen (drbg));
+  drbg_string_fill (&cipherin, X, drbg_blocklen (drbg));
+
+  /* 10.4.2 step 12: overwriting of outval */
+
+  /* 10.4.2 step 13 */
+  while (generated_len < bytes_to_return)
+    {
+      short blocklen = 0;
+      /* 10.4.2 step 13.1 */
+      /* the truncation of the key length is implicit as the key
+       * is only drbg_blocklen in size -- check for the implementation
+       * of the cipher function callback */
+      ret = drbg_sym (drbg, temp, X, &cipherin);
+      if (ret)
+       goto out;
+      blocklen = (drbg_blocklen (drbg) <
+                 (bytes_to_return - generated_len)) ?
+       drbg_blocklen (drbg) : (bytes_to_return - generated_len);
+      /* 10.4.2 step 13.2 and 14 */
+      memcpy (df_data + generated_len, X, blocklen);
+      generated_len += blocklen;
+    }
+
+  ret = 0;
+
+ out:
+  memset (iv, 0, drbg_blocklen (drbg));
+  memset (temp, 0, drbg_statelen (drbg));
+  memset (pad, 0, drbg_blocklen (drbg));
+  return ret;
+}
+
+/*
+ * Update function of CTR DRBG as defined in 10.2.1.2
+ *
+ * The reseed variable has an enhanced meaning compared to the update
+ * functions of the other DRBGs as follows:
+ * 0 => initial seed from initialization
+ * 1 => reseed via drbg_seed
+ * 2 => first invocation from drbg_ctr_update when addtl is present. In
+ *      this case, the df_data scratchpad is not deleted so that it is
+ *      available for another calls to prevent calling the DF function
+ *      again.
+ * 3 => second invocation from drbg_ctr_update. When the update function
+ *      was called with addtl, the df_data memory already contains the
+ *      DFed addtl information and we do not need to call DF again.
+ */
+static gpg_err_code_t
+drbg_ctr_update (drbg_state_t drbg, drbg_string_t *addtl, int reseed)
+{
+  gpg_err_code_t ret = GPG_ERR_GENERAL;
+  /* 10.2.1.2 step 1 */
+  unsigned char *temp = drbg->scratchpad;
+  unsigned char *df_data = drbg->scratchpad +
+    drbg_statelen (drbg) + drbg_blocklen (drbg);
+  unsigned char *temp_p, *df_data_p;   /* pointer to iterate over buffers */
+  unsigned int len = 0;
+  drbg_string_t cipherin;
+  unsigned char prefix = DRBG_PREFIX1;
+
+  memset (temp, 0, drbg_statelen (drbg) + drbg_blocklen (drbg));
+  if (3 > reseed)
+    memset (df_data, 0, drbg_statelen (drbg));
+
+  /* 10.2.1.3.2 step 2 and 10.2.1.4.2 step 2 */
+  /* TODO use reseed variable to avoid re-doing DF operation */
+  (void) reseed;
+  if (addtl && 0 < addtl->len)
+    {
+      ret =
+       drbg_ctr_df (drbg, df_data, drbg_statelen (drbg), addtl);
+      if (ret)
+       goto out;
+    }
+
+  drbg_string_fill (&cipherin, drbg->V, drbg_blocklen (drbg));
+  /* 10.2.1.3.2 step 2 and 3 -- are already covered as we memset(0)
+   * all memory during initialization */
+  while (len < (drbg_statelen (drbg)))
+    {
+      /* 10.2.1.2 step 2.1 */
+      drbg_add_buf (drbg->V, drbg_blocklen (drbg), &prefix, 1);
+      /* 10.2.1.2 step 2.2 */
+      /* using target of temp + len: 10.2.1.2 step 2.3 and 3 */
+      ret = drbg_sym (drbg, drbg->C, temp + len, &cipherin);
+      if (ret)
+       goto out;
+      /* 10.2.1.2 step 2.3 and 3 */
+      len += drbg_blocklen (drbg);
+    }
+
+  /* 10.2.1.2 step 4 */
+  temp_p = temp;
+  df_data_p = df_data;
+  for (len = 0; len < drbg_statelen (drbg); len++)
+    {
+      *temp_p ^= *df_data_p;
+      df_data_p++;
+      temp_p++;
+    }
+
+  /* 10.2.1.2 step 5 */
+  memcpy (drbg->C, temp, drbg_keylen (drbg));
+  /* 10.2.1.2 step 6 */
+  memcpy (drbg->V, temp + drbg_keylen (drbg), drbg_blocklen (drbg));
+  ret = 0;
+
+ out:
+  memset (temp, 0, drbg_statelen (drbg) + drbg_blocklen (drbg));
+  if (2 != reseed)
+    memset (df_data, 0, drbg_statelen (drbg));
+  return ret;
+}
+
+/*
+ * scratchpad use: drbg_ctr_update is called independently from
+ * drbg_ctr_extract_bytes. Therefore, the scratchpad is reused
+ */
+/* Generate function of CTR DRBG as defined in 10.2.1.5.2 */
+static gpg_err_code_t
+drbg_ctr_generate (drbg_state_t drbg,
+                   unsigned char *buf, unsigned int buflen,
+                   drbg_string_t *addtl)
+{
+  gpg_err_code_t ret = 0;
+  unsigned int len = 0;
+  drbg_string_t data;
+  unsigned char prefix = DRBG_PREFIX1;
+
+  memset (drbg->scratchpad, 0, drbg_blocklen (drbg));
+
+  /* 10.2.1.5.2 step 2 */
+  if (addtl && 0 < addtl->len)
+    {
+      addtl->next = NULL;
+      ret = drbg_ctr_update (drbg, addtl, 2);
+      if (ret)
+       return ret;
+    }
+
+  /* 10.2.1.5.2 step 4.1 */
+  drbg_add_buf (drbg->V, drbg_blocklen (drbg), &prefix, 1);
+  drbg_string_fill (&data, drbg->V, drbg_blocklen (drbg));
+  while (len < buflen)
+    {
+      unsigned int outlen = 0;
+      /* 10.2.1.5.2 step 4.2 */
+      ret = drbg_sym (drbg, drbg->C, drbg->scratchpad, &data);
+      if (ret)
+       goto out;
+      outlen = (drbg_blocklen (drbg) < (buflen - len)) ?
+       drbg_blocklen (drbg) : (buflen - len);
+      /* 10.2.1.5.2 step 4.3 */
+      memcpy (buf + len, drbg->scratchpad, outlen);
+      len += outlen;
+      /* 10.2.1.5.2 step 6 */
+      if (len < buflen)
+       drbg_add_buf (drbg->V, drbg_blocklen (drbg), &prefix, 1);
+    }
+
+  /* 10.2.1.5.2 step 6 */
+  if (addtl)
+    addtl->next = NULL;
+  ret = drbg_ctr_update (drbg, addtl, 3);
+
+ out:
+  memset (drbg->scratchpad, 0, drbg_blocklen (drbg));
+  return ret;
+}
+
+static struct drbg_state_ops_s drbg_ctr_ops = {
+  drbg_ctr_update,
+  drbg_ctr_generate
+};
+
+/******************************************************************
+ * HMAC DRBG callback functions
+ ******************************************************************/
+
+static gpg_err_code_t
+drbg_hmac_update (drbg_state_t drbg, drbg_string_t *seed, int reseed)
+{
+  gpg_err_code_t ret = GPG_ERR_GENERAL;
+  int i = 0;
+  drbg_string_t seed1, seed2, cipherin;
+
+  if (!reseed)
+    {
+      /* 10.1.2.3 step 2 already implicitly covered with
+       * the initial memset(0) of drbg->C */
+      memset (drbg->V, 1, drbg_statelen (drbg));
+    }
+
+  /* build linked list which implements the concatenation and fill
+   * first part*/
+  drbg_string_fill (&seed1, drbg->V, drbg_statelen (drbg));
+  /* buffer will be filled in for loop below with one byte */
+  drbg_string_fill (&seed2, NULL, 1);
+  seed1.next = &seed2;
+  /* seed may be NULL */
+  seed2.next = seed;
+
+  drbg_string_fill (&cipherin, drbg->V, drbg_statelen (drbg));
+  /* we execute two rounds of V/K massaging */
+  for (i = 2; 0 < i; i--)
+    {
+      /* first round uses 0x0, second 0x1 */
+      unsigned char prefix = DRBG_PREFIX0;
+      if (1 == i)
+       prefix = DRBG_PREFIX1;
+      /* 10.1.2.2 step 1 and 4 -- concatenation and HMAC for key */
+      seed2.buf = &prefix;
+      ret = drbg_hmac (drbg, drbg->C, drbg->C, &seed1);
+      if (ret)
+       return ret;
+
+      /* 10.1.2.2 step 2 and 5 -- HMAC for V */
+      ret = drbg_hmac (drbg, drbg->C, drbg->V, &cipherin);
+      if (ret)
+       return ret;
+
+      /* 10.1.2.2 step 3 */
+      if (!seed || 0 == seed->len)
+       return ret;
+    }
+  return 0;
+}
+
+/* generate function of HMAC DRBG as defined in 10.1.2.5 */
+static gpg_err_code_t
+drbg_hmac_generate (drbg_state_t drbg, unsigned char *buf, unsigned int buflen,
+                    drbg_string_t *addtl)
+{
+  gpg_err_code_t ret = 0;
+  unsigned int len = 0;
+  drbg_string_t data;
+
+  /* 10.1.2.5 step 2 */
+  if (addtl && 0 < addtl->len)
+    {
+      addtl->next = NULL;
+      ret = drbg_hmac_update (drbg, addtl, 1);
+      if (ret)
+       return ret;
+    }
+
+  drbg_string_fill (&data, drbg->V, drbg_statelen (drbg));
+  while (len < buflen)
+    {
+      unsigned int outlen = 0;
+      /* 10.1.2.5 step 4.1 */
+      ret = drbg_hmac (drbg, drbg->C, drbg->V, &data);
+      if (ret)
+       return ret;
+      outlen = (drbg_blocklen (drbg) < (buflen - len)) ?
+       drbg_blocklen (drbg) : (buflen - len);
+
+      /* 10.1.2.5 step 4.2 */
+      memcpy (buf + len, drbg->V, outlen);
+      len += outlen;
+    }
+
+  /* 10.1.2.5 step 6 */
+  if (addtl)
+    addtl->next = NULL;
+  ret = drbg_hmac_update (drbg, addtl, 1);
+
+  return ret;
+}
+
+static struct drbg_state_ops_s drbg_hmac_ops = {
+  drbg_hmac_update,
+  drbg_hmac_generate
+};
+
+/******************************************************************
+ * Hash DRBG callback functions
+ ******************************************************************/
+
+/*
+ * scratchpad usage: as drbg_hash_update and drbg_hash_df are used
+ * interlinked, the scratchpad is used as follows:
+ * drbg_hash_update
+ *     start: drbg->scratchpad
+ *     length: drbg_statelen(drbg)
+ * drbg_hash_df:
+ *     start: drbg->scratchpad + drbg_statelen(drbg)
+ *     length: drbg_blocklen(drbg)
+ */
+/* Derivation Function for Hash DRBG as defined in 10.4.1 */
+static gpg_err_code_t
+drbg_hash_df (drbg_state_t drbg,
+              unsigned char *outval, size_t outlen,
+              drbg_string_t *entropy)
+{
+  gpg_err_code_t ret = 0;
+  size_t len = 0;
+  unsigned char input[5];
+  unsigned char *tmp = drbg->scratchpad + drbg_statelen (drbg);
+  drbg_string_t data1;
+
+  memset (tmp, 0, drbg_blocklen (drbg));
+
+  /* 10.4.1 step 3 */
+  input[0] = 1;
+  drbg_cpu_to_be32 ((outlen * 8), &input[1]);
+
+  /* 10.4.1 step 4.1 -- concatenation of data for input into hash */
+  drbg_string_fill (&data1, input, 5);
+  data1.next = entropy;
+
+  /* 10.4.1 step 4 */
+  while (len < outlen)
+    {
+      short blocklen = 0;
+      /* 10.4.1 step 4.1 */
+      ret = drbg_hmac (drbg, NULL, tmp, &data1);
+      if (ret)
+       goto out;
+      /* 10.4.1 step 4.2 */
+      input[0]++;
+      blocklen = (drbg_blocklen (drbg) < (outlen - len)) ?
+       drbg_blocklen (drbg) : (outlen - len);
+      memcpy (outval + len, tmp, blocklen);
+      len += blocklen;
+    }
+
+ out:
+  memset (tmp, 0, drbg_blocklen (drbg));
+  return ret;
+}
+
+/* update function for Hash DRBG as defined in 10.1.1.2 / 10.1.1.3 */
+static gpg_err_code_t
+drbg_hash_update (drbg_state_t drbg, drbg_string_t *seed, int reseed)
+{
+  gpg_err_code_t ret = 0;
+  drbg_string_t data1, data2;
+  unsigned char *V = drbg->scratchpad;
+  unsigned char prefix = DRBG_PREFIX1;
+
+  memset (drbg->scratchpad, 0, drbg_statelen (drbg));
+  if (!seed)
+    return GPG_ERR_INV_ARG;
+
+  if (reseed)
+    {
+      /* 10.1.1.3 step 1: string length is concatenation of
+       * 1 byte, V and seed (which is concatenated entropy/addtl
+       * input)
+       */
+      memcpy (V, drbg->V, drbg_statelen (drbg));
+      drbg_string_fill (&data1, &prefix, 1);
+      drbg_string_fill (&data2, V, drbg_statelen (drbg));
+      data1.next = &data2;
+      data2.next = seed;
+    }
+  else
+    {
+      drbg_string_fill (&data1, seed->buf, seed->len);
+      data1.next = seed->next;
+    }
+
+  /* 10.1.1.2 / 10.1.1.3 step 2 and 3 */
+  ret = drbg_hash_df (drbg, drbg->V, drbg_statelen (drbg), &data1);
+  if (ret)
+    goto out;
+
+  /* 10.1.1.2 / 10.1.1.3 step 4 -- concatenation  */
+  prefix = DRBG_PREFIX0;
+  drbg_string_fill (&data1, &prefix, 1);
+  drbg_string_fill (&data2, drbg->V, drbg_statelen (drbg));
+  data1.next = &data2;
+  /* 10.1.1.2 / 10.1.1.3 step 4 -- df operation */
+  ret = drbg_hash_df (drbg, drbg->C, drbg_statelen (drbg), &data1);
+
+ out:
+  memset (drbg->scratchpad, 0, drbg_statelen (drbg));
+  return ret;
+}
+
+/* Processing of additional information string for Hash DRBG.  */
+static gpg_err_code_t
+drbg_hash_process_addtl (drbg_state_t drbg, drbg_string_t *addtl)
+{
+  gpg_err_code_t ret = 0;
+  drbg_string_t data1, data2;
+  drbg_string_t *data3;
+  unsigned char prefix = DRBG_PREFIX2;
+
+  /* this is value w as per documentation */
+  memset (drbg->scratchpad, 0, drbg_blocklen (drbg));
+
+  /* 10.1.1.4 step 2 */
+  if (!addtl || 0 == addtl->len)
+    return 0;
+
+  /* 10.1.1.4 step 2a -- concatenation */
+  drbg_string_fill (&data1, &prefix, 1);
+  drbg_string_fill (&data2, drbg->V, drbg_statelen (drbg));
+  data3 = addtl;
+  data1.next = &data2;
+  data2.next = data3;
+  data3->next = NULL;
+  /* 10.1.1.4 step 2a -- cipher invocation */
+  ret = drbg_hmac (drbg, NULL, drbg->scratchpad, &data1);
+  if (ret)
+    goto out;
+
+  /* 10.1.1.4 step 2b */
+  drbg_add_buf (drbg->V, drbg_statelen (drbg),
+                    drbg->scratchpad, drbg_blocklen (drbg));
+
+ out:
+  memset (drbg->scratchpad, 0, drbg_blocklen (drbg));
+  return ret;
+}
+
+/*
+ * Hashgen defined in 10.1.1.4
+ */
+static gpg_err_code_t
+drbg_hash_hashgen (drbg_state_t drbg,
+                   unsigned char *buf, unsigned int buflen)
+{
+  gpg_err_code_t ret = 0;
+  unsigned int len = 0;
+  unsigned char *src = drbg->scratchpad;
+  unsigned char *dst = drbg->scratchpad + drbg_statelen (drbg);
+  drbg_string_t data;
+  unsigned char prefix = DRBG_PREFIX1;
+
+  /* use the scratchpad as a lookaside buffer */
+  memset (src, 0, drbg_statelen (drbg));
+  memset (dst, 0, drbg_blocklen (drbg));
+
+  /* 10.1.1.4 step hashgen 2 */
+  memcpy (src, drbg->V, drbg_statelen (drbg));
+
+  drbg_string_fill (&data, src, drbg_statelen (drbg));
+  while (len < buflen)
+    {
+      unsigned int outlen = 0;
+      /* 10.1.1.4 step hashgen 4.1 */
+      ret = drbg_hmac (drbg, NULL, dst, &data);
+      if (ret)
+       goto out;
+      outlen = (drbg_blocklen (drbg) < (buflen - len)) ?
+       drbg_blocklen (drbg) : (buflen - len);
+      /* 10.1.1.4 step hashgen 4.2 */
+      memcpy (buf + len, dst, outlen);
+      len += outlen;
+      /* 10.1.1.4 hashgen step 4.3 */
+      if (len < buflen)
+       drbg_add_buf (src, drbg_statelen (drbg), &prefix, 1);
+    }
+
+ out:
+  memset (drbg->scratchpad, 0,
+         (drbg_statelen (drbg) + drbg_blocklen (drbg)));
+  return ret;
+}
+
+/* Generate function for Hash DRBG as defined in 10.1.1.4  */
+static gpg_err_code_t
+drbg_hash_generate (drbg_state_t drbg,
+                        unsigned char *buf, unsigned int buflen,
+                        drbg_string_t *addtl)
+{
+  gpg_err_code_t ret = 0;
+  unsigned char prefix = DRBG_PREFIX3;
+  drbg_string_t data1, data2;
+  union
+  {
+    unsigned char req[8];
+    u64 req_int;
+  } u;
+
+  /*
+   * scratchpad usage: drbg_hash_process_addtl uses the scratchpad, but
+   * fully completes before returning. Thus, we can reuse the scratchpad
+   */
+  /* 10.1.1.4 step 2 */
+  ret = drbg_hash_process_addtl (drbg, addtl);
+  if (ret)
+    return ret;
+  /* 10.1.1.4 step 3 -- invocation of the Hashgen function defined in
+   * 10.1.1.4 */
+  ret = drbg_hash_hashgen (drbg, buf, buflen);
+  if (ret)
+    return ret;
+
+  /* this is the value H as documented in 10.1.1.4 */
+  memset (drbg->scratchpad, 0, drbg_blocklen (drbg));
+  /* 10.1.1.4 step 4 */
+  drbg_string_fill (&data1, &prefix, 1);
+  drbg_string_fill (&data2, drbg->V, drbg_statelen (drbg));
+  data1.next = &data2;
+  ret = drbg_hmac (drbg, NULL, drbg->scratchpad, &data1);
+  if (ret)
+    goto out;
+
+  /* 10.1.1.4 step 5 */
+  drbg_add_buf (drbg->V, drbg_statelen (drbg),
+                    drbg->scratchpad, drbg_blocklen (drbg));
+  drbg_add_buf (drbg->V, drbg_statelen (drbg), drbg->C,
+                    drbg_statelen (drbg));
+  u.req_int = be_bswap64 (drbg->reseed_ctr);
+  drbg_add_buf (drbg->V, drbg_statelen (drbg), u.req,
+                    sizeof (u.req));
+
+ out:
+  memset (drbg->scratchpad, 0, drbg_blocklen (drbg));
+  return ret;
+}
+
+/*
+ * scratchpad usage: as update and generate are used isolated, both
+ * can use the scratchpad
+ */
+static struct drbg_state_ops_s drbg_hash_ops = {
+  drbg_hash_update,
+  drbg_hash_generate
+};
+
+/******************************************************************
+ * Functions common for DRBG implementations
+ ******************************************************************/
+
+/*
+ * Seeding or reseeding of the DRBG
+ *
+ * @drbg: DRBG state struct
+ * @pers: personalization / additional information buffer
+ * @reseed: 0 for initial seed process, 1 for reseeding
+ *
+ * return:
+ *     0 on success
+ *     error value otherwise
+ */
+static gpg_err_code_t
+drbg_seed (drbg_state_t drbg, drbg_string_t *pers, int reseed)
+{
+  gpg_err_code_t ret = 0;
+  unsigned char *entropy = NULL;
+  size_t entropylen = 0;
+  drbg_string_t data1;
+
+  /* 9.1 / 9.2 / 9.3.1 step 3 */
+  if (pers && pers->len > (drbg_max_addtl ()))
+    {
+      dbg (("DRBG: personalization string too long %lu\n", pers->len));
+      return GPG_ERR_INV_ARG;
+    }
+  if (drbg->test_data && drbg->test_data->testentropy)
+    {
+      drbg_string_fill (&data1, drbg->test_data->testentropy->buf,
+                            drbg->test_data->testentropy->len);
+      dbg (("DRBG: using test entropy\n"));
+    }
+  else
+    {
+      /* Gather entropy equal to the security strength of the DRBG.
+       * With a derivation function, a nonce is required in addition
+       * to the entropy. A nonce must be at least 1/2 of the security
+       * strength of the DRBG in size. Thus, entropy * nonce is 3/2
+       * of the strength. The consideration of a nonce is only
+       * applicable during initial seeding. */
+      entropylen = drbg_sec_strength (drbg->core->flags);
+      if (!entropylen)
+       return GPG_ERR_GENERAL;
+      if (0 == reseed)
+       /* make sure we round up strength/2 in
+        * case it is not divisible by 2 */
+       entropylen = ((entropylen + 1) / 2) * 3;
+      dbg (("DRBG: (re)seeding with %lu bytes of entropy\n", entropylen));
+      entropy = xcalloc_secure (1, entropylen);
+      if (!entropy)
+       return GPG_ERR_ENOMEM;
+      ret = drbg_get_entropy (drbg, entropy, entropylen);
+      if (ret)
+       goto out;
+      drbg_string_fill (&data1, entropy, entropylen);
+    }
+
+  /* concatenation of entropy with personalization str / addtl input)
+   * the variable pers is directly handed by the caller, check its
+   * contents whether it is appropriate */
+  if (pers && pers->buf && 0 < pers->len && NULL == pers->next)
+    {
+      data1.next = pers;
+      dbg (("DRBG: using personalization string\n"));
+    }
+
+  ret = drbg->d_ops->update (drbg, &data1, reseed);
+  dbg (("DRBG: state updated with seed\n"));
+  if (ret)
+    goto out;
+  drbg->seeded = 1;
+  /* 10.1.1.2 / 10.1.1.3 step 5 */
+  drbg->reseed_ctr = 1;
+
+ out:
+  xfree (entropy);
+  return ret;
+}
+
+\f
+/*************************************************************************
+ * Exported interfaces.
+ *************************************************************************/
+
+/*
+ * DRBG generate function as required by SP800-90A - this function
+ * generates random numbers
+ *
+ * @drbg   DRBG state handle
+ * @buf    Buffer where to store the random numbers -- the buffer must already
+ *         be pre-allocated by caller
+ * @buflen Length of output buffer - this value defines the number of random
+ *        bytes pulled from DRBG
+ * @addtl  Additional input that is mixed into state, may be NULL -- note
+ *        the entropy is pulled by the DRBG internally unconditionally
+ *        as defined in SP800-90A. The additional input is mixed into
+ *        the state in addition to the pulled entropy.
+ *
+ * return: Generated number of bytes.
+ */
+static gpg_err_code_t
+drbg_generate (drbg_state_t drbg,
+               unsigned char *buf, unsigned int buflen,
+               drbg_string_t *addtl)
+{
+  gpg_err_code_t ret = GPG_ERR_INV_ARG;
+
+  if (0 == buflen || !buf)
+    {
+      dbg (("DRBG: no buffer provided\n"));
+      return ret;
+    }
+  if (addtl && NULL == addtl->buf && 0 < addtl->len)
+    {
+      dbg (("DRBG: wrong format of additional information\n"));
+      return ret;
+    }
+
+  /* 9.3.1 step 2 */
+  if (buflen > (drbg_max_request_bytes ()))
+    {
+      dbg (("DRBG: requested random numbers too large %u\n", buflen));
+      return ret;
+    }
+  /* 9.3.1 step 3 is implicit with the chosen DRBG */
+  /* 9.3.1 step 4 */
+  if (addtl && addtl->len > (drbg_max_addtl ()))
+    {
+      dbg (("DRBG: additional information string too long %lu\n",
+           addtl->len));
+      return ret;
+    }
+  /* 9.3.1 step 5 is implicit with the chosen DRBG */
+  /* 9.3.1 step 6 and 9 supplemented by 9.3.2 step c -- the spec is a
+   * bit convoluted here, we make it simpler */
+  if ((drbg_max_requests ()) < drbg->reseed_ctr)
+    drbg->seeded = 0;
+
+  if (drbg->pr || !drbg->seeded)
+    {
+      dbg (("DRBG: reseeding before generation (prediction resistance: %s, state %s)\n", drbg->pr ? "true" : "false", drbg->seeded ? "seeded" : "unseeded"));
+      /* 9.3.1 steps 7.1 through 7.3 */
+      ret = drbg_seed (drbg, addtl, 1);
+      if (ret)
+       return ret;
+      /* 9.3.1 step 7.4 */
+      addtl = NULL;
+    }
+
+  if (addtl && addtl->buf)
+    {
+      dbg (("DRBG: using additional information string\n"));
+    }
+
+  /* 9.3.1 step 8 and 10 */
+  ret = drbg->d_ops->generate (drbg, buf, buflen, addtl);
+
+  /* 10.1.1.4 step 6, 10.1.2.5 step 7, 10.2.1.5.2 step 7 */
+  drbg->reseed_ctr++;
+  if (ret)
+    return ret;
+
+  /* 11.3.3 -- re-perform self tests after some generated random
+   * numbers, the chosen value after which self test is performed
+   * is arbitrary, but it should be reasonable */
+  /* Here we do not perform the self tests because of the following
+   * reasons: it is mathematically impossible that the initial self tests
+   * were successfully and the following are not. If the initial would
+   * pass and the following would not, the system integrity is violated.
+   * In this case, the entire system operation is questionable and it
+   * is unlikely that the integrity violation only affects to the
+   * correct operation of the DRBG.
+   */
+#if 0
+  if (drbg->reseed_ctr && !(drbg->reseed_ctr % 4096))
+    {
+      dbg (("DRBG: start to perform self test\n"));
+      ret = drbg_healthcheck ();
+      if (ret)
+       {
+         log_fatal (("DRBG: self test failed\n"));
+         return ret;
+       }
+      else
+       {
+         dbg (("DRBG: self test successful\n"));
+       }
+    }
+#endif
+
+  return ret;
+}
+
+/*
+ * Wrapper around drbg_generate which can pull arbitrary long strings
+ * from the DRBG without hitting the maximum request limitation.
+ *
+ * Parameters: see drbg_generate
+ * Return codes: see drbg_generate -- if one drbg_generate request fails,
+ *              the entire drbg_generate_long request fails
+ */
+static gpg_err_code_t
+drbg_generate_long (drbg_state_t drbg,
+                    unsigned char *buf, unsigned int buflen,
+                    drbg_string_t *addtl)
+{
+  gpg_err_code_t ret = 0;
+  unsigned int slice = 0;
+  unsigned char *buf_p = buf;
+  unsigned len = 0;
+  do
+    {
+      unsigned int chunk = 0;
+      slice = ((buflen - len) / drbg_max_request_bytes ());
+      chunk = slice ? drbg_max_request_bytes () : (buflen - len);
+      ret = drbg_generate (drbg, buf_p, chunk, addtl);
+      if (ret)
+       return ret;
+      buf_p += chunk;
+      len += chunk;
+    }
+  while (slice > 0 && (len < buflen));
+  return ret;
+}
+
+/*
+ * DRBG uninstantiate function as required by SP800-90A - this function
+ * frees all buffers and the DRBG handle
+ *
+ * @drbg DRBG state handle
+ *
+ * return
+ *     0 on success
+ */
+static gpg_err_code_t
+drbg_uninstantiate (drbg_state_t drbg)
+{
+  if (!drbg)
+    return GPG_ERR_INV_ARG;
+  xfree (drbg->V);
+  drbg->V = NULL;
+  xfree (drbg->C);
+  drbg->C = NULL;
+  drbg->reseed_ctr = 0;
+  xfree (drbg->scratchpad);
+  drbg->scratchpad = NULL;
+  drbg->seeded = 0;
+  drbg->pr = 0;
+  drbg->seed_init_pid = 0;
+  return 0;
+}
+
+/*
+ * DRBG instantiation function as required by SP800-90A - this function
+ * sets up the DRBG handle, performs the initial seeding and all sanity
+ * checks required by SP800-90A
+ *
+ * @drbg memory of state -- if NULL, new memory is allocated
+ * @pers Personalization string that is mixed into state, may be NULL -- note
+ *      the entropy is pulled by the DRBG internally unconditionally
+ *      as defined in SP800-90A. The additional input is mixed into
+ *      the state in addition to the pulled entropy.
+ * @coreref reference to core
+ * @flags Flags defining the requested DRBG type and cipher type. The flags
+ *       are defined in drbg.h and may be XORed. Beware, if you XOR multiple
+ *       cipher types together, the code picks the core on a first come first
+ *       serve basis as it iterates through the available cipher cores and
+ *       uses the one with the first match. The minimum required flags are:
+ *             cipher type flag
+ *
+ * return
+ *     0 on success
+ *     error value otherwise
+ */
+static gpg_err_code_t
+drbg_instantiate (drbg_state_t drbg,
+                  drbg_string_t *pers, int coreref, int pr)
+{
+  gpg_err_code_t ret = GPG_ERR_ENOMEM;
+  unsigned int sb_size = 0;
+
+  if (!drbg)
+    return GPG_ERR_INV_ARG;
+
+  dbg (("DRBG: Initializing DRBG core %d with prediction resistance %s\n",
+       coreref, pr ? "enabled" : "disabled"));
+  drbg->core = &drbg_cores[coreref];
+  drbg->pr = pr;
+  drbg->seeded = 0;
+  if (drbg->core->flags & DRBG_HMAC)
+    drbg->d_ops = &drbg_hmac_ops;
+  else if (drbg->core->flags & DRBG_HASH_MASK)
+    drbg->d_ops = &drbg_hash_ops;
+  else if (drbg->core->flags & DRBG_CTR_MASK)
+    drbg->d_ops = &drbg_ctr_ops;
+  else
+    return GPG_ERR_GENERAL;
+  /* 9.1 step 1 is implicit with the selected DRBG type -- see
+   * drbg_sec_strength() */
+
+  /* 9.1 step 2 is implicit as caller can select prediction resistance
+   * and the flag is copied into drbg->flags --
+   * all DRBG types support prediction resistance */
+
+  /* 9.1 step 4 is implicit in  drbg_sec_strength */
+
+  /* no allocation of drbg as this is done by the kernel crypto API */
+  drbg->V = xcalloc_secure (1, drbg_statelen (drbg));
+  if (!drbg->V)
+    goto err;
+  drbg->C = xcalloc_secure (1, drbg_statelen (drbg));
+  if (!drbg->C)
+    goto err;
+  /* scratchpad is only generated for CTR and Hash */
+  if (drbg->core->flags & DRBG_HMAC)
+    sb_size = 0;
+  else if (drbg->core->flags & DRBG_CTR_MASK)
+    sb_size = drbg_statelen (drbg) + drbg_blocklen (drbg) +    /* temp */
+      drbg_statelen (drbg) +   /* df_data */
+      drbg_blocklen (drbg) +   /* pad */
+      drbg_blocklen (drbg) +   /* iv */
+      drbg_statelen (drbg) + drbg_blocklen (drbg);     /* temp */
+  else
+    sb_size = drbg_statelen (drbg) + drbg_blocklen (drbg);
+
+  if (0 < sb_size)
+    {
+      drbg->scratchpad = xcalloc_secure (1, sb_size);
+      if (!drbg->scratchpad)
+       goto err;
+    }
+  dbg (("DRBG: state allocated with scratchpad size %u bytes\n", sb_size));
+
+  /* 9.1 step 6 through 11 */
+  ret = drbg_seed (drbg, pers, 0);
+  if (ret)
+    goto err;
+
+  dbg (("DRBG: core %d %s prediction resistance successfully initialized\n",
+       coreref, pr ? "with" : "without"));
+  return 0;
+
+ err:
+  drbg_uninstantiate (drbg);
+  return ret;
+}
+
+/*
+ * DRBG reseed function as required by SP800-90A
+ *
+ * @drbg DRBG state handle
+ * @addtl Additional input that is mixed into state, may be NULL -- note
+ *             the entropy is pulled by the DRBG internally unconditionally
+ *             as defined in SP800-90A. The additional input is mixed into
+ *             the state in addition to the pulled entropy.
+ *
+ * return
+ *     0 on success
+ *     error value otherwise
+ */
+static gpg_err_code_t
+drbg_reseed (drbg_state_t drbg,drbg_string_t *addtl)
+{
+  gpg_err_code_t ret = 0;
+  ret = drbg_seed (drbg, addtl, 1);
+  return ret;
+}
+
+
+\f
+/******************************************************************
+ * Libgcrypt integration code.
+ ******************************************************************/
+
+/***************************************************
+ * Libgcrypt backend functions to the RNG API code.
+ ***************************************************/
+
+static inline void
+drbg_lock (void)
+{
+  gpg_err_code_t ec;
+
+  ec = gpgrt_lock_lock (&drbg_lock_var);
+  if (ec)
+    log_fatal ("failed to acquire the RNG lock: %s\n", gpg_strerror (ec));
+}
+
+static inline void
+drbg_unlock (void)
+{
+  gpg_err_code_t ec;
+
+  ec = gpgrt_lock_unlock (&drbg_lock_var);
+  if (ec)
+    log_fatal ("failed to release the RNG lock: %s\n", gpg_strerror (ec));
+}
+
+/* Basic initialization is required to initialize mutexes and
+   do a few checks on the implementation.  */
+static void
+basic_initialization (void)
+{
+  static int initialized;
+
+  if (initialized)
+    return;
+  initialized = 1;
+
+  /* Make sure that we are still using the values we have
+     traditionally used for the random levels.  */
+  gcry_assert (GCRY_WEAK_RANDOM == 0
+               && GCRY_STRONG_RANDOM == 1
+               && GCRY_VERY_STRONG_RANDOM == 2);
+}
+
+/****** helper functions where lock must be held by caller *****/
+
+/* Check whether given flags are known to point to an applicable DRBG */
+static gpg_err_code_t
+drbg_algo_available (u32 flags, int *coreref)
+{
+  int i = 0;
+  for (i = 0; ARRAY_SIZE (drbg_cores) > i; i++)
+    {
+      if ((drbg_cores[i].flags & DRBG_CIPHER_MASK) ==
+         (flags & DRBG_CIPHER_MASK))
+       {
+         *coreref = i;
+         return 0;
+       }
+    }
+  return GPG_ERR_GENERAL;
+}
+
+static gpg_err_code_t
+_drbg_init_internal (u32 flags, drbg_string_t *pers)
+{
+  static u32 oldflags;
+  gpg_err_code_t ret = 0;
+  int coreref = 0;
+  int pr = 0;
+
+  /* If a caller provides 0 as flags, use the flags of the previous
+   * initialization, otherwise use the current flags and remember them
+   * for the next invocation.  If no flag is given and no global state
+   * is set this is the first initialization and we set the default
+   * type.
+   */
+  if (!flags && !drbg_state)
+    flags = oldflags = DRBG_DEFAULT_TYPE;
+  else if (!flags)
+    flags = oldflags;
+  else
+    oldflags = flags;
+
+  ret = drbg_algo_available (flags, &coreref);
+  if (ret)
+    return ret;
+
+  if (drbg_state)
+    {
+      drbg_uninstantiate (drbg_state);
+    }
+  else
+    {
+      drbg_state = xtrycalloc_secure (1, sizeof *drbg_state);
+      if (!drbg_state)
+       return gpg_err_code_from_syserror ();
+    }
+  if (flags & DRBG_PREDICTION_RESIST)
+    pr = 1;
+  ret = drbg_instantiate (drbg_state, pers, coreref, pr);
+  if (ret)
+    fips_signal_error ("DRBG cannot be initialized");
+  else
+    drbg_state->seed_init_pid = getpid ();
+  return ret;
+}
+
+/************* calls available to common RNG code **************/
+
+/*
+ * Initialize one DRBG invoked by the libgcrypt API
+ */
+void
+_gcry_rngdrbg_inititialize (int full)
+{
+  basic_initialization ();
+  if (!full)
+      return;
+  drbg_lock ();
+  if (!drbg_state)
+    _drbg_init_internal (0, NULL);
+  drbg_unlock ();
+}
+
+/*
+ * Backend handler function for GCRYCTL_DRBG_REINIT
+ *
+ * Select a different DRBG type and initialize it.
+ * Function checks whether requested DRBG type exists and returns an error in
+ * case it does not. In case of an error, the previous instantiated DRBG is
+ * left untouched and alive. Thus, in case of an error, a DRBG is always
+ * available, even if it is not the chosen one.
+ *
+ * Re-initialization will be performed in any case regardless whether flags
+ * or personalization string are set.
+ *
+ * If flags is NULL, do not change current DRBG.  If PERS is NULL and
+ * NPERS is 0, re-initialize without personalization string.  If PERS
+ * is not NULL NPERS must be one and PERS and the first ietm from the
+ * bufer is take as personalization string.
+ */
+gpg_err_code_t
+_gcry_rngdrbg_reinit (const char *flagstr, gcry_buffer_t *pers, int npers)
+{
+  gpg_err_code_t ret;
+  unsigned int flags;
+
+  /* If PERS is not given we expect NPERS to be zero; if given we
+     expect a one-item array.  */
+  if ((!pers && npers) || (pers && npers != 1))
+    return GPG_ERR_INV_ARG;
+
+  ret = parse_flag_string (flagstr, &flags);
+  if (!ret)
+    {
+      dbg (("DRBG: reinitialize internal DRBG state with flags %u\n", flags));
+      drbg_lock ();
+      if (pers)
+        {
+          drbg_string_t persbuf;
+
+          drbg_string_fill
+            (&persbuf, (const unsigned char *)pers[0].data + pers[0].off,
+             pers[0].len);
+          ret = _drbg_init_internal (flags, &persbuf);
+        }
+      else
+        ret = _drbg_init_internal (flags, NULL);
+      drbg_unlock ();
+    }
+  return ret;
+}
+
+/* Try to close the FDs of the random gather module.  This is
+ * currently only implemented for rndlinux. */
+void
+_gcry_rngdrbg_close_fds (void)
+{
+#if USE_RNDLINUX
+  drbg_lock ();
+  _gcry_rndlinux_gather_random (NULL, 0, 0, 0);
+  drbg_unlock ();
+#endif
+}
+
+/* Print some statistics about the RNG.  */
+void
+_gcry_rngdrbg_dump_stats (void)
+{
+  /* Not yet implemented.  */
+  /* Maybe dumping of reseed counter? */
+}
+
+/* This function returns true if no real RNG is available or the
+ * quality of the RNG has been degraded for test purposes.  */
+int
+_gcry_rngdrbg_is_faked (void)
+{
+  return 0;                    /* Faked random is not allowed.  */
+}
+
+/* Add BUFLEN bytes from BUF to the internal random pool.  QUALITY
+ * should be in the range of 0..100 to indicate the goodness of the
+ * entropy added, or -1 for goodness not known. */
+gcry_error_t
+_gcry_rngdrbg_add_bytes (const void *buf, size_t buflen, int quality)
+{
+  gpg_err_code_t ret = 0;
+  drbg_string_t seed;
+  (void) quality;
+  _gcry_rngdrbg_inititialize (1); /* Auto-initialize if needed */
+  if (!drbg_state)
+    return GPG_ERR_GENERAL;
+  drbg_string_fill (&seed, (unsigned char *) buf, buflen);
+  drbg_lock ();
+  ret = drbg_reseed (drbg_state, &seed);
+  drbg_unlock ();
+  return ret;
+}
+
+/* This function is to be used for all types of random numbers, including
+ * nonces
+ */
+void
+_gcry_rngdrbg_randomize (void *buffer, size_t length,
+                     enum gcry_random_level level)
+{
+  (void) level;
+  _gcry_rngdrbg_inititialize (1); /* Auto-initialize if needed */
+  drbg_lock ();
+  if (!drbg_state)
+    {
+      fips_signal_error ("DRBG is not initialized");
+      goto bailout;
+    }
+
+  /* As reseeding changes the entire state of the DRBG, including any
+   * key, either a re-init or a reseed is sufficient for a fork */
+  if (drbg_state->seed_init_pid != getpid ())
+    {
+      /* We are in a child of us. Perform a reseeding. */
+      if (drbg_reseed (drbg_state, NULL))
+       {
+         fips_signal_error ("reseeding upon fork failed");
+         log_fatal ("severe error getting random\n");
+         goto bailout;
+       }
+    }
+  /* potential integer overflow is covered by drbg_generate which
+   * ensures that length cannot overflow an unsigned int */
+  if (0 < length)
+    {
+      if (!buffer)
+       goto bailout;
+      if (drbg_generate_long (drbg_state, buffer, (unsigned int) length, NULL))
+       log_fatal ("No random numbers generated\n");
+    }
+  else
+    {
+      drbg_gen_t *data = (drbg_gen_t *)buffer;
+      /* catch NULL pointer */
+      if (!data || !data->outbuf)
+       {
+         fips_signal_error ("No output buffer provided");
+         goto bailout;
+       }
+      if (drbg_generate_long (drbg_state, data->outbuf, data->outlen,
+                              data->addtl))
+       log_fatal ("No random numbers generated\n");
+    }
+
+ bailout:
+  drbg_unlock ();
+  return;
+
+}
+
+/***************************************************************
+ * Self-test code
+ ***************************************************************/
+
+/*
+ * Test vectors from
+ * http://csrc.nist.gov/groups/STM/cavp/documents/drbg/drbgtestvectors.zip
+ */
+struct gcry_drbg_test_vector drbg_test_pr[] = {
+  {
+    /* .flags = */ "sha256 pr" /* DRBG_PR_HASHSHA256 */,
+    /* .entropy = */ (unsigned char *)
+    "\x5d\xf2\x14\xbc\xf6\xb5\x4e\x0b\xf0\x0d\x6f\x2d"
+    "\xe2\x01\x66\x7b\xd0\xa4\x73\xa4\x21\xdd\xb0\xc0"
+    "\x51\x79\x09\xf4\xea\xa9\x08\xfa\xa6\x67\xe0\xe1"
+    "\xd1\x88\xa8\xad\xee\x69\x74\xb3\x55\x06\x9b\xf6",
+    /* .entropylen = */ 48,
+    /* .entpra = */ (unsigned char *)
+    "\xef\x48\x06\xa2\xc2\x45\xf1\x44\xfa\x34\x2c\xeb"
+    "\x8d\x78\x3c\x09\x8f\x34\x72\x20\xf2\xe7\xfd\x13"
+    "\x76\x0a\xf6\xdc\x3c\xf5\xc0\x15",
+    /* .entprb = */ (unsigned char *)
+    "\x4b\xbe\xe5\x24\xed\x6a\x2d\x0c\xdb\x73\x5e\x09"
+    "\xf9\xad\x67\x7c\x51\x47\x8b\x6b\x30\x2a\xc6\xde"
+    "\x76\xaa\x55\x04\x8b\x0a\x72\x95",
+    /* .entprlen = */ 32,
+    /* .addtla = */ (unsigned char *)
+    "\xbe\x13\xdb\x2a\xe9\xa8\xfe\x09\x97\xe1\xce\x5d"
+    "\xe8\xbb\xc0\x7c\x4f\xcb\x62\x19\x3f\x0f\xd2\xad"
+    "\xa9\xd0\x1d\x59\x02\xc4\xff\x70",
+    /* .addtlb = */ (unsigned char *)
+    "\x6f\x96\x13\xe2\xa7\xf5\x6c\xfe\xdf\x66\xe3\x31"
+    "\x63\x76\xbf\x20\x27\x06\x49\xf1\xf3\x01\x77\x41"
+    "\x9f\xeb\xe4\x38\xfe\x67\x00\xcd",
+    /* .addtllen = */ 32,
+    /* .pers = */ NULL,
+    /* .perslen = */ 0,
+    /* .expected = */ (unsigned char *)
+    "\x3b\x14\x71\x99\xa1\xda\xa0\x42\xe6\xc8\x85\x32"
+    "\x70\x20\x32\x53\x9a\xbe\xd1\x1e\x15\xef\xfb\x4c"
+    "\x25\x6e\x19\x3a\xf0\xb9\xcb\xde\xf0\x3b\xc6\x18"
+    "\x4d\x85\x5a\x9b\xf1\xe3\xc2\x23\x03\x93\x08\xdb"
+    "\xa7\x07\x4b\x33\x78\x40\x4d\xeb\x24\xf5\x6e\x81"
+    "\x4a\x1b\x6e\xa3\x94\x52\x43\xb0\xaf\x2e\x21\xf4"
+    "\x42\x46\x8e\x90\xed\x34\x21\x75\xea\xda\x67\xb6"
+    "\xe4\xf6\xff\xc6\x31\x6c\x9a\x5a\xdb\xb3\x97\x13"
+    "\x09\xd3\x20\x98\x33\x2d\x6d\xd7\xb5\x6a\xa8\xa9"
+    "\x9a\x5b\xd6\x87\x52\xa1\x89\x2b\x4b\x9c\x64\x60"
+    "\x50\x47\xa3\x63\x81\x16\xaf\x19",
+    /* .expectedlen = */ 128,
+    /* .entropyreseed = */ NULL,
+    /* .entropyreseed_len = */ 0,
+    /* .addtl_reseed = */ NULL,
+    /* .addtl_reseed_len = */ 0
+  },
+  {
+    /* flags = */ "hmac sha256 pr" /* DRBG_PR_HMACSHA256 */,
+    /* .entropy = */ (unsigned char *)
+    "\x13\x54\x96\xfc\x1b\x7d\x28\xf3\x18\xc9\xa7\x89"
+    "\xb6\xb3\xc8\x72\xac\x00\xd4\x59\x36\x25\x05\xaf"
+    "\xa5\xdb\x96\xcb\x3c\x58\x46\x87\xa5\xaa\xbf\x20"
+    "\x3b\xfe\x23\x0e\xd1\xc7\x41\x0f\x3f\xc9\xb3\x67",
+    /* .entropylen = */ 48,
+    /* .entpra = */ (unsigned char *)
+    "\xe2\xbd\xb7\x48\x08\x06\xf3\xe1\x93\x3c\xac\x79"
+    "\xa7\x2b\x11\xda\xe3\x2e\xe1\x91\xa5\x02\x19\x57"
+    "\x20\x28\xad\xf2\x60\xd7\xcd\x45",
+    /* .entprb = */ (unsigned char *)
+    "\x8b\xd4\x69\xfc\xff\x59\x95\x95\xc6\x51\xde\x71"
+    "\x68\x5f\xfc\xf9\x4a\xab\xec\x5a\xcb\xbe\xd3\x66"
+    "\x1f\xfa\x74\xd3\xac\xa6\x74\x60",
+    /* .entprlen = */ 32,
+    /* .addtla = */ NULL,
+    /* .addtlb = */ NULL,
+    /* .addtllen = */ 0,
+    /* .pers = */ (unsigned char *)
+    "\x64\xb6\xfc\x60\xbc\x61\x76\x23\x6d\x3f\x4a\x0f"
+    "\xe1\xb4\xd5\x20\x9e\x70\xdd\x03\x53\x6d\xbf\xce"
+    "\xcd\x56\x80\xbc\xb8\x15\xc8\xaa",
+    /* .perslen = */ 32,
+    /* .expected = */ (unsigned char *)
+    "\x1f\x9e\xaf\xe4\xd2\x46\xb7\x47\x41\x4c\x65\x99"
+    "\x01\xe9\x3b\xbb\x83\x0c\x0a\xb0\xc1\x3a\xe2\xb3"
+    "\x31\x4e\xeb\x93\x73\xee\x0b\x26\xc2\x63\xa5\x75"
+    "\x45\x99\xd4\x5c\x9f\xa1\xd4\x45\x87\x6b\x20\x61"
+    "\x40\xea\x78\xa5\x32\xdf\x9e\x66\x17\xaf\xb1\x88"
+    "\x9e\x2e\x23\xdd\xc1\xda\x13\x97\x88\xa5\xb6\x5e"
+    "\x90\x14\x4e\xef\x13\xab\x5c\xd9\x2c\x97\x9e\x7c"
+    "\xd7\xf8\xce\xea\x81\xf5\xcd\x71\x15\x49\x44\xce"
+    "\x83\xb6\x05\xfb\x7d\x30\xb5\x57\x2c\x31\x4f\xfc"
+    "\xfe\x80\xb6\xc0\x13\x0c\x5b\x9b\x2e\x8f\x3d\xfc"
+    "\xc2\xa3\x0c\x11\x1b\x80\x5f\xf3",
+    /* .expectedlen = */ 128,
+    /* .entropyreseed = */ NULL,
+    /* .entropyreseed_len = */ 0,
+    /* .addtl_reseed = */ NULL,
+    /* .addtl_reseed_len = */ 0
+  },
+  {
+    /* .flags = */ "aes sym128 pr", /* DRBG_PR_CTRAES128 */
+    /* .entropy = */ (unsigned char *)
+    "\x92\x89\x8f\x31\xfa\x1c\xff\x6d\x18\x2f\x26\x06"
+    "\x43\xdf\xf8\x18\xc2\xa4\xd9\x72\xc3\xb9\xb6\x97",
+    /* .entropylen = */ 24,
+    /* .entpra = */ (unsigned char *)
+    "\x20\x72\x8a\x06\xf8\x6f\x8d\xd4\x41\xe2\x72\xb7"
+    "\xc4\x2c\xe8\x10",
+    /* .entprb = */ (unsigned char *)
+    "\x3d\xb0\xf0\x94\xf3\x05\x50\x33\x17\x86\x3e\x22"
+    "\x08\xf7\xa5\x01",
+    /* .entprlen = */ 16,
+    /* .addtla = */ (unsigned char *)
+    "\x1a\x40\xfa\xe3\xcc\x6c\x7c\xa0\xf8\xda\xba\x59"
+    "\x23\x6d\xad\x1d",
+    /* .addtlb = */ (unsigned char *)
+    "\x9f\x72\x76\x6c\xc7\x46\xe5\xed\x2e\x53\x20\x12"
+    "\xbc\x59\x31\x8c",
+    /* .addtllen = */ 16,
+    /* .pers = */ (unsigned char *)
+    "\xea\x65\xee\x60\x26\x4e\x7e\xb6\x0e\x82\x68\xc4"
+    "\x37\x3c\x5c\x0b",
+    /* .perslen = */ 16,
+    /* .expected = */ (unsigned char *)
+    "\x5a\x35\x39\x87\x0f\x4d\x22\xa4\x09\x24\xee\x71"
+    "\xc9\x6f\xac\x72\x0a\xd6\xf0\x88\x82\xd0\x83\x28"
+    "\x73\xec\x3f\x93\xd8\xab\x45\x23\xf0\x7e\xac\x45"
+    "\x14\x5e\x93\x9f\xb1\xd6\x76\x43\x3d\xb6\xe8\x08"
+    "\x88\xf6\xda\x89\x08\x77\x42\xfe\x1a\xf4\x3f\xc4"
+    "\x23\xc5\x1f\x68",
+    /* .expectedlen = */ 64,
+    /* .entropyreseed = */ NULL,
+    /* .entropyreseed_len = */ 0,
+    /* .addtl_reseed = */ NULL,
+    /* .addtl_reseed_len = */ 0
+   }
+};
+
+struct gcry_drbg_test_vector drbg_test_nopr[] = {
+  {
+    /* .flags = */ "sha256" /* DRBG_NOPR_HASHSHA256 */,
+    /* .entropy = */ (unsigned char *)
+    "\x73\xd3\xfb\xa3\x94\x5f\x2b\x5f\xb9\x8f\xf6\x9c"
+    "\x8a\x93\x17\xae\x19\xc3\x4c\xc3\xd6\xca\xa3\x2d"
+    "\x16\xfc\x42\xd2\x2d\xd5\x6f\x56\xcc\x1d\x30\xff"
+    "\x9e\x06\x3e\x09\xce\x58\xe6\x9a\x35\xb3\xa6\x56",
+    /* .entropylen = */ 48,
+    /* .entpra = */ NULL,
+    /* .entprb = */ NULL,
+    /* .entprlen = */ 0,
+    /* .addtla = */ (unsigned char *)
+    "\xf4\xd5\x98\x3d\xa8\xfc\xfa\x37\xb7\x54\x67\x73"
+    "\xc7\xc3\xdd\x47\x34\x71\x02\x5d\xc1\xa0\xd3\x10"
+    "\xc1\x8b\xbd\xf5\x66\x34\x6f\xdd",
+    /* .addtlb = */ (unsigned char *)
+    "\xf7\x9e\x6a\x56\x0e\x73\xe9\xd9\x7a\xd1\x69\xe0"
+    "\x6f\x8c\x55\x1c\x44\xd1\xce\x6f\x28\xcc\xa4\x4d"
+    "\xa8\xc0\x85\xd1\x5a\x0c\x59\x40",
+    /* .addtllen = */ 32,
+    /* .pers = */ NULL,
+    /* .perslen = */ 0,
+    /* .expected = */ (unsigned char *)
+    "\x71\x7b\x93\x46\x1a\x40\xaa\x35\xa4\xaa\xc5\xe7"
+    "\x6d\x5b\x5b\x8a\xa0\xdf\x39\x7d\xae\x71\x58\x5b"
+    "\x3c\x7c\xb4\xf0\x89\xfa\x4a\x8c\xa9\x5c\x54\xc0"
+    "\x40\xdf\xbc\xce\x26\x81\x34\xf8\xba\x7d\x1c\xe8"
+    "\xad\x21\xe0\x74\xcf\x48\x84\x30\x1f\xa1\xd5\x4f"
+    "\x81\x42\x2f\xf4\xdb\x0b\x23\xf8\x73\x27\xb8\x1d"
+    "\x42\xf8\x44\x58\xd8\x5b\x29\x27\x0a\xf8\x69\x59"
+    "\xb5\x78\x44\xeb\x9e\xe0\x68\x6f\x42\x9a\xb0\x5b"
+    "\xe0\x4e\xcb\x6a\xaa\xe2\xd2\xd5\x33\x25\x3e\xe0"
+    "\x6c\xc7\x6a\x07\xa5\x03\x83\x9f\xe2\x8b\xd1\x1c"
+    "\x70\xa8\x07\x59\x97\xeb\xf6\xbe",
+    /* .expectedlen = */ 128,
+    /* .entropyreseed = */ NULL,
+    /* .entropyreseed_len = */ 0,
+    /* .addtl_reseed = */ NULL,
+    /* .addtl_reseed_len = */ 0
+  },
+  {
+    /* .flags = */ "hmac sha256" /* DRBG_NOPR_HMACSHA256 */,
+    /* .entropy = */ (unsigned char *)
+    "\x8d\xf0\x13\xb4\xd1\x03\x52\x30\x73\x91\x7d\xdf"
+    "\x6a\x86\x97\x93\x05\x9e\x99\x43\xfc\x86\x54\x54"
+    "\x9e\x7a\xb2\x2f\x7c\x29\xf1\x22\xda\x26\x25\xaf"
+    "\x2d\xdd\x4a\xbc\xce\x3c\xf4\xfa\x46\x59\xd8\x4e",
+    /* .entropylen = */ 48,
+    /* .entpra = */ NULL,
+    /* .entprb = */ NULL,
+    /* .entprlen = */ 0,
+    /* .addtla = */ NULL,
+    /* .addtlb = */ NULL,
+    /* .addtllen = */ 0,
+    /* .pers = */ (unsigned char *)
+    "\xb5\x71\xe6\x6d\x7c\x33\x8b\xc0\x7b\x76\xad\x37"
+    "\x57\xbb\x2f\x94\x52\xbf\x7e\x07\x43\x7a\xe8\x58"
+    "\x1c\xe7\xbc\x7c\x3a\xc6\x51\xa9",
+    /* .perslen = */ 32,
+    /* .expected = */ (unsigned char *)
+    "\xb9\x1c\xba\x4c\xc8\x4f\xa2\x5d\xf8\x61\x0b\x81"
+    "\xb6\x41\x40\x27\x68\xa2\x09\x72\x34\x93\x2e\x37"
+    "\xd5\x90\xb1\x15\x4c\xbd\x23\xf9\x74\x52\xe3\x10"
+    "\xe2\x91\xc4\x51\x46\x14\x7f\x0d\xa2\xd8\x17\x61"
+    "\xfe\x90\xfb\xa6\x4f\x94\x41\x9c\x0f\x66\x2b\x28"
+    "\xc1\xed\x94\xda\x48\x7b\xb7\xe7\x3e\xec\x79\x8f"
+    "\xbc\xf9\x81\xb7\x91\xd1\xbe\x4f\x17\x7a\x89\x07"
+    "\xaa\x3c\x40\x16\x43\xa5\xb6\x2b\x87\xb8\x9d\x66"
+    "\xb3\xa6\x0e\x40\xd4\xa8\xe4\xe9\xd8\x2a\xf6\xd2"
+    "\x70\x0e\x6f\x53\x5c\xdb\x51\xf7\x5c\x32\x17\x29"
+    "\x10\x37\x41\x03\x0c\xcc\x3a\x56",
+    /* .expectedlen = */ 128,
+    /* .entropyreseed = */ NULL,
+    /* .entropyreseed_len = */ 0,
+    /* .addtl_reseed = */ NULL,
+    /* .addtl_reseed_len = */ 0
+  },
+  {
+    /* .flags = */ "aes sym128" /* DRBG_NOPR_CTRAES128 */,
+    /* .entropy = */ (unsigned char *)
+    "\xc0\x70\x1f\x92\x50\x75\x8f\xcd\xf2\xbe\x73\x98"
+    "\x80\xdb\x66\xeb\x14\x68\xb4\xa5\x87\x9c\x2d\xa6",
+    /* .entropylen = */ 24,
+    /* .entpra = */ NULL,
+    /* .entprb = */ NULL,
+    /* .entprlen = */ 0,
+    /* .addtla = */ (unsigned char *)
+    "\xf9\x01\xf8\x16\x7a\x1d\xff\xde\x8e\x3c\x83\xe2"
+    "\x44\x85\xe7\xfe",
+    /* .addtlb = */ (unsigned char *)
+    "\x17\x1c\x09\x38\xc2\x38\x9f\x97\x87\x60\x55\xb4"
+    "\x82\x16\x62\x7f",
+    /* .addtllen = */ 16,
+    /* .pers = */ (unsigned char *)
+    "\x80\x08\xae\xe8\xe9\x69\x40\xc5\x08\x73\xc7\x9f"
+    "\x8e\xcf\xe0\x02",
+    /* .perslen = */ 16,
+    /* .expected = */ (unsigned char *)
+    "\x97\xc0\xc0\xe5\xa0\xcc\xf2\x4f\x33\x63\x48\x8a"
+    "\xdb\x13\x0a\x35\x89\xbf\x80\x65\x62\xee\x13\x95"
+    "\x7c\x33\xd3\x7d\xf4\x07\x77\x7a\x2b\x65\x0b\x5f"
+    "\x45\x5c\x13\xf1\x90\x77\x7f\xc5\x04\x3f\xcc\x1a"
+    "\x38\xf8\xcd\x1b\xbb\xd5\x57\xd1\x4a\x4c\x2e\x8a"
+    "\x2b\x49\x1e\x5c",
+    /* .expectedlen = */ 64,
+    /* .entropyreseed = */ NULL,
+    /* .entropyreseed_len = */ 0,
+    /* .addtl_reseed = */ NULL,
+    /* .addtl_reseed_len = */ 0
+  },
+  {
+    /* .flags = */ "sha1" /* DRBG_NOPR_HASHSHA1 */,
+    /* .entropy = */ (unsigned char *)
+    "\x16\x10\xb8\x28\xcc\xd2\x7d\xe0\x8c\xee\xa0\x32"
+    "\xa2\x0e\x92\x08\x49\x2c\xf1\x70\x92\x42\xf6\xb5",
+    /* .entropylen = */ 24,
+    /* .entpra = */ NULL,
+    /* .entprb = */ NULL,
+    /* .entprlen = */ 0,
+    /* .addtla = */ NULL,
+    /* .addtlb = */ NULL,
+    /* .addtllen = */ 0,
+    /* .pers = */ NULL,
+    /* .perslen = */ 0,
+    /* .expected = */ (unsigned char *)
+    "\x56\xf3\x3d\x4f\xdb\xb9\xa5\xb6\x4d\x26\x23\x44"
+    "\x97\xe9\xdc\xb8\x77\x98\xc6\x8d\x08\xf7\xc4\x11"
+    "\x99\xd4\xbd\xdf\x97\xeb\xbf\x6c\xb5\x55\x0e\x5d"
+    "\x14\x9f\xf4\xd5\xbd\x0f\x05\xf2\x5a\x69\x88\xc1"
+    "\x74\x36\x39\x62\x27\x18\x4a\xf8\x4a\x56\x43\x35"
+    "\x65\x8e\x2f\x85\x72\xbe\xa3\x33\xee\xe2\xab\xff"
+    "\x22\xff\xa6\xde\x3e\x22\xac\xa2",
+    /* .expectedlen = */ 80,
+    /* .entropyreseed = */ (unsigned char *)
+    "\x72\xd2\x8c\x90\x8e\xda\xf9\xa4\xd1\xe5\x26\xd8"
+    "\xf2\xde\xd5\x44",
+    /* .entropyreseed_len = */ 16,
+    /* .addtl_reseed = */ NULL,
+    /* .addtl_reseed_len = */ 0
+  },
+  {
+    /* .flags = */ "sha1" /* DRBG_NOPR_HASHSHA1 */,
+    /* .entropy = */ (unsigned char *)
+    "\xd9\xba\xb5\xce\xdc\xa9\x6f\x61\x78\xd6\x45\x09"
+    "\xa0\xdf\xdc\x5e\xda\xd8\x98\x94\x14\x45\x0e\x01",
+    /* .entropylen = */ 24,
+    /* .entpra = */ NULL,
+    /* .entprb = */ NULL,
+    /* .entprlen = */ 0,
+    /* .addtla = */ (unsigned char *)
+    "\x04\xfa\x28\x95\xaa\x5a\x6f\x8c\x57\x43\x34\x3b"
+    "\x80\x5e\x5e\xa4",
+    /* .addtlb = */ (unsigned char *)
+    "\xdf\x5d\xc4\x59\xdf\xf0\x2a\xa2\xf0\x52\xd7\x21"
+    "\xec\x60\x72\x30",
+    /* .addtllen = */ 16,
+    /* .pers = */ NULL,
+    /* .perslen = */ 0,
+    /* .expected = */ (unsigned char *)
+    "\xc4\x8b\x89\xf9\xda\x3f\x74\x82\x45\x55\x5d\x5d"
+    "\x03\x3b\x69\x3d\xd7\x1a\x4d\xf5\x69\x02\x05\xce"
+    "\xfc\xd7\x20\x11\x3c\xc2\x4e\x09\x89\x36\xff\x5e"
+    "\x77\xb5\x41\x53\x58\x70\xb3\x39\x46\x8c\xdd\x8d"
+    "\x6f\xaf\x8c\x56\x16\x3a\x70\x0a\x75\xb2\x3e\x59"
+    "\x9b\x5a\xec\xf1\x6f\x3b\xaf\x6d\x5f\x24\x19\x97"
+    "\x1f\x24\xf4\x46\x72\x0f\xea\xbe",
+    /* .expectedlen = */ 80,
+    /* .entropyreseed = */ (unsigned char *)
+    "\xc6\xba\xd0\x74\xc5\x90\x67\x86\xf5\xe1\xf3\x20"
+    "\x99\xf5\xb4\x91",
+    /* .entropyreseed_len = */ 16,
+    /* .addtl_reseed = */ (unsigned char *)
+    "\x3e\x6b\xf4\x6f\x4d\xaa\x38\x25\xd7\x19\x4e\x69"
+    "\x4e\x77\x52\xf7",
+    /* .addtl_reseed_len = */ 16
+  }
+};
+
+
+/*
+ * Tests implement the CAVS test approach as documented in
+ * http://csrc.nist.gov/groups/STM/cavp/documents/drbg/DRBGVS.pdf
+ */
+
+/*
+ * CAVS test
+ *
+ * This function is not static as it is needed for as a private API
+ * call for the CAVS test tool.
+ */
+gpg_err_code_t
+_gcry_rngdrbg_cavs_test (struct gcry_drbg_test_vector *test, unsigned char *buf)
+{
+  gpg_err_code_t ret = 0;
+  drbg_state_t drbg = NULL;
+  struct drbg_test_data_s test_data;
+  drbg_string_t addtl, pers, testentropy;
+  int coreref = 0;
+  int pr = 0;
+  u32 flags;
+
+  ret = parse_flag_string (test->flagstr, &flags);
+  if (ret)
+    goto outbuf;
+
+  ret = drbg_algo_available (flags, &coreref);
+  if (ret)
+    goto outbuf;
+
+  drbg = xtrycalloc_secure (1, sizeof *drbg);
+  if (!drbg)
+    {
+      ret = gpg_err_code_from_syserror ();
+      goto outbuf;
+    }
+
+  if ((flags & DRBG_PREDICTION_RESIST))
+    pr = 1;
+
+  test_data.testentropy = &testentropy;
+  drbg_string_fill (&testentropy, test->entropy, test->entropylen);
+  drbg->test_data = &test_data;
+  drbg_string_fill (&pers, test->pers, test->perslen);
+  ret = drbg_instantiate (drbg, &pers, coreref, pr);
+  if (ret)
+    goto outbuf;
+
+  if (test->entropyreseed)
+    {
+      drbg_string_fill (&testentropy, test->entropyreseed,
+                            test->entropyreseed_len);
+      drbg_string_fill (&addtl, test->addtl_reseed,
+                            test->addtl_reseed_len);
+      if (drbg_reseed (drbg, &addtl))
+       goto outbuf;
+    }
+
+  drbg_string_fill (&addtl, test->addtla, test->addtllen);
+  if (test->entpra)
+    {
+      drbg_string_fill (&testentropy, test->entpra, test->entprlen);
+      drbg->test_data = &test_data;
+    }
+  drbg_generate_long (drbg, buf, test->expectedlen, &addtl);
+
+  drbg_string_fill (&addtl, test->addtlb, test->addtllen);
+  if (test->entprb)
+    {
+      drbg_string_fill (&testentropy, test->entprb, test->entprlen);
+      drbg->test_data = &test_data;
+    }
+  drbg_generate_long (drbg, buf, test->expectedlen, &addtl);
+  drbg_uninstantiate (drbg);
+
+ outbuf:
+  xfree (drbg);
+  return ret;
+}
+
+/*
+ * Invoke the CAVS test and perform the final check whether the
+ * calculated random value matches the expected one.
+ *
+ * This function is not static as it is needed for as a private API
+ * call for the CAVS test tool.
+ */
+gpg_err_code_t
+_gcry_rngdrbg_healthcheck_one (struct gcry_drbg_test_vector * test)
+{
+  gpg_err_code_t ret = GPG_ERR_ENOMEM;
+  unsigned char *buf = xcalloc_secure (1, test->expectedlen);
+  if (!buf)
+    return GPG_ERR_ENOMEM;
+
+  ret = _gcry_rngdrbg_cavs_test (test, buf);
+  /* FIXME: The next line is wrong.   */
+  ret = memcmp (test->expected, buf, test->expectedlen);
+
+  xfree (buf);
+  return ret;
+}
+
+/*
+ * Tests as defined in 11.3.2 in addition to the cipher tests: testing
+ * of the error handling.
+ *
+ * Note, testing the reseed counter is not done as an automatic reseeding
+ * is performed in drbg_generate when the reseed counter is too large.
+ */
+static gpg_err_code_t
+drbg_healthcheck_sanity (struct gcry_drbg_test_vector *test)
+{
+  unsigned int len = 0;
+  drbg_state_t drbg = NULL;
+  gpg_err_code_t ret = GPG_ERR_GENERAL;
+  gpg_err_code_t tmpret = GPG_ERR_GENERAL;
+  struct drbg_test_data_s test_data;
+  drbg_string_t addtl, testentropy;
+  int coreref = 0;
+  unsigned char *buf = NULL;
+  size_t max_addtllen, max_request_bytes;
+  u32 flags;
+
+  /* only perform test in FIPS mode */
+  if (0 == fips_mode ())
+    return 0;
+
+  ret = parse_flag_string (test->flagstr, &flags);
+  if (ret)
+    return ret;
+  ret = GPG_ERR_GENERAL; /* Fixme: Improve handling of RET.  */
+
+  buf = xtrycalloc_secure (1, test->expectedlen);
+  if (!buf)
+    return gpg_err_code_from_syserror ();
+  tmpret = drbg_algo_available (flags, &coreref);
+  if (tmpret)
+    goto outbuf;
+  drbg = xtrycalloc_secure (1, sizeof *drbg);
+  if (!drbg)
+    {
+      ret = gpg_err_code_from_syserror ();
+      goto outbuf;
+    }
+
+  /* if the following tests fail, it is likely that there is a buffer
+   * overflow and we get a SIGSEV */
+  ret = drbg_instantiate (drbg, NULL, coreref, 1);
+  if (ret)
+    goto outbuf;
+  max_addtllen = drbg_max_addtl ();
+  max_request_bytes = drbg_max_request_bytes ();
+  /* overflow addtllen with additonal info string */
+  drbg_string_fill (&addtl, test->addtla, (max_addtllen + 1));
+  len = drbg_generate (drbg, buf, test->expectedlen, &addtl);
+  if (len)
+    goto outdrbg;
+
+  /* overflow max_bits */
+  len = drbg_generate (drbg, buf, (max_request_bytes + 1), NULL);
+  if (len)
+    goto outdrbg;
+  drbg_uninstantiate (drbg);
+
+  /* test failing entropy source as defined in 11.3.2 */
+  test_data.testentropy = NULL;
+  test_data.fail_seed_source = 1;
+  drbg->test_data = &test_data;
+  tmpret = drbg_instantiate (drbg, NULL, coreref, 0);
+  if (!tmpret)
+    goto outdrbg;
+  test_data.fail_seed_source = 0;
+
+  test_data.testentropy = &testentropy;
+  drbg_string_fill (&testentropy, test->entropy, test->entropylen);
+  /* overflow max addtllen with personalization string */
+  tmpret = drbg_instantiate (drbg, &addtl, coreref, 0);
+  if (!tmpret)
+    goto outdrbg;
+
+  dbg (("DRBG: Sanity tests for failure code paths successfully completed\n"));
+  ret = 0;
+
+ outdrbg:
+  drbg_uninstantiate (drbg);
+ outbuf:
+  xfree (buf);
+  xfree (drbg);
+  return ret;
+}
+
+/*
+ * DRBG Healthcheck function as required in SP800-90A
+ *
+ * return:
+ *     0 on success (all tests pass)
+ *     >0 on error (return code indicate the number of failures)
+ */
+static int
+drbg_healthcheck (void)
+{
+  int ret = 0;
+  ret += _gcry_rngdrbg_healthcheck_one (&drbg_test_nopr[0]);
+  ret += _gcry_rngdrbg_healthcheck_one (&drbg_test_nopr[1]);
+  ret += _gcry_rngdrbg_healthcheck_one (&drbg_test_nopr[2]);
+  ret += _gcry_rngdrbg_healthcheck_one (&drbg_test_nopr[3]);
+  ret += _gcry_rngdrbg_healthcheck_one (&drbg_test_nopr[4]);
+  ret += _gcry_rngdrbg_healthcheck_one (&drbg_test_pr[0]);
+  ret += _gcry_rngdrbg_healthcheck_one (&drbg_test_pr[1]);
+  ret += _gcry_rngdrbg_healthcheck_one (&drbg_test_pr[2]);
+  ret += drbg_healthcheck_sanity (&drbg_test_nopr[0]);
+  return ret;
+}
+
+/* Run the self-tests.  */
+gcry_error_t
+_gcry_rngdrbg_selftest (selftest_report_func_t report)
+{
+  gcry_err_code_t ec;
+  const char *errtxt = NULL;
+  drbg_lock ();
+  if (0 != drbg_healthcheck ())
+    errtxt = "RNG output does not match known value";
+  drbg_unlock ();
+  if (report && errtxt)
+    report ("random", 0, "KAT", errtxt);
+  ec = errtxt ? GPG_ERR_SELFTEST_FAILED : 0;
+  return gpg_error (ec);
+}
+
+/***************************************************************
+ * Cipher invocations requested by DRBG
+ ***************************************************************/
+
+static gpg_err_code_t
+drbg_hmac (drbg_state_t drbg, const unsigned char *key,
+               unsigned char *outval, const drbg_string_t *buf)
+{
+  gpg_error_t err;
+  gcry_md_hd_t hd;
+
+  if (key)
+    {
+      err =
+       _gcry_md_open (&hd, drbg->core->backend_cipher, GCRY_MD_FLAG_HMAC);
+      if (err)
+       return err;
+      err = _gcry_md_setkey (hd, key, drbg_statelen (drbg));
+      if (err)
+       return err;
+    }
+  else
+    {
+      err = _gcry_md_open (&hd, drbg->core->backend_cipher, 0);
+      if (err)
+       return err;
+    }
+  for (; NULL != buf; buf = buf->next)
+    _gcry_md_write (hd, buf->buf, buf->len);
+  _gcry_md_final (hd);
+  memcpy (outval, _gcry_md_read (hd, drbg->core->backend_cipher),
+         drbg_blocklen (drbg));
+  _gcry_md_close (hd);
+  return 0;
+}
+
+static gpg_err_code_t
+drbg_sym (drbg_state_t drbg, const unsigned char *key,
+          unsigned char *outval, const drbg_string_t *buf)
+{
+  gpg_error_t err;
+  gcry_cipher_hd_t hd;
+
+  err = _gcry_cipher_open (&hd, drbg->core->backend_cipher,
+                           GCRY_CIPHER_MODE_ECB, 0);
+  if (err)
+    return err;
+  if (drbg_blocklen (drbg) !=
+      _gcry_cipher_get_algo_blklen (drbg->core->backend_cipher))
+    return -GPG_ERR_NO_ERROR;
+  if (drbg_blocklen (drbg) < buf->len)
+    return -GPG_ERR_NO_ERROR;
+  err = _gcry_cipher_setkey (hd, key, drbg_keylen (drbg));
+  if (err)
+    return err;
+  /* in is only component */
+  _gcry_cipher_encrypt (hd, outval, drbg_blocklen (drbg), buf->buf,
+                       buf->len);
+  _gcry_cipher_close (hd);
+  return 0;
+}
diff --git a/random/random-fips.c b/random/random-fips.c
deleted file mode 100644 (file)
index d00825e..0000000
+++ /dev/null
@@ -1,1129 +0,0 @@
-/* random-fips.c - FIPS style random number generator
- * Copyright (C) 2008  Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
-   The core of this deterministic random number generator is
-   implemented according to the document "NIST-Recommended Random
-   Number Generator Based on ANSI X9.31 Appendix A.2.4 Using the 3-Key
-   Triple DES and AES Algorithms" (2005-01-31).  This implementation
-   uses the AES variant.
-
-   There are 3 random context which map to the different levels of
-   random quality:
-
-   Generator                Seed and Key        Kernel entropy (init/reseed)
-   ------------------------------------------------------------
-   GCRY_VERY_STRONG_RANDOM  /dev/random         256/128 bits
-   GCRY_STRONG_RANDOM       /dev/random         256/128 bits
-   gcry_create_nonce        GCRY_STRONG_RANDOM  n/a
-
-   All random generators return their data in 128 bit blocks.  If the
-   caller requested less bits, the extra bits are not used.  The key
-   for each generator is only set once at the first time a generator
-   is used.  The seed value is set with the key and again after 1000
-   (SEED_TTL) output blocks; the re-seeding is disabled in test mode.
-
-   The GCRY_VERY_STRONG_RANDOM and GCRY_STRONG_RANDOM generators are
-   keyed and seeded from the /dev/random device.  Thus these
-   generators may block until the kernel has collected enough entropy.
-
-   The gcry_create_nonce generator is keyed and seeded from the
-   GCRY_STRONG_RANDOM generator.  It may also block if the
-   GCRY_STRONG_RANDOM generator has not yet been used before and thus
-   gets initialized on the first use by gcry_create_nonce.  This
-   special treatment is justified by the weaker requirements for a
-   nonce generator and to save precious kernel entropy for use by the
-   real random generators.
-
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <unistd.h>
-#ifdef HAVE_GETTIMEOFDAY
-#include <sys/time.h>
-#endif
-
-#include "g10lib.h"
-#include "random.h"
-#include "rand-internal.h"
-#include "ath.h"
-
-/* This is the lock we use to serialize access to this RNG.  The extra
-   integer variable is only used to check the locking state; that is,
-   it is not meant to be thread-safe but merely as a failsafe feature
-   to assert proper locking.  */
-static ath_mutex_t fips_rng_lock;
-static int fips_rng_is_locked;
-
-
-/* The required size for the temporary buffer of the x931_aes_driver
-   function and the buffer itself which will be allocated in secure
-   memory.  This needs to be global variable for proper initialization
-   and to allow shutting down the RNG without leaking memory.  May
-   only be used while holding the FIPS_RNG_LOCK.
-
-   This variable is also used to avoid duplicate initialization.  */
-#define TEMPVALUE_FOR_X931_AES_DRIVER_SIZE 48
-static unsigned char *tempvalue_for_x931_aes_driver;
-
-
-/* After having retrieved this number of blocks from the RNG, we want
-   to do a reseeding.  */
-#define SEED_TTL 1000
-
-
-/* The length of the key we use:  16 bytes (128 bit) for AES128.  */
-#define X931_AES_KEYLEN  16
-/* A global buffer used to communicate between the x931_generate_key
-   and x931_generate_seed functions and the entropy_collect_cb
-   function.  It may only be used by these functions. */
-static unsigned char *entropy_collect_buffer;  /* Buffer.  */
-static size_t entropy_collect_buffer_len;      /* Used length.  */
-static size_t entropy_collect_buffer_size;     /* Allocated length.  */
-
-
-/* This random context type is used to track properties of one random
-   generator. Thee context are usually allocated in secure memory so
-   that the seed value is well protected.  There are a couble of guard
-   fields to help detecting applications accidently overwriting parts
-   of the memory. */
-struct rng_context
-{
-  unsigned char guard_0[1];
-
-  /* The handle of the cipher used by the RNG.  If this one is not
-     NULL a cipher handle along with a random key has been
-     established.  */
-  gcry_cipher_hd_t cipher_hd;
-
-  /* If this flag is true, the SEED_V buffer below carries a valid
-     seed.  */
-  int is_seeded:1;
-
-  /* The very first block generated is used to compare the result
-     against the last result.  This flag indicates that such a block
-     is available.  */
-  int compare_value_valid:1;
-
-  /* A counter used to trigger re-seeding.  */
-  unsigned int use_counter;
-
-  unsigned char guard_1[1];
-
-  /* The buffer containing the seed value V.  */
-  unsigned char seed_V[16];
-
-  unsigned char guard_2[1];
-
-  /* The last result from the x931_aes function.  Only valid if
-     compare_value_valid is set.  */
-  unsigned char compare_value[16];
-
-  unsigned char guard_3[1];
-
-  /* The external test may want to suppress the duplicate bock check.
-     This is done if the this flag is set.  */
-  unsigned char test_no_dup_check;
-  /* To implement a KAT we need to provide a know DT value.  To
-     accomplish this the x931_get_dt function checks whether this
-     field is not NULL and then uses the 16 bytes at this address for
-     the DT value.  However the last 4 bytes are replaced by the
-     value of field TEST_DT_COUNTER which will be incremented after
-     each invocation of x931_get_dt. We use a pointer and not a buffer
-     because there is no need to put this value into secure memory.  */
-  const unsigned char *test_dt_ptr;
-  u32 test_dt_counter;
-
-  /* We need to keep track of the process which did the initialization
-     so that we can detect a fork.  The volatile modifier is required
-     so that the compiler does not optimize it away in case the getpid
-     function is badly attributed.  */
-  pid_t key_init_pid;
-  pid_t seed_init_pid;
-};
-typedef struct rng_context *rng_context_t;
-
-
-/* The random context used for the nonce generator.  May only be used
-   while holding the FIPS_RNG_LOCK.  */
-static rng_context_t nonce_context;
-/* The random context used for the standard random generator.  May
-   only be used while holding the FIPS_RNG_LOCK.  */
-static rng_context_t std_rng_context;
-/* The random context used for the very strong random generator.  May
-   only be used while holding the FIPS_RNG_LOCK.  */
-static rng_context_t strong_rng_context;
-
-
-/* --- Local prototypes ---  */
-static void x931_reseed (rng_context_t rng_ctx);
-static void get_random (void *buffer, size_t length, rng_context_t rng_ctx);
-
-
-
-\f
-/* --- Functions  --- */
-
-/* Basic initialization is required to initialize mutexes and
-   do a few checks on the implementation.  */
-static void
-basic_initialization (void)
-{
-  static int initialized;
-  int my_errno;
-
-  if (initialized)
-    return;
-  initialized = 1;
-
-  my_errno = ath_mutex_init (&fips_rng_lock);
-  if (my_errno)
-    log_fatal ("failed to create the RNG lock: %s\n", strerror (my_errno));
-  fips_rng_is_locked = 0;
-
-  /* Make sure that we are still using the values we have
-     traditionally used for the random levels.  */
-  gcry_assert (GCRY_WEAK_RANDOM == 0
-               && GCRY_STRONG_RANDOM == 1
-               && GCRY_VERY_STRONG_RANDOM == 2);
-
-}
-
-
-/* Acquire the fips_rng_lock.  */
-static void
-lock_rng (void)
-{
-  int my_errno;
-
-  my_errno = ath_mutex_lock (&fips_rng_lock);
-  if (my_errno)
-    log_fatal ("failed to acquire the RNG lock: %s\n", strerror (my_errno));
-  fips_rng_is_locked = 1;
-}
-
-
-/* Release the fips_rng_lock.  */
-static void
-unlock_rng (void)
-{
-  int my_errno;
-
-  fips_rng_is_locked = 0;
-  my_errno = ath_mutex_unlock (&fips_rng_lock);
-  if (my_errno)
-    log_fatal ("failed to release the RNG lock: %s\n", strerror (my_errno));
-}
-
-static void
-setup_guards (rng_context_t rng_ctx)
-{
-  /* Set the guards to some arbitrary values.  */
-  rng_ctx->guard_0[0] = 17;
-  rng_ctx->guard_1[0] = 42;
-  rng_ctx->guard_2[0] = 137;
-  rng_ctx->guard_3[0] = 252;
-}
-
-static void
-check_guards (rng_context_t rng_ctx)
-{
-  if ( rng_ctx->guard_0[0] != 17
-       || rng_ctx->guard_1[0] != 42
-       || rng_ctx->guard_2[0] != 137
-       || rng_ctx->guard_3[0] != 252 )
-    log_fatal ("memory corruption detected in RNG context %p\n", rng_ctx);
-}
-
-
-/* Get the DT vector for use with the core PRNG function.  Buffer
-   needs to be provided by the caller with a size of at least LENGTH
-   bytes. RNG_CTX needs to be passed to allow for a KAT.  The 16 byte
-   timestamp we construct is made up the real time and three counters:
-
-   Buffer:       00112233445566778899AABBCCDDEEFF
-                 !--+---!!-+-!!+!!--+---!!--+---!
-   seconds ---------/      |   |    |       |
-   microseconds -----------/   |    |       |
-   counter2 -------------------/    |       |
-   counter1 ------------------------/       |
-   counter0 --------------------------------/
-
-   Counter 2 is just 12 bits wide and used to track fractions of
-   milliseconds whereas counters 1 and 0 are combined to a free
-   running 64 bit counter.  */
-static void
-x931_get_dt (unsigned char *buffer, size_t length, rng_context_t rng_ctx)
-{
-  gcry_assert (length == 16); /* This length is required for use with AES.  */
-  gcry_assert (fips_rng_is_locked);
-
-  /* If the random context indicates that a test DT should be used,
-     take the DT value from the context.  For safety reasons we do
-     this only if the context is not one of the regular contexts.  */
-  if (rng_ctx->test_dt_ptr
-      && rng_ctx != nonce_context
-      && rng_ctx != std_rng_context
-      && rng_ctx != strong_rng_context)
-    {
-      memcpy (buffer, rng_ctx->test_dt_ptr, 16);
-      buffer[12] = (rng_ctx->test_dt_counter >> 24);
-      buffer[13] = (rng_ctx->test_dt_counter >> 16);
-      buffer[14] = (rng_ctx->test_dt_counter >> 8);
-      buffer[15] = rng_ctx->test_dt_counter;
-      rng_ctx->test_dt_counter++;
-      return;
-    }
-
-
-#if HAVE_GETTIMEOFDAY
-  {
-    static u32 last_sec, last_usec;
-    static u32 counter1, counter0;
-    static u16 counter2;
-
-    unsigned int usec;
-    struct timeval tv;
-
-    if (!last_sec)
-      {
-        /* This is the very first time we are called: Set the counters
-           to an not so easy predictable value to avoid always
-           starting at 0.  Not really needed but it doesn't harm.  */
-        counter1 = (u32)getpid ();
-#ifndef HAVE_W32_SYSTEM
-        counter0 = (u32)getppid ();
-#endif
-      }
-
-
-    if (gettimeofday (&tv, NULL))
-      log_fatal ("gettimeofday() failed: %s\n", strerror (errno));
-
-    /* The microseconds part is always less than 1 millon (0x0f4240).
-       Thus we don't care about the MSB and in addition shift it to
-       the left by 4 bits.  */
-    usec = tv.tv_usec;
-    usec <<= 4;
-    /* If we got the same time as by the last invocation, bump up
-       counter2 and save the time for the next invocation.  */
-    if (tv.tv_sec == last_sec && usec == last_usec)
-      {
-        counter2++;
-        counter2 &= 0x0fff;
-      }
-    else
-      {
-        counter2 = 0;
-        last_sec = tv.tv_sec;
-        last_usec = usec;
-      }
-    /* Fill the buffer with the timestamp.  */
-    buffer[0] = ((tv.tv_sec >> 24) & 0xff);
-    buffer[1] = ((tv.tv_sec >> 16) & 0xff);
-    buffer[2] = ((tv.tv_sec >> 8) & 0xff);
-    buffer[3] = (tv.tv_sec & 0xff);
-    buffer[4] = ((usec >> 16) & 0xff);
-    buffer[5] = ((usec >> 8) & 0xff);
-    buffer[6] = ((usec & 0xf0) | ((counter2 >> 8) & 0x0f));
-    buffer[7] = (counter2 & 0xff);
-    /* Add the free running counter.  */
-    buffer[8]  = ((counter1 >> 24) & 0xff);
-    buffer[9]  = ((counter1 >> 16) & 0xff);
-    buffer[10] = ((counter1 >> 8) & 0xff);
-    buffer[11] = ((counter1) & 0xff);
-    buffer[12] = ((counter0 >> 24) & 0xff);
-    buffer[13] = ((counter0 >> 16) & 0xff);
-    buffer[14] = ((counter0 >> 8) & 0xff);
-    buffer[15] = ((counter0) & 0xff);
-    /* Bump up that counter.  */
-    if (!++counter0)
-      ++counter1;
-  }
-#else
-  log_fatal ("gettimeofday() not available on this system\n");
-#endif
-
-  /* log_printhex ("x931_get_dt: ", buffer, 16); */
-}
-
-
-/* XOR the buffers A and B which are each of LENGTH bytes and store
-   the result at R.  R needs to be provided by the caller with a size
-   of at least LENGTH bytes.  */
-static void
-xor_buffer (unsigned char *r,
-            const unsigned char *a, const unsigned char *b, size_t length)
-{
-  for ( ; length; length--, a++, b++, r++)
-    *r = (*a ^ *b);
-}
-
-
-/* Encrypt LENGTH bytes of INPUT to OUTPUT using KEY.  LENGTH
-   needs to be 16. */
-static void
-encrypt_aes (gcry_cipher_hd_t key,
-             unsigned char *output, const unsigned char *input, size_t length)
-{
-  gpg_error_t err;
-
-  gcry_assert (length == 16);
-
-  err = _gcry_cipher_encrypt (key, output, length, input, length);
-  if (err)
-    log_fatal ("AES encryption in RNG failed: %s\n", _gcry_strerror (err));
-}
-
-
-/* The core ANSI X9.31, Appendix A.2.4 function using AES.  The caller
-   needs to pass a 16 byte buffer for the result, the 16 byte
-   datetime_DT value and the 16 byte seed value V.  The caller also
-   needs to pass an appropriate KEY and make sure to pass a valid
-   seed_V.  The caller also needs to provide two 16 bytes buffer for
-   intermediate results, they may be reused by the caller later.
-
-   On return the result is stored at RESULT_R and the SEED_V is
-   updated.  May only be used while holding the lock.  */
-static void
-x931_aes (unsigned char result_R[16],
-          unsigned char datetime_DT[16], unsigned char seed_V[16],
-          gcry_cipher_hd_t key,
-          unsigned char intermediate_I[16], unsigned char temp_xor[16])
-{
-  /* Let ede*X(Y) represent the AES encryption of Y under the key *X.
-
-     Let V be a 128-bit seed value which is also kept secret, and XOR
-     be the exclusive-or operator. Let DT be a date/time vector which
-     is updated on each iteration. I is a intermediate value.
-
-     I = ede*K(DT)  */
-  encrypt_aes (key, intermediate_I, datetime_DT, 16);
-
-  /* R = ede*K(I XOR V) */
-  xor_buffer (temp_xor, intermediate_I, seed_V, 16);
-  encrypt_aes (key, result_R, temp_xor, 16);
-
-  /* V = ede*K(R XOR I).  */
-  xor_buffer (temp_xor, result_R, intermediate_I, 16);
-  encrypt_aes (key, seed_V, temp_xor, 16);
-
-  /* Zero out temporary values.  */
-  wipememory (intermediate_I, 16);
-  wipememory (temp_xor, 16);
-}
-
-
-/* The high level driver to x931_aes.  This one does the required
-   tests and calls the core function until the entire buffer has been
-   filled.  OUTPUT is a caller provided buffer of LENGTH bytes to
-   receive the random, RNG_CTX is the context of the RNG.  The context
-   must be properly initialized.  Returns 0 on success. */
-static int
-x931_aes_driver (unsigned char *output, size_t length, rng_context_t rng_ctx)
-{
-  unsigned char datetime_DT[16];
-  unsigned char *intermediate_I, *temp_buffer, *result_buffer;
-  size_t nbytes;
-
-  gcry_assert (fips_rng_is_locked);
-  gcry_assert (rng_ctx->cipher_hd);
-  gcry_assert (rng_ctx->is_seeded);
-
-  gcry_assert (tempvalue_for_x931_aes_driver);
-  gcry_assert (TEMPVALUE_FOR_X931_AES_DRIVER_SIZE == 48);
-  intermediate_I = tempvalue_for_x931_aes_driver;
-  temp_buffer    = tempvalue_for_x931_aes_driver + 16;
-  result_buffer  = tempvalue_for_x931_aes_driver + 32;
-
-  while (length)
-    {
-      /* Unless we are running with a test context, we require a new
-         seed after some time.  */
-      if (!rng_ctx->test_dt_ptr && rng_ctx->use_counter > SEED_TTL)
-        {
-          x931_reseed (rng_ctx);
-          rng_ctx->use_counter = 0;
-        }
-
-      /* Due to the design of the RNG, we always receive 16 bytes (128
-         bit) of random even if we require less.  The extra bytes
-         returned are not used.  Intheory we could save them for the
-         next invocation, but that would make the control flow harder
-         to read.  */
-      nbytes = length < 16? length : 16;
-
-      x931_get_dt (datetime_DT, 16, rng_ctx);
-      x931_aes (result_buffer,
-                datetime_DT, rng_ctx->seed_V, rng_ctx->cipher_hd,
-                intermediate_I, temp_buffer);
-      rng_ctx->use_counter++;
-
-      if (rng_ctx->test_no_dup_check
-          && rng_ctx->test_dt_ptr
-          && rng_ctx != nonce_context
-          && rng_ctx != std_rng_context
-          && rng_ctx != strong_rng_context)
-        {
-          /* This is a test context which does not want the duplicate
-             block check. */
-        }
-      else
-        {
-          /* Do a basic check on the output to avoid a stuck generator.  */
-          if (!rng_ctx->compare_value_valid)
-            {
-              /* First time used, only save the result.  */
-              memcpy (rng_ctx->compare_value, result_buffer, 16);
-              rng_ctx->compare_value_valid = 1;
-              continue;
-            }
-          if (!memcmp (rng_ctx->compare_value, result_buffer, 16))
-            {
-              /* Ooops, we received the same 128 bit block - that should
-                 in theory never happen.  The FIPS requirement says that
-                 we need to put ourself into the error state in such
-                 case.  */
-              fips_signal_error ("duplicate 128 bit block returned by RNG");
-              return -1;
-            }
-          memcpy (rng_ctx->compare_value, result_buffer, 16);
-        }
-
-      /* Append to outbut.  */
-      memcpy (output, result_buffer, nbytes);
-      wipememory (result_buffer, 16);
-      output += nbytes;
-      length -= nbytes;
-    }
-
-  return 0;
-}
-
-
-/* Callback for x931_generate_key. Note that this callback uses the
-   global ENTROPY_COLLECT_BUFFER which has been setup by get_entropy.
-   ORIGIN is not used but required due to the design of entropy
-   gathering module. */
-static void
-entropy_collect_cb (const void *buffer, size_t length,
-                    enum random_origins origin)
-{
-  const unsigned char *p = buffer;
-
-  (void)origin;
-
-  gcry_assert (fips_rng_is_locked);
-  gcry_assert (entropy_collect_buffer);
-
-  /* Note that we need to protect against gatherers returning more
-     than the requested bytes (e.g. rndw32).  */
-  while (length-- && entropy_collect_buffer_len < entropy_collect_buffer_size)
-    {
-      entropy_collect_buffer[entropy_collect_buffer_len++] ^= *p++;
-    }
-}
-
-
-/* Get NBYTES of entropy from the kernel device.  The callers needs to
-   free the returned buffer.  The function either succeeds or
-   terminates the process in case of a fatal error. */
-static void *
-get_entropy (size_t nbytes)
-{
-  void *result;
-  int rc;
-
-  gcry_assert (!entropy_collect_buffer);
-  entropy_collect_buffer = xmalloc_secure (nbytes);
-  entropy_collect_buffer_size = nbytes;
-  entropy_collect_buffer_len = 0;
-
-#if USE_RNDLINUX
-  rc = _gcry_rndlinux_gather_random (entropy_collect_cb, 0,
-                                     X931_AES_KEYLEN,
-                                     GCRY_VERY_STRONG_RANDOM);
-#elif USE_RNDW32
-  do
-    {
-      rc = _gcry_rndw32_gather_random (entropy_collect_cb, 0,
-                                       X931_AES_KEYLEN,
-                                       GCRY_VERY_STRONG_RANDOM);
-    }
-  while (rc >= 0 && entropy_collect_buffer_len < entropy_collect_buffer_size);
-#else
-  rc = -1;
-#endif
-
-  if (rc < 0 || entropy_collect_buffer_len != entropy_collect_buffer_size)
-    {
-      xfree (entropy_collect_buffer);
-      entropy_collect_buffer = NULL;
-      log_fatal ("error getting entropy data\n");
-    }
-  result = entropy_collect_buffer;
-  entropy_collect_buffer = NULL;
-  return result;
-}
-
-
-/* Generate a key for use with x931_aes.  The function returns a
-   handle to the cipher context readily prepared for ECB encryption.
-   If FOR_NONCE is true, the key is retrieved by readong random from
-   the standard generator.  On error NULL is returned.  */
-static gcry_cipher_hd_t
-x931_generate_key (int for_nonce)
-{
-  gcry_cipher_hd_t hd;
-  gpg_err_code_t rc;
-  void *buffer;
-
-  gcry_assert (fips_rng_is_locked);
-
-  /* Allocate a cipher context.  */
-  rc = _gcry_cipher_open (&hd, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB,
-                          GCRY_CIPHER_SECURE);
-  if (rc)
-    {
-      log_error ("error creating cipher context for RNG: %s\n",
-                 _gcry_strerror (rc));
-      return NULL;
-    }
-
-  /* Get a key from the standard RNG or from the entropy source.  */
-  if (for_nonce)
-    {
-      buffer = xmalloc (X931_AES_KEYLEN);
-      get_random (buffer, X931_AES_KEYLEN, std_rng_context);
-    }
-  else
-    {
-      buffer = get_entropy (X931_AES_KEYLEN);
-    }
-
-  /* Set the key and delete the buffer because the key is now part of
-     the cipher context.  */
-  rc = _gcry_cipher_setkey (hd, buffer, X931_AES_KEYLEN);
-  wipememory (buffer, X931_AES_KEYLEN);
-  xfree (buffer);
-  if (rc)
-    {
-      log_error ("error creating key for RNG: %s\n", _gcry_strerror (rc));
-      _gcry_cipher_close (hd);
-      return NULL;
-    }
-
-  return hd;
-}
-
-
-/* Generate a key for use with x931_aes.  The function copies a seed
-   of LENGTH bytes into SEED_BUFFER. LENGTH needs to by given as 16.  */
-static void
-x931_generate_seed (unsigned char *seed_buffer, size_t length)
-{
-  void *buffer;
-
-  gcry_assert (fips_rng_is_locked);
-  gcry_assert (length == 16);
-
-  buffer = get_entropy (X931_AES_KEYLEN);
-
-  memcpy (seed_buffer, buffer, X931_AES_KEYLEN);
-  wipememory (buffer, X931_AES_KEYLEN);
-  xfree (buffer);
-}
-
-
-
-/* Reseed a generator.  This is also used for the initial seeding. */
-static void
-x931_reseed (rng_context_t rng_ctx)
-{
-  gcry_assert (fips_rng_is_locked);
-
-  if (rng_ctx == nonce_context)
-    {
-      /* The nonce context is special.  It will be seeded using the
-         standard random generator.  */
-      get_random (rng_ctx->seed_V, 16, std_rng_context);
-      rng_ctx->is_seeded = 1;
-      rng_ctx->seed_init_pid = getpid ();
-    }
-  else
-    {
-      /* The other two generators are seeded from /dev/random.  */
-      x931_generate_seed (rng_ctx->seed_V, 16);
-      rng_ctx->is_seeded = 1;
-      rng_ctx->seed_init_pid = getpid ();
-    }
-}
-
-
-/* Core random function.  This is used for both nonce and random
-   generator.  The actual RNG to be used depends on the random context
-   RNG_CTX passed.  Note that this function is called with the RNG not
-   yet locked.  */
-static void
-get_random (void *buffer, size_t length, rng_context_t rng_ctx)
-{
-  gcry_assert (buffer);
-  gcry_assert (rng_ctx);
-
-  check_guards (rng_ctx);
-
-  /* Initialize the cipher handle and thus setup the key if needed.  */
-  if (!rng_ctx->cipher_hd)
-    {
-      if (rng_ctx == nonce_context)
-        rng_ctx->cipher_hd = x931_generate_key (1);
-      else
-        rng_ctx->cipher_hd = x931_generate_key (0);
-      if (!rng_ctx->cipher_hd)
-        goto bailout;
-      rng_ctx->key_init_pid = getpid ();
-    }
-
-  /* Initialize the seed value if needed.  */
-  if (!rng_ctx->is_seeded)
-    x931_reseed (rng_ctx);
-
-  if (rng_ctx->key_init_pid != getpid ()
-      || rng_ctx->seed_init_pid != getpid ())
-    {
-      /* We are in a child of us.  Because we have no way yet to do
-         proper re-initialization (including self-checks etc), the
-         only chance we have is to bail out.  Obviusly a fork/exec
-         won't harm because the exec overwrites the old image. */
-      fips_signal_error ("fork without proper re-initialization "
-                         "detected in RNG");
-      goto bailout;
-    }
-
-  if (x931_aes_driver (buffer, length, rng_ctx))
-    goto bailout;
-
-  check_guards (rng_ctx);
-  return;
-
- bailout:
-  log_fatal ("severe error getting random\n");
-  /*NOTREACHED*/
-}
-
-
-\f
-/* --- Public Functions --- */
-
-/* Initialize this random subsystem.  If FULL is false, this function
-   merely calls the basic initialization of the module and does not do
-   anything more.  Doing this is not really required but when running
-   in a threaded environment we might get a race condition
-   otherwise. */
-void
-_gcry_rngfips_initialize (int full)
-{
-  basic_initialization ();
-  if (!full)
-    return;
-
-  /* Allocate temporary buffers.  If that buffer already exists we
-     know that we are already initialized.  */
-  lock_rng ();
-  if (!tempvalue_for_x931_aes_driver)
-    {
-      tempvalue_for_x931_aes_driver
-        = xmalloc_secure (TEMPVALUE_FOR_X931_AES_DRIVER_SIZE);
-
-      /* Allocate the random contexts.  Note that we do not need to use
-         secure memory for the nonce context.  */
-      nonce_context = xcalloc (1, sizeof *nonce_context);
-      setup_guards (nonce_context);
-
-      std_rng_context = xcalloc_secure (1, sizeof *std_rng_context);
-      setup_guards (std_rng_context);
-
-      strong_rng_context = xcalloc_secure (1, sizeof *strong_rng_context);
-      setup_guards (strong_rng_context);
-    }
-  else
-    {
-      /* Already initialized. Do some sanity checks.  */
-      gcry_assert (!nonce_context->test_dt_ptr);
-      gcry_assert (!std_rng_context->test_dt_ptr);
-      gcry_assert (!strong_rng_context->test_dt_ptr);
-      check_guards (nonce_context);
-      check_guards (std_rng_context);
-      check_guards (strong_rng_context);
-    }
-  unlock_rng ();
-}
-
-
-/* Try to close the FDs of the random gather module.  This is
-   currently only implemented for rndlinux. */
-void
-_gcry_rngfips_close_fds (void)
-{
-  lock_rng ();
-#if USE_RNDLINUX
-  _gcry_rndlinux_gather_random (NULL, 0, 0, 0);
-#endif
-  unlock_rng ();
-}
-
-
-/* Print some statistics about the RNG.  */
-void
-_gcry_rngfips_dump_stats (void)
-{
-  /* Not yet implemented.  */
-}
-
-
-/* This function returns true if no real RNG is available or the
-   quality of the RNG has been degraded for test purposes.  */
-int
-_gcry_rngfips_is_faked (void)
-{
-  return 0;  /* Faked random is not allowed.  */
-}
-
-
-/* Add BUFLEN bytes from BUF to the internal random pool.  QUALITY
-   should be in the range of 0..100 to indicate the goodness of the
-   entropy added, or -1 for goodness not known. */
-gcry_error_t
-_gcry_rngfips_add_bytes (const void *buf, size_t buflen, int quality)
-{
-  (void)buf;
-  (void)buflen;
-  (void)quality;
-  return 0;  /* Not implemented. */
-}
-
-
-/* Public function to fill the buffer with LENGTH bytes of
-   cryptographically strong random bytes.  Level GCRY_WEAK_RANDOM is
-   here mapped to GCRY_STRONG_RANDOM, GCRY_STRONG_RANDOM is strong
-   enough for most usage, GCRY_VERY_STRONG_RANDOM is good for key
-   generation stuff but may be very slow.  */
-void
-_gcry_rngfips_randomize (void *buffer, size_t length,
-                         enum gcry_random_level level)
-{
-  _gcry_rngfips_initialize (1);  /* Auto-initialize if needed.  */
-
-  lock_rng ();
-  if (level == GCRY_VERY_STRONG_RANDOM)
-    get_random (buffer, length, strong_rng_context);
-  else
-    get_random (buffer, length, std_rng_context);
-  unlock_rng ();
-}
-
-
-/* Create an unpredicable nonce of LENGTH bytes in BUFFER. */
-void
-_gcry_rngfips_create_nonce (void *buffer, size_t length)
-{
-  _gcry_rngfips_initialize (1);  /* Auto-initialize if needed.  */
-
-  lock_rng ();
-  get_random (buffer, length, nonce_context);
-  unlock_rng ();
-}
-
-
-/* Run a Know-Answer-Test using a dedicated test context.  Note that
-   we can't use the samples from the NISR RNGVS document because they
-   don't take the requirement to throw away the first block and use
-   that for duplicate check in account.  Thus we made up our own test
-   vectors. */
-static gcry_err_code_t
-selftest_kat (selftest_report_func_t report)
-{
-  static struct
-  {
-    const unsigned char key[16];
-    const unsigned char dt[16];
-    const unsigned char v[16];
-    const unsigned char r[3][16];
-  } tv[] =
-    {
-      { { 0xb9, 0xca, 0x7f, 0xd6, 0xa0, 0xf5, 0xd3, 0x42,
-          0x19, 0x6d, 0x84, 0x91, 0x76, 0x1c, 0x3b, 0xbe },
-        { 0x48, 0xb2, 0x82, 0x98, 0x68, 0xc2, 0x80, 0x00,
-          0x00, 0x00, 0x28, 0x18, 0x00, 0x00, 0x25, 0x00 },
-        { 0x52, 0x17, 0x8d, 0x29, 0xa2, 0xd5, 0x84, 0x12,
-          0x9d, 0x89, 0x9a, 0x45, 0x82, 0x02, 0xf7, 0x77 },
-        { { 0x42, 0x9c, 0x08, 0x3d, 0x82, 0xf4, 0x8a, 0x40,
-            0x66, 0xb5, 0x49, 0x27, 0xab, 0x42, 0xc7, 0xc3 },
-          { 0x0e, 0xb7, 0x61, 0x3c, 0xfe, 0xb0, 0xbe, 0x73,
-            0xf7, 0x6e, 0x6d, 0x6f, 0x1d, 0xa3, 0x14, 0xfa },
-          { 0xbb, 0x4b, 0xc1, 0x0e, 0xc5, 0xfb, 0xcd, 0x46,
-            0xbe, 0x28, 0x61, 0xe7, 0x03, 0x2b, 0x37, 0x7d } } },
-      { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
-        { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
-        { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
-        { { 0xf7, 0x95, 0xbd, 0x4a, 0x52, 0xe2, 0x9e, 0xd7,
-            0x13, 0xd3, 0x13, 0xfa, 0x20, 0xe9, 0x8d, 0xbc },
-          { 0xc8, 0xd1, 0xe5, 0x11, 0x59, 0x52, 0xf7, 0xfa,
-            0x37, 0x38, 0xb4, 0xc5, 0xce, 0xb2, 0xb0, 0x9a },
-          { 0x0d, 0x9c, 0xc5, 0x0d, 0x16, 0xe1, 0xbc, 0xed,
-            0xcf, 0x60, 0x62, 0x09, 0x9d, 0x20, 0x83, 0x7e } } },
-      { { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-          0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
-        { 0x80, 0x00, 0x81, 0x01, 0x82, 0x02, 0x83, 0x03,
-          0xa0, 0x20, 0xa1, 0x21, 0xa2, 0x22, 0xa3, 0x23 },
-        { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
-        { { 0x96, 0xed, 0xcc, 0xc3, 0xdd, 0x04, 0x7f, 0x75,
-            0x63, 0x19, 0x37, 0x6f, 0x15, 0x22, 0x57, 0x56 },
-          { 0x7a, 0x14, 0x76, 0x77, 0x95, 0x17, 0x7e, 0xc8,
-            0x92, 0xe8, 0xdd, 0x15, 0xcb, 0x1f, 0xbc, 0xb1 },
-          { 0x25, 0x3e, 0x2e, 0xa2, 0x41, 0x1b, 0xdd, 0xf5,
-            0x21, 0x48, 0x41, 0x71, 0xb3, 0x8d, 0x2f, 0x4c } } }
-    };
-  int tvidx, ridx;
-  rng_context_t test_ctx;
-  gpg_err_code_t rc;
-  const char *errtxt = NULL;
-  unsigned char result[16];
-
-  gcry_assert (tempvalue_for_x931_aes_driver);
-
-  test_ctx = xcalloc (1, sizeof *test_ctx);
-  setup_guards (test_ctx);
-
-  lock_rng ();
-
-  for (tvidx=0; tvidx < DIM (tv); tvidx++)
-    {
-      /* Setup the key.  */
-      rc = _gcry_cipher_open (&test_ctx->cipher_hd,
-                              GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB,
-                              GCRY_CIPHER_SECURE);
-      if (rc)
-        {
-          errtxt = "error creating cipher context for RNG";
-          goto leave;
-        }
-
-      rc = _gcry_cipher_setkey (test_ctx->cipher_hd, tv[tvidx].key, 16);
-      if (rc)
-        {
-          errtxt = "error setting key for RNG";
-          goto leave;
-        }
-      test_ctx->key_init_pid = getpid ();
-
-      /* Setup the seed.  */
-      memcpy (test_ctx->seed_V, tv[tvidx].v, 16);
-      test_ctx->is_seeded = 1;
-      test_ctx->seed_init_pid = getpid ();
-
-      /* Setup a DT value.  */
-      test_ctx->test_dt_ptr = tv[tvidx].dt;
-      test_ctx->test_dt_counter = ( (tv[tvidx].dt[12] << 24)
-                                   |(tv[tvidx].dt[13] << 16)
-                                   |(tv[tvidx].dt[14] << 8)
-                                   |(tv[tvidx].dt[15]) );
-
-      /* Get and compare the first three results.  */
-      for (ridx=0; ridx < 3; ridx++)
-        {
-          /* Compute the next value.  */
-          if (x931_aes_driver (result, 16, test_ctx))
-            {
-              errtxt = "X9.31 RNG core function failed";
-              goto leave;
-            }
-
-          /* Compare it to the known value.  */
-          if (memcmp (result, tv[tvidx].r[ridx], 16))
-            {
-              /* log_printhex ("x931_aes got: ", result, 16); */
-              /* log_printhex ("x931_aes exp: ", tv[tvidx].r[ridx], 16); */
-              errtxt = "RNG output does not match known value";
-              goto leave;
-            }
-        }
-
-      /* This test is actual pretty pointless because we use a local test
-         context.  */
-      if (test_ctx->key_init_pid != getpid ()
-          || test_ctx->seed_init_pid != getpid ())
-        {
-          errtxt = "fork detection failed";
-          goto leave;
-        }
-
-      _gcry_cipher_close (test_ctx->cipher_hd);
-      test_ctx->cipher_hd = NULL;
-      test_ctx->is_seeded = 0;
-      check_guards (test_ctx);
-    }
-
- leave:
-  unlock_rng ();
-  _gcry_cipher_close (test_ctx->cipher_hd);
-  check_guards (test_ctx);
-  xfree (test_ctx);
-  if (report && errtxt)
-    report ("random", 0, "KAT", errtxt);
-  return errtxt? GPG_ERR_SELFTEST_FAILED : 0;
-}
-
-
-/* Run the self-tests.  */
-gcry_error_t
-_gcry_rngfips_selftest (selftest_report_func_t report)
-{
-  gcry_err_code_t ec;
-
-#if defined(USE_RNDLINUX) || defined(USE_RNDW32)
-  {
-    char buffer[8];
-
-    /* Do a simple test using the public interface.  This will also
-       enforce full initialization of the RNG.  We need to be fully
-       initialized due to the global requirement of the
-       tempvalue_for_x931_aes_driver stuff. */
-    _gcry_randomize (buffer, sizeof buffer, GCRY_STRONG_RANDOM);
-  }
-
-  ec = selftest_kat (report);
-
-#else /*!(USE_RNDLINUX||USE_RNDW32)*/
-  report ("random", 0, "setup", "no entropy gathering module");
-  ec = GPG_ERR_SELFTEST_FAILED;
-#endif
-  return gpg_error (ec);
-}
-
-
-/* Create a new test context for an external RNG test driver.  On
-   success the test context is stored at R_CONTEXT; on failure NULL is
-   stored at R_CONTEXT and an error code is returned.  */
-gcry_err_code_t
-_gcry_rngfips_init_external_test (void **r_context, unsigned int flags,
-                                  const void *key, size_t keylen,
-                                  const void *seed, size_t seedlen,
-                                  const void *dt, size_t dtlen)
-{
-  gpg_err_code_t rc;
-  rng_context_t test_ctx;
-
-  _gcry_rngfips_initialize (1);  /* Auto-initialize if needed.  */
-
-  if (!r_context
-      || !key  || keylen  != 16
-      || !seed || seedlen != 16
-      || !dt   || dtlen   != 16 )
-    return GPG_ERR_INV_ARG;
-
-  test_ctx = xtrycalloc (1, sizeof *test_ctx + dtlen);
-  if (!test_ctx)
-    return gpg_err_code_from_syserror ();
-  setup_guards (test_ctx);
-
-  /* Setup the key.  */
-  rc = _gcry_cipher_open (&test_ctx->cipher_hd,
-                          GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB,
-                          GCRY_CIPHER_SECURE);
-  if (rc)
-    goto leave;
-
-  rc = _gcry_cipher_setkey (test_ctx->cipher_hd, key, keylen);
-  if (rc)
-    goto leave;
-
-  test_ctx->key_init_pid = getpid ();
-
-  /* Setup the seed.  */
-  memcpy (test_ctx->seed_V, seed, seedlen);
-  test_ctx->is_seeded = 1;
-  test_ctx->seed_init_pid = getpid ();
-
-  /* Setup a DT value.  Because our context structure only stores a
-     pointer we copy the DT value to the extra space we allocated in
-     the test_ctx and set the pointer to that address.  */
-  memcpy ((unsigned char*)test_ctx + sizeof *test_ctx, dt, dtlen);
-  test_ctx->test_dt_ptr = (unsigned char*)test_ctx + sizeof *test_ctx;
-  test_ctx->test_dt_counter = ( (test_ctx->test_dt_ptr[12] << 24)
-                               |(test_ctx->test_dt_ptr[13] << 16)
-                               |(test_ctx->test_dt_ptr[14] << 8)
-                               |(test_ctx->test_dt_ptr[15]) );
-
-  if ( (flags & 1) )
-    test_ctx->test_no_dup_check = 1;
-
-  check_guards (test_ctx);
-  /* All fine.  */
-  rc = 0;
-
- leave:
-  if (rc)
-    {
-      _gcry_cipher_close (test_ctx->cipher_hd);
-      xfree (test_ctx);
-      *r_context = NULL;
-    }
-  else
-    *r_context = test_ctx;
-  return rc;
-}
-
-
-/* Get BUFLEN bytes from the RNG using the test CONTEXT and store them
-   at BUFFER.  Return 0 on success or an error code.  */
-gcry_err_code_t
-_gcry_rngfips_run_external_test (void *context, char *buffer, size_t buflen)
-{
-  rng_context_t test_ctx = context;
-
-  if (!test_ctx || !buffer || buflen != 16)
-    return GPG_ERR_INV_ARG;
-
-  lock_rng ();
-  get_random (buffer, buflen, test_ctx);
-  unlock_rng ();
-  return 0;
-}
-
-/* Release the test CONTEXT.  */
-void
-_gcry_rngfips_deinit_external_test (void *context)
-{
-  rng_context_t test_ctx = context;
-
-  if (test_ctx)
-    {
-      _gcry_cipher_close (test_ctx->cipher_hd);
-      xfree (test_ctx);
-    }
-}
index 3962ab8..8b79511 100644 (file)
 #include "g10lib.h"
 #include "random.h"
 #include "rand-internal.h"
-#include "ath.h"
 
 /* This is the lock we use to serialize access to this RNG.  The extra
    integer variable is only used to check the locking state; that is,
    it is not meant to be thread-safe but merely as a failsafe feature
    to assert proper locking.  */
-static ath_mutex_t system_rng_lock;
+GPGRT_LOCK_DEFINE (system_rng_lock);
 static int system_rng_is_locked;
 
 
@@ -58,16 +57,11 @@ static void
 basic_initialization (void)
 {
   static int initialized;
-  int my_errno;
 
   if (initialized)
     return;
   initialized = 1;
 
-  my_errno = ath_mutex_init (&system_rng_lock);
-  if (my_errno)
-    log_fatal ("failed to create the System RNG lock: %s\n",
-               strerror (my_errno));
   system_rng_is_locked = 0;
 
   /* Make sure that we are still using the values we traditionally
@@ -83,12 +77,12 @@ basic_initialization (void)
 static void
 lock_rng (void)
 {
-  int my_errno;
+  gpg_err_code_t rc;
 
-  my_errno = ath_mutex_lock (&system_rng_lock);
-  if (my_errno)
+  rc = gpgrt_lock_lock (&system_rng_lock);
+  if (rc)
     log_fatal ("failed to acquire the System RNG lock: %s\n",
-               strerror (my_errno));
+               gpg_strerror (rc));
   system_rng_is_locked = 1;
 }
 
@@ -97,13 +91,13 @@ lock_rng (void)
 static void
 unlock_rng (void)
 {
-  int my_errno;
+  gpg_err_code_t rc;
 
   system_rng_is_locked = 0;
-  my_errno = ath_mutex_unlock (&system_rng_lock);
-  if (my_errno)
+  rc = gpgrt_lock_unlock (&system_rng_lock);
+  if (rc)
     log_fatal ("failed to release the System RNG lock: %s\n",
-               strerror (my_errno));
+               gpg_strerror (rc));
 }
 
 
index ff9d6d2..ff9be16 100644 (file)
@@ -34,7 +34,6 @@
 #include "random.h"
 #include "rand-internal.h"
 #include "cipher.h"         /* For _gcry_sha1_hash_buffer().  */
-#include "ath.h"
 
 
 /* If not NULL a progress function called from certain places and the
@@ -54,7 +53,7 @@ static struct
 
 /* This is the lock we use to protect the buffer used by the nonce
    generation.  */
-static ath_mutex_t nonce_buffer_lock;
+GPGRT_LOCK_DEFINE (nonce_buffer_lock);
 
 
 \f
@@ -140,24 +139,12 @@ _gcry_set_preferred_rng_type (int type)
 void
 _gcry_random_initialize (int full)
 {
-  static int nonce_initialized;
-  int err;
-
-  if (!nonce_initialized)
-    {
-      nonce_initialized = 1;
-      err = ath_mutex_init (&nonce_buffer_lock);
-      if (err)
-        log_fatal ("failed to create the nonce buffer lock: %s\n",
-                   strerror (err) );
-    }
-
   if (fips_mode ())
-    _gcry_rngfips_initialize (full);
+    _gcry_rngdrbg_inititialize (full);
   else if (rng_types.standard)
     _gcry_rngcsprng_initialize (full);
   else if (rng_types.fips)
-    _gcry_rngfips_initialize (full);
+    _gcry_rngdrbg_inititialize (full);
   else if (rng_types.system)
     _gcry_rngsystem_initialize (full);
   else
@@ -174,11 +161,11 @@ _gcry_random_close_fds (void)
      the entropy gatherer.  */
 
   if (fips_mode ())
-    _gcry_rngfips_close_fds ();
+    _gcry_rngdrbg_close_fds ();
   else if (rng_types.standard)
     _gcry_rngcsprng_close_fds ();
   else if (rng_types.fips)
-    _gcry_rngfips_close_fds ();
+    _gcry_rngdrbg_close_fds ();
   else if (rng_types.system)
     _gcry_rngsystem_close_fds ();
   else
@@ -212,7 +199,7 @@ void
 _gcry_random_dump_stats (void)
 {
   if (fips_mode ())
-    _gcry_rngfips_dump_stats ();
+    _gcry_rngdrbg_dump_stats ();
   else
     _gcry_rngcsprng_dump_stats ();
 }
@@ -271,7 +258,7 @@ int
 _gcry_random_is_faked (void)
 {
   if (fips_mode ())
-    return _gcry_rngfips_is_faked ();
+    return _gcry_rngdrbg_is_faked ();
   else
     return _gcry_rngcsprng_is_faked ();
 }
@@ -301,11 +288,11 @@ static void
 do_randomize (void *buffer, size_t length, enum gcry_random_level level)
 {
   if (fips_mode ())
-    _gcry_rngfips_randomize (buffer, length, level);
+    _gcry_rngdrbg_randomize (buffer, length, level);
   else if (rng_types.standard)
     _gcry_rngcsprng_randomize (buffer, length, level);
   else if (rng_types.fips)
-    _gcry_rngfips_randomize (buffer, length, level);
+    _gcry_rngdrbg_randomize (buffer, length, level);
   else if (rng_types.system)
     _gcry_rngsystem_randomize (buffer, length, level);
   else /* default */
@@ -437,7 +424,7 @@ _gcry_create_nonce (void *buffer, size_t length)
      nonce generator which is seeded by the RNG actual in use.  */
   if (fips_mode ())
     {
-      _gcry_rngfips_create_nonce (buffer, length);
+      _gcry_rngdrbg_randomize (buffer, length, GCRY_WEAK_RANDOM);
       return;
     }
 
@@ -450,10 +437,10 @@ _gcry_create_nonce (void *buffer, size_t length)
   _gcry_random_initialize (1);
 
   /* Acquire the nonce buffer lock. */
-  err = ath_mutex_lock (&nonce_buffer_lock);
+  err = gpgrt_lock_lock (&nonce_buffer_lock);
   if (err)
     log_fatal ("failed to acquire the nonce buffer lock: %s\n",
-               strerror (err));
+               gpg_strerror (err));
 
   apid = getpid ();
   /* The first time initialize our buffer. */
@@ -501,10 +488,10 @@ _gcry_create_nonce (void *buffer, size_t length)
     }
 
   /* Release the nonce buffer lock. */
-  err = ath_mutex_unlock (&nonce_buffer_lock);
+  err = gpgrt_lock_unlock (&nonce_buffer_lock);
   if (err)
     log_fatal ("failed to release the nonce buffer lock: %s\n",
-               strerror (err));
+               gpg_strerror (err));
 }
 
 
@@ -514,46 +501,7 @@ gpg_error_t
 _gcry_random_selftest (selftest_report_func_t report)
 {
   if (fips_mode ())
-    return _gcry_rngfips_selftest (report);
+    return _gcry_rngdrbg_selftest (report);
   else
     return 0; /* No selftests yet.  */
 }
-
-
-/* Create a new test context for an external RNG test driver.  On
-   success the test context is stored at R_CONTEXT; on failure NULL is
-   stored at R_CONTEXT and an error code is returned.  */
-gcry_err_code_t
-_gcry_random_init_external_test (void **r_context,
-                                 unsigned int flags,
-                                 const void *key, size_t keylen,
-                                 const void *seed, size_t seedlen,
-                                 const void *dt, size_t dtlen)
-{
-  (void)flags;
-  if (fips_mode ())
-    return _gcry_rngfips_init_external_test (r_context, flags, key, keylen,
-                                             seed, seedlen,
-                                             dt, dtlen);
-  else
-    return GPG_ERR_NOT_SUPPORTED;
-}
-
-/* Get BUFLEN bytes from the RNG using the test CONTEXT and store them
-   at BUFFER.  Return 0 on success or an error code.  */
-gcry_err_code_t
-_gcry_random_run_external_test (void *context, char *buffer, size_t buflen)
-{
-  if (fips_mode ())
-    return _gcry_rngfips_run_external_test (context, buffer, buflen);
-  else
-    return GPG_ERR_NOT_SUPPORTED;
-}
-
-/* Release the test CONTEXT.  */
-void
-_gcry_random_deinit_external_test (void *context)
-{
-  if (fips_mode ())
-    _gcry_rngfips_deinit_external_test (context);
-}
index 2bc8cab..30e6fdf 100644 (file)
@@ -21,6 +21,7 @@
 #define G10_RANDOM_H
 
 #include "types.h"
+#include "../src/gcrypt-testapi.h"  /* struct gcry_drbg_test_vector */
 
 /*-- random.c --*/
 void _gcry_register_random_progress (void (*cb)(void *,const char*,int,int,int),
@@ -54,6 +55,12 @@ gcry_err_code_t _gcry_random_run_external_test (void *context,
                                                 char *buffer, size_t buflen);
 void            _gcry_random_deinit_external_test (void *context);
 
+/*-- random-drbg.c --*/
+gpg_err_code_t _gcry_rngdrbg_reinit (const char *flagstr,
+                                     gcry_buffer_t *pers, int npers);
+gpg_err_code_t _gcry_rngdrbg_cavs_test (struct gcry_drbg_test_vector *t,
+                                        unsigned char *buf);
+gpg_err_code_t _gcry_rngdrbg_healthcheck_one (struct gcry_drbg_test_vector *t);
 
 /*-- rndegd.c --*/
 gpg_error_t _gcry_rndegd_set_socket_name (const char *name);
index d43fcbc..b87115f 100644 (file)
@@ -62,7 +62,7 @@ my_make_filename (const char *first_part, const char *second_part)
       && (home = getenv("HOME")) && *home )
     n += strlen(home);
 
-  name = gcry_xmalloc(n);
+  name = _gcry_xmalloc(n);
   p = (home
        ? stpcpy (stpcpy (name, home), first_part+1 )
        : stpcpy (name, first_part) );
@@ -161,7 +161,7 @@ _gcry_rndegd_connect_socket (int nofail)
 #endif
   if (user_socket_name)
     {
-      name = gcry_strdup (user_socket_name);
+      name = _gcry_strdup (user_socket_name);
       if (!name)
         {
           if (!nofail)
index e625512..8e50751 100644 (file)
@@ -69,7 +69,7 @@ poll_padlock (void (*add)(const void*, size_t, enum random_origins),
   nbytes = 0;
   while (nbytes < 64)
     {
-#if defined(__x86_64__) && defined(__LP64__)
+#if defined(__x86_64__) && SIZEOF_VOID_P == 8
       asm volatile
         ("movq %1, %%rdi\n\t"         /* Set buffer.  */
          "xorq %%rdx, %%rdx\n\t"      /* Request up to 8 bytes.  */
@@ -123,7 +123,7 @@ poll_padlock (void (*add)(const void*, size_t, enum random_origins),
 #ifdef USE_DRNG
 # define RDRAND_RETRY_LOOPS    10
 # define RDRAND_INT    ".byte 0x0f,0xc7,0xf0"
-# if defined(__x86_64__) && defined(__LP64__)
+# if defined(__x86_64__) && SIZEOF_UNSIGNED_LONG == 8
 #  define RDRAND_LONG  ".byte 0x48,0x0f,0xc7,0xf0"
 # else
 #  define RDRAND_LONG  RDRAND_INT
index 9eeec57..f08c9f9 100644 (file)
 #include <string.h>
 #include <unistd.h>
 #include <fcntl.h>
+#if defined(__linux__) && defined(HAVE_SYSCALL)
+# include <sys/syscall.h>
+#endif
+
 #include "types.h"
 #include "g10lib.h"
 #include "rand-internal.h"
@@ -139,10 +143,18 @@ _gcry_rndlinux_gather_random (void (*add)(const void*, size_t,
 
 
   /* First read from a hardware source.  However let it account only
-     for up to 50% of the requested bytes.  */
+     for up to 50% (or 25% for RDRAND) of the requested bytes.  */
   n_hw = _gcry_rndhw_poll_slow (add, origin);
-  if (n_hw > length/2)
-    n_hw = length/2;
+  if ((_gcry_get_hw_features () & HWF_INTEL_RDRAND))
+    {
+      if (n_hw > length/4)
+        n_hw = length/4;
+    }
+  else
+    {
+      if (n_hw > length/2)
+        n_hw = length/2;
+    }
   if (length > 1)
     length -= n_hw;
 
@@ -224,6 +236,49 @@ _gcry_rndlinux_gather_random (void (*add)(const void*, size_t,
             }
         }
 
+      /* If we have a modern Linux kernel and we want to read from the
+       * the non-blocking /dev/urandom, we first try to use the new
+       * getrandom syscall.  That call guarantees that the kernel's
+       * RNG has been properly seeded before returning any data.  This
+       * is different from /dev/urandom which may, due to its
+       * non-blocking semantics, return data even if the kernel has
+       * not been properly seeded.  Unfortunately we need to use a
+       * syscall and not a new device and thus we are not able to use
+       * select(2) to have a timeout. */
+#if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom)
+      if (fd == fd_urandom)
+        {
+          long ret;
+          size_t nbytes;
+
+          do
+            {
+              nbytes = length < sizeof(buffer)? length : sizeof(buffer);
+              if (nbytes > 256)
+                nbytes = 256;
+              ret = syscall (__NR_getrandom,
+                             (void*)buffer, (size_t)nbytes, (unsigned int)0);
+            }
+          while (ret == -1 && errno == EINTR);
+          if (ret == -1 && errno == ENOSYS)
+            ; /* The syscall is not supported - fallback to /dev/urandom.  */
+          else
+            { /* The syscall is supported.  Some sanity checks.  */
+              if (ret == -1)
+                log_fatal ("unexpected error from getrandom: %s\n",
+                           strerror (errno));
+              else if (ret != nbytes)
+                log_fatal ("getrandom returned only"
+                           " %ld of %zu requested bytes\n", ret, nbytes);
+
+              (*add)(buffer, nbytes, origin);
+              length -= nbytes;
+              continue; /* until LENGTH is zero.  */
+            }
+          log_debug ("syscall(getrandom) not supported; errno = %d\n", errno);
+        }
+#endif
+
       do
         {
           size_t nbytes;
index 1b810d7..e7238f4 100644 (file)
@@ -86,6 +86,9 @@
 #include <config.h>
 #include <stdlib.h>
 #include <stdio.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
 #include <string.h>
 
 /* OS-specific includes */
 #ifndef STDOUT_FILENO
 #define STDOUT_FILENO 1
 #endif
+#ifndef STDERR_FILENO
+#define STDERR_FILENO 2
+#endif
 
 #define GATHER_BUFSIZE         49152   /* Usually about 25K are filled */
 
@@ -708,7 +714,7 @@ start_gatherer( int pipefd )
     int dbgall;
 
     {
-       const char *s = getenv("GNUPG_RNDUNIX_DBG");
+       const char *s = getenv("GCRYPT_RNDUNIX_DBG");
        if( s ) {
            dbgfp = (*s=='-' && !s[1])? stdout : fopen(s, "a");
            if( !dbgfp )
@@ -717,18 +723,24 @@ start_gatherer( int pipefd )
            else
                fprintf(dbgfp,"\nSTART RNDUNIX DEBUG pid=%d\n", (int)getpid());
        }
-       dbgall = !!getenv("GNUPG_RNDUNIX_DBGALL");
+       dbgall = !!getenv("GCRYPT_RNDUNIX_DBGALL");
     }
     /* close all files but the ones we need */
     {  int nmax, n1, n2, i;
 #ifdef _SC_OPEN_MAX
        if( (nmax=sysconf( _SC_OPEN_MAX )) < 0 ) {
-#ifdef _POSIX_OPEN_MAX
+# ifdef _POSIX_OPEN_MAX
            nmax = _POSIX_OPEN_MAX;
-#else
+# else
            nmax = 20; /* assume a reasonable value */
-#endif
+# endif
        }
+        /* AIX returns INT32_MAX instead of a proper value.  We assume that
+         * this is always an error and use a reasonable value.  */
+# ifdef INT32_MAX
+        if (nmax == INT32_MAX)
+          nmax = 20;
+# endif
 #else /*!_SC_OPEN_MAX*/
        nmax = 20; /* assume a reasonable value */
 #endif /*!_SC_OPEN_MAX*/
@@ -766,13 +778,27 @@ start_gatherer( int pipefd )
 
     fclose(stderr);            /* Arrghh!!  It's Stuart code!! */
 
+    /* Mary goes to Berkeley: NetBSD emits warnings if the standard
+       descriptors are not open when running setuid program.  Thus we
+       connect them to the bitbucket if they are not already open.  */
+    {
+      struct stat statbuf;
+
+      if (fstat (STDIN_FILENO, &statbuf) == -1 && errno == EBADF)
+        open ("/dev/null",O_RDONLY);
+      if (fstat (STDOUT_FILENO, &statbuf) == -1 && errno == EBADF)
+        open ("/dev/null",O_WRONLY);
+      if (fstat (STDERR_FILENO, &statbuf) == -1 && errno == EBADF)
+        open ("/dev/null",O_WRONLY);
+    }
+
     for(;;) {
        GATHER_MSG msg;
        size_t nbytes;
        const char *p;
 
        msg.usefulness = slow_poll( dbgfp, dbgall, &nbytes );
-       p = gather_buffer;
+       p = (const char*)gather_buffer;
        while( nbytes ) {
            msg.ndata = nbytes > sizeof(msg.data)? sizeof(msg.data) : nbytes;
            memcpy( msg.data, p, msg.ndata );
index c495131..de6e783 100644 (file)
@@ -419,7 +419,7 @@ registry_poll (void (*add)(const void*, size_t, enum random_origins),
      this can consume tens of MB of memory and huge amounts of CPU time
      while it gathers its data, and even running once can still consume
      about 1/2MB of memory */
-  if (getenv ("GNUPG_RNDW32_NOPERF"))
+  if (getenv ("GCRYPT_RNDW32_NOPERF"))
     {
       static int shown;
 
@@ -513,7 +513,7 @@ slow_gatherer ( void (*add)(const void*, size_t, enum random_origins),
 
           status = RegQueryValueEx (hKey, "ProductType", 0, NULL,
                                     szValue, &dwSize);
-          if (status == ERROR_SUCCESS && stricmp (szValue, "WinNT"))
+          if (status == ERROR_SUCCESS && stricmp ((char*)szValue, "WinNT"))
             {
               /* Note: There are (at least) three cases for ProductType:
                  WinNT = NT Workstation, ServerNT = NT Server, LanmanNT =
@@ -826,39 +826,47 @@ _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t,
      cursor position for last message, 1 ms time for last message,
      handle of window with clipboard open, handle of process heap,
      handle of procs window station, types of events in input queue,
-     and milliseconds since Windows was started.  */
+     and milliseconds since Windows was started. On 64-bit platform
+     some of these return values are pointers and thus 64-bit wide.
+     We discard the upper 32-bit of those values.  */
 
   {
     byte buffer[20*sizeof(ulong)], *bufptr;
 
     bufptr = buffer;
-#define ADD(f)  do { ulong along = (ulong)(f);                  \
-                     memcpy (bufptr, &along, sizeof (along) );  \
-                     bufptr += sizeof (along);                  \
-                   } while (0)
-
-    ADD ( GetActiveWindow ());
-    ADD ( GetCapture ());
-    ADD ( GetClipboardOwner ());
-    ADD ( GetClipboardViewer ());
-    ADD ( GetCurrentProcess ());
-    ADD ( GetCurrentProcessId ());
-    ADD ( GetCurrentThread ());
-    ADD ( GetCurrentThreadId ());
-    ADD ( GetDesktopWindow ());
-    ADD ( GetFocus ());
-    ADD ( GetInputState ());
-    ADD ( GetMessagePos ());
-    ADD ( GetMessageTime ());
-    ADD ( GetOpenClipboardWindow ());
-    ADD ( GetProcessHeap ());
-    ADD ( GetProcessWindowStation ());
-    ADD ( GetQueueStatus (QS_ALLEVENTS));
-    ADD ( GetTickCount ());
+#define ADDINT(f)  do { ulong along = (ulong)(f);                  \
+                        memcpy (bufptr, &along, sizeof (along) );  \
+                        bufptr += sizeof (along);                  \
+                      } while (0)
+#define ADDPTR(f)  do { void *aptr = (f);                          \
+                        ADDINT((SIZE_T)aptr);                      \
+                      } while (0)
+
+    ADDPTR ( GetActiveWindow ());
+    ADDPTR ( GetCapture ());
+    ADDPTR ( GetClipboardOwner ());
+    ADDPTR ( GetClipboardViewer ());
+    ADDPTR ( GetCurrentProcess ());
+    ADDINT ( GetCurrentProcessId ());
+    ADDPTR ( GetCurrentThread ());
+    ADDINT ( GetCurrentThreadId ());
+    ADDPTR ( GetDesktopWindow ());
+    ADDPTR ( GetFocus ());
+    ADDINT ( GetInputState ());
+    ADDINT ( GetMessagePos ());
+    ADDINT ( GetMessageTime ());
+    ADDPTR ( GetOpenClipboardWindow ());
+    ADDPTR ( GetProcessHeap ());
+    ADDPTR ( GetProcessWindowStation ());
+    /* Following function in some cases stops returning events, and cannot
+       be used as an entropy source.  */
+    /*ADDINT ( GetQueueStatus (QS_ALLEVENTS));*/
+    ADDINT ( GetTickCount ());
 
     gcry_assert ( bufptr-buffer < sizeof (buffer) );
     (*add) ( buffer, bufptr-buffer, origin );
-#undef ADD
+#undef ADDINT
+#undef ADDPTR
   }
 
   /* Get multiword system information: Current caret position, current
@@ -888,7 +896,7 @@ _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t,
   {
     HANDLE handle;
     FILETIME creationTime, exitTime, kernelTime, userTime;
-    DWORD minimumWorkingSetSize, maximumWorkingSetSize;
+    SIZE_T minimumWorkingSetSize, maximumWorkingSetSize;
 
     handle = GetCurrentThread ();
     GetThreadTimes (handle, &creationTime, &exitTime,
@@ -910,10 +918,9 @@ _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t,
        process.  */
     GetProcessWorkingSetSize (handle, &minimumWorkingSetSize,
                               &maximumWorkingSetSize);
-    (*add) ( &minimumWorkingSetSize,
-             sizeof (minimumWorkingSetSize), origin );
-    (*add) ( &maximumWorkingSetSize,
-             sizeof (maximumWorkingSetSize), origin );
+    /* On 64-bit system, discard the high 32-bits. */
+    (*add) ( &minimumWorkingSetSize, sizeof (int), origin );
+    (*add) ( &maximumWorkingSetSize, sizeof (int), origin );
   }
 
 
@@ -948,7 +955,7 @@ _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t,
      However, the kernel appears to synchronise the TSCs across CPUs at
      boot time (it resets the TSC as part of its system init), so this
      shouldn't really be a problem.  Under WinCE it's completely platform-
-     dependant, if there's no hardware performance counter available, it
+     dependent, if there's no hardware performance counter available, it
      uses the 1ms system timer.
 
      Another feature of the TSC (although it doesn't really affect us here)
@@ -961,7 +968,20 @@ _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t,
 
      To make things unambiguous, we detect a CPU new enough to call RDTSC
      directly by checking for CPUID capabilities, and fall back to QPC if
-     this isn't present.  */
+     this isn't present.
+
+     On AMD64, TSC is always available and intrinsic is provided for accessing
+     it.  */
+#ifdef __WIN64__
+    {
+      unsigned __int64 aint64;
+
+      /* Note: cryptlib does not discard upper 32 bits of TSC on WIN64, but does
+       * on WIN32.  Is this correct?  */
+      aint64 = __rdtsc();
+      (*add) (&aint64, sizeof(aint64), origin);
+    }
+#else
 #ifdef __GNUC__
 /*   FIXME: We would need to implement the CPU feature tests first.  */
 /*   if (cpu_has_feature_rdtsc) */
@@ -990,6 +1010,7 @@ _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t,
           (*add) (&aword, sizeof (aword), origin );
         }
     }
+#endif /*__WIN64__*/
 
 
 }
index 2d4800f..3cc4a55 100644 (file)
 
 ## Process this file with automake to produce Makefile.in
 
-EXTRA_DIST = Manifest libgcrypt-config.in libgcrypt.m4 libgcrypt.vers \
+EXTRA_DIST = libgcrypt-config.in libgcrypt.m4 libgcrypt.vers \
              gcrypt.h.in libgcrypt.def
 
 bin_SCRIPTS = libgcrypt-config
 m4datadir = $(datadir)/aclocal
 m4data_DATA = libgcrypt.m4
-include_HEADERS = gcrypt.h
+nodist_include_HEADERS = gcrypt.h
 
 lib_LTLIBRARIES = libgcrypt.la
 bin_PROGRAMS = dumpsexp hmac256 mpicalc
@@ -56,13 +56,12 @@ endif
 libgcrypt_la_CFLAGS = $(GPG_ERROR_CFLAGS)
 libgcrypt_la_SOURCES = \
         gcrypt-int.h g10lib.h visibility.c visibility.h types.h \
-       cipher.h cipher-proto.h \
+       gcrypt-testapi.h cipher.h cipher-proto.h \
        misc.c global.c sexp.c hwfeatures.c hwf-common.h \
        stdmem.c stdmem.h secmem.c secmem.h \
        mpi.h missing-string.c fips.c \
        hmac256.c hmac256.h context.c context.h \
-       ec-context.h \
-       ath.h ath.c
+       ec-context.h
 
 EXTRA_libgcrypt_la_SOURCES = hwf-x86.c hwf-arm.c
 gcrypt_hwf_modules = @GCRYPT_HWF_MODULES@
@@ -82,6 +81,7 @@ SUFFIXES = .rc .lo
 gcrypt_res = versioninfo.lo
 no_undefined = -no-undefined
 export_symbols = -export-symbols $(srcdir)/libgcrypt.def
+extra_ltoptions = -XCClinker -static-libgcc
 
 install-def-file:
        -$(INSTALL) -d $(DESTDIR)$(libdir)
@@ -98,6 +98,7 @@ gcrypt_res =
 gcrypt_res_ldflag =
 no_undefined =
 export_symbols =
+extra_ltoptions =
 install-def-file:
 uninstall-def-file:
 
@@ -106,7 +107,7 @@ gcrypt_deps =
 endif !HAVE_W32_SYSTEM
 
 
-libgcrypt_la_LDFLAGS = $(no_undefined) $(export_symbols) \
+libgcrypt_la_LDFLAGS = $(no_undefined) $(export_symbols) $(extra_ltoptions) \
        $(libgcrypt_version_script_cmd) -version-info \
        @LIBGCRYPT_LT_CURRENT@:@LIBGCRYPT_LT_REVISION@:@LIBGCRYPT_LT_AGE@
 libgcrypt_la_DEPENDENCIES = \
@@ -126,20 +127,20 @@ libgcrypt_la_LIBADD = $(gcrypt_res) \
 
 dumpsexp_SOURCES = dumpsexp.c
 dumpsexp_CFLAGS = $(arch_gpg_error_cflags)
-dumpsexp_LDADD = $(arch_gpg_error_libs) $(LIBTHREAD)
+dumpsexp_LDADD = $(arch_gpg_error_libs)
 
 mpicalc_SOURCES = mpicalc.c
 mpicalc_CFLAGS = $(GPG_ERROR_CFLAGS)
-mpicalc_LDADD = libgcrypt.la $(GPG_ERROR_LIBS) $(LIBTHREAD)
+mpicalc_LDADD = libgcrypt.la $(DL_LIBS) $(GPG_ERROR_LIBS)
 
 hmac256_SOURCES = hmac256.c
 hmac256_CFLAGS = -DSTANDALONE $(arch_gpg_error_cflags)
-hmac256_LDADD = $(arch_gpg_error_libs) $(LIBTHREAD)
+hmac256_LDADD = $(arch_gpg_error_libs)
 
 if USE_RANDOM_DAEMON
 gcryptrnd_SOURCES = gcryptrnd.c
 gcryptrnd_CFLAGS = $(GPG_ERROR_CFLAGS) $(PTH_CFLAGS)
-gcryptrnd_LDADD = libgcrypt.la $(GPG_ERROR_LIBS) $(PTH_LIBS) $(LIBTHREAD)
+gcryptrnd_LDADD = libgcrypt.la $(GPG_ERROR_LIBS) $(PTH_LIBS)
 
 getrandom_SOURCES = getrandom.c
 endif USE_RANDOM_DAEMON
index 24ad6b4..d020ea6 100644 (file)
@@ -1,9 +1,8 @@
-# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
-# Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
 
 VPATH = @srcdir@
-am__make_dryrun = \
-  { \
-    am__dry=no; \
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
     case $$MAKEFLAGS in \
       *\\[\ \  ]*) \
-        echo 'am--echo: ; @echo "AM"  OK' | $(MAKE) -f - 2>/dev/null \
-          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
-      *) \
-        for am__flg in $$MAKEFLAGS; do \
-          case $$am__flg in \
-            *=*|--*) ;; \
-            *n*) am__dry=yes; break;; \
-          esac; \
-        done;; \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs  ]*//g"`;; \
     esac; \
-    test $$am__dry = yes; \
-  }
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -79,18 +106,17 @@ bin_PROGRAMS = dumpsexp$(EXEEXT) hmac256$(EXEEXT) mpicalc$(EXEEXT) \
 @USE_RANDOM_DAEMON_TRUE@sbin_PROGRAMS = gcryptrnd$(EXEEXT)
 @USE_RANDOM_DAEMON_TRUE@am__append_1 = getrandom
 subdir = src
-DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \
-       $(srcdir)/Makefile.in $(srcdir)/gcrypt.h.in \
-       $(srcdir)/libgcrypt-config.in $(srcdir)/versioninfo.rc.in
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+       $(srcdir)/gcrypt.h.in $(srcdir)/libgcrypt-config.in \
+       $(srcdir)/versioninfo.rc.in $(top_srcdir)/build-aux/depcomp
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/gpg-error.m4 \
-       $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/lock.m4 \
-       $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
-       $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+       $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+       $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+       $(top_srcdir)/m4/lt~obsolete.m4 \
        $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \
        $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
-       $(top_srcdir)/m4/threadlib.m4 $(top_srcdir)/acinclude.m4 \
-       $(top_srcdir)/configure.ac
+       $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -135,12 +161,12 @@ am_libgcrypt_la_OBJECTS = libgcrypt_la-visibility.lo \
        libgcrypt_la-sexp.lo libgcrypt_la-hwfeatures.lo \
        libgcrypt_la-stdmem.lo libgcrypt_la-secmem.lo \
        libgcrypt_la-missing-string.lo libgcrypt_la-fips.lo \
-       libgcrypt_la-hmac256.lo libgcrypt_la-context.lo \
-       libgcrypt_la-ath.lo
+       libgcrypt_la-hmac256.lo libgcrypt_la-context.lo
 libgcrypt_la_OBJECTS = $(am_libgcrypt_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
 am__v_lt_0 = --silent
+am__v_lt_1 = 
 libgcrypt_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libgcrypt_la_CFLAGS) \
        $(CFLAGS) $(libgcrypt_la_LDFLAGS) $(LDFLAGS) -o $@
@@ -149,7 +175,7 @@ PROGRAMS = $(bin_PROGRAMS) $(sbin_PROGRAMS)
 am_dumpsexp_OBJECTS = dumpsexp-dumpsexp.$(OBJEXT)
 dumpsexp_OBJECTS = $(am_dumpsexp_OBJECTS)
 @HAVE_W32CE_SYSTEM_TRUE@am__DEPENDENCIES_3 = $(am__DEPENDENCIES_2)
-dumpsexp_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2)
+dumpsexp_DEPENDENCIES = $(am__DEPENDENCIES_3)
 dumpsexp_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(dumpsexp_CFLAGS) \
        $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
@@ -159,7 +185,6 @@ am__gcryptrnd_SOURCES_DIST = gcryptrnd.c
 gcryptrnd_OBJECTS = $(am_gcryptrnd_OBJECTS)
 @USE_RANDOM_DAEMON_TRUE@gcryptrnd_DEPENDENCIES = libgcrypt.la \
 @USE_RANDOM_DAEMON_TRUE@       $(am__DEPENDENCIES_2) \
-@USE_RANDOM_DAEMON_TRUE@       $(am__DEPENDENCIES_2) \
 @USE_RANDOM_DAEMON_TRUE@       $(am__DEPENDENCIES_2)
 gcryptrnd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(gcryptrnd_CFLAGS) \
@@ -170,7 +195,7 @@ getrandom_OBJECTS = $(am_getrandom_OBJECTS)
 getrandom_LDADD = $(LDADD)
 am_hmac256_OBJECTS = hmac256-hmac256.$(OBJEXT)
 hmac256_OBJECTS = $(am_hmac256_OBJECTS)
-hmac256_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2)
+hmac256_DEPENDENCIES = $(am__DEPENDENCIES_3)
 hmac256_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(hmac256_CFLAGS) \
        $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
@@ -182,6 +207,18 @@ mpicalc_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(mpicalc_CFLAGS) \
        $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
 SCRIPTS = $(bin_SCRIPTS)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
 depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
 am__depfiles_maybe = depfiles
@@ -194,20 +231,16 @@ LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(AM_CFLAGS) $(CFLAGS)
 AM_V_CC = $(am__v_CC_@AM_V@)
 am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
-am__v_CC_0 = @echo "  CC    " $@;
-AM_V_at = $(am__v_at_@AM_V@)
-am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
-am__v_at_0 = @
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
 CCLD = $(CC)
 LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
        $(AM_LDFLAGS) $(LDFLAGS) -o $@
 AM_V_CCLD = $(am__v_CCLD_@AM_V@)
 am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
-am__v_CCLD_0 = @echo "  CCLD  " $@;
-AM_V_GEN = $(am__v_GEN_@AM_V@)
-am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
-am__v_GEN_0 = @echo "  GEN   " $@;
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
 SOURCES = $(libgcrypt_la_SOURCES) $(EXTRA_libgcrypt_la_SOURCES) \
        $(dumpsexp_SOURCES) $(gcryptrnd_SOURCES) $(getrandom_SOURCES) \
        $(hmac256_SOURCES) $(mpicalc_SOURCES)
@@ -221,7 +254,24 @@ am__can_run_installinfo = \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
 DATA = $(m4data_DATA)
-HEADERS = $(include_HEADERS)
+HEADERS = $(nodist_include_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -269,6 +319,8 @@ GCRYPT_RANDOM = @GCRYPT_RANDOM@
 GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
 GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
 GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GPG_ERROR_MT_CFLAGS = @GPG_ERROR_MT_CFLAGS@
+GPG_ERROR_MT_LIBS = @GPG_ERROR_MT_LIBS@
 GREP = @GREP@
 INSERT_SYS_SELECT_H = @INSERT_SYS_SELECT_H@
 INSTALL = @INSTALL@
@@ -289,16 +341,12 @@ LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@
 LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@
 LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@
 LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@
-LIBMULTITHREAD = @LIBMULTITHREAD@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
-LIBTHREAD = @LIBTHREAD@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
-LTLIBMULTITHREAD = @LTLIBMULTITHREAD@
 LTLIBOBJS = @LTLIBOBJS@
-LTLIBTHREAD = @LTLIBTHREAD@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
@@ -329,6 +377,7 @@ SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
+SYSROOT = @SYSROOT@
 SYS_SOCKET_H = @SYS_SOCKET_H@
 VERSION = @VERSION@
 VERSION_NUMBER = @VERSION_NUMBER@
@@ -387,13 +436,13 @@ target_alias = @target_alias@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-EXTRA_DIST = Manifest libgcrypt-config.in libgcrypt.m4 libgcrypt.vers \
+EXTRA_DIST = libgcrypt-config.in libgcrypt.m4 libgcrypt.vers \
              gcrypt.h.in libgcrypt.def
 
 bin_SCRIPTS = libgcrypt-config
 m4datadir = $(datadir)/aclocal
 m4data_DATA = libgcrypt.m4
-include_HEADERS = gcrypt.h
+nodist_include_HEADERS = gcrypt.h
 lib_LTLIBRARIES = libgcrypt.la
 @HAVE_W32CE_SYSTEM_FALSE@arch_gpg_error_cflags = 
 
@@ -408,13 +457,12 @@ AM_CCASFLAGS = $(NOEXECSTACK_FLAGS)
 libgcrypt_la_CFLAGS = $(GPG_ERROR_CFLAGS)
 libgcrypt_la_SOURCES = \
         gcrypt-int.h g10lib.h visibility.c visibility.h types.h \
-       cipher.h cipher-proto.h \
+       gcrypt-testapi.h cipher.h cipher-proto.h \
        misc.c global.c sexp.c hwfeatures.c hwf-common.h \
        stdmem.c stdmem.h secmem.c secmem.h \
        mpi.h missing-string.c fips.c \
        hmac256.c hmac256.h context.c context.h \
-       ec-context.h \
-       ath.h ath.c
+       ec-context.h
 
 EXTRA_libgcrypt_la_SOURCES = hwf-x86.c hwf-arm.c
 gcrypt_hwf_modules = @GCRYPT_HWF_MODULES@
@@ -429,10 +477,12 @@ gcrypt_hwf_modules = @GCRYPT_HWF_MODULES@
 @HAVE_W32_SYSTEM_TRUE@no_undefined = -no-undefined
 @HAVE_W32_SYSTEM_FALSE@export_symbols = 
 @HAVE_W32_SYSTEM_TRUE@export_symbols = -export-symbols $(srcdir)/libgcrypt.def
+@HAVE_W32_SYSTEM_FALSE@extra_ltoptions = 
+@HAVE_W32_SYSTEM_TRUE@extra_ltoptions = -XCClinker -static-libgcc
 @HAVE_W32_SYSTEM_FALSE@gcrypt_deps = 
 @HAVE_W32_SYSTEM_TRUE@gcrypt_deps = $(gcrypt_res) libgcrypt.def
 @HAVE_W32_SYSTEM_FALSE@gcrypt_res_ldflag = 
-libgcrypt_la_LDFLAGS = $(no_undefined) $(export_symbols) \
+libgcrypt_la_LDFLAGS = $(no_undefined) $(export_symbols) $(extra_ltoptions) \
        $(libgcrypt_version_script_cmd) -version-info \
        @LIBGCRYPT_LT_CURRENT@:@LIBGCRYPT_LT_REVISION@:@LIBGCRYPT_LT_AGE@
 
@@ -453,16 +503,16 @@ libgcrypt_la_LIBADD = $(gcrypt_res) \
 
 dumpsexp_SOURCES = dumpsexp.c
 dumpsexp_CFLAGS = $(arch_gpg_error_cflags)
-dumpsexp_LDADD = $(arch_gpg_error_libs) $(LIBTHREAD)
+dumpsexp_LDADD = $(arch_gpg_error_libs)
 mpicalc_SOURCES = mpicalc.c
 mpicalc_CFLAGS = $(GPG_ERROR_CFLAGS)
-mpicalc_LDADD = libgcrypt.la $(GPG_ERROR_LIBS) $(LIBTHREAD)
+mpicalc_LDADD = libgcrypt.la $(DL_LIBS) $(GPG_ERROR_LIBS)
 hmac256_SOURCES = hmac256.c
 hmac256_CFLAGS = -DSTANDALONE $(arch_gpg_error_cflags)
-hmac256_LDADD = $(arch_gpg_error_libs) $(LIBTHREAD)
+hmac256_LDADD = $(arch_gpg_error_libs)
 @USE_RANDOM_DAEMON_TRUE@gcryptrnd_SOURCES = gcryptrnd.c
 @USE_RANDOM_DAEMON_TRUE@gcryptrnd_CFLAGS = $(GPG_ERROR_CFLAGS) $(PTH_CFLAGS)
-@USE_RANDOM_DAEMON_TRUE@gcryptrnd_LDADD = libgcrypt.la $(GPG_ERROR_LIBS) $(PTH_LIBS) $(LIBTHREAD)
+@USE_RANDOM_DAEMON_TRUE@gcryptrnd_LDADD = libgcrypt.la $(GPG_ERROR_LIBS) $(PTH_LIBS)
 @USE_RANDOM_DAEMON_TRUE@getrandom_SOURCES = getrandom.c
 all: all-am
 
@@ -504,6 +554,7 @@ libgcrypt-config: $(top_builddir)/config.status $(srcdir)/libgcrypt-config.in
        cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 versioninfo.rc: $(top_builddir)/config.status $(srcdir)/versioninfo.rc.in
        cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+
 install-libLTLIBRARIES: $(lib_LTLIBRARIES)
        @$(NORMAL_INSTALL)
        @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
@@ -530,12 +581,15 @@ uninstall-libLTLIBRARIES:
 
 clean-libLTLIBRARIES:
        -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
-       @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
-         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
-         test "$$dir" != "$$p" || dir=.; \
-         echo "rm -f \"$${dir}/so_locations\""; \
-         rm -f "$${dir}/so_locations"; \
-       done
+       @list='$(lib_LTLIBRARIES)'; \
+       locs=`for p in $$list; do echo $$p; done | \
+             sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+             sort -u`; \
+       test -z "$$locs" || { \
+         echo rm -f $${locs}; \
+         rm -f $${locs}; \
+       }
+
 libgcrypt.la: $(libgcrypt_la_OBJECTS) $(libgcrypt_la_DEPENDENCIES) $(EXTRA_libgcrypt_la_DEPENDENCIES) 
        $(AM_V_CCLD)$(libgcrypt_la_LINK) -rpath $(libdir) $(libgcrypt_la_OBJECTS) $(libgcrypt_la_LIBADD) $(LIBS)
 install-binPROGRAMS: $(bin_PROGRAMS)
@@ -547,10 +601,12 @@ install-binPROGRAMS: $(bin_PROGRAMS)
        fi; \
        for p in $$list; do echo "$$p $$p"; done | \
        sed 's/$(EXEEXT)$$//' | \
-       while read p p1; do if test -f $$p || test -f $$p1; \
-         then echo "$$p"; echo "$$p"; else :; fi; \
+       while read p p1; do if test -f $$p \
+        || test -f $$p1 \
+         ; then echo "$$p"; echo "$$p"; else :; fi; \
        done | \
-       sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+       sed -e 'p;s,.*/,,;n;h' \
+           -e 's|.*|.|' \
            -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
        sed 'N;N;N;s,\n, ,g' | \
        $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
@@ -571,7 +627,8 @@ uninstall-binPROGRAMS:
        @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
        files=`for p in $$list; do echo "$$p"; done | \
          sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
-             -e 's/$$/$(EXEEXT)/' `; \
+             -e 's/$$/$(EXEEXT)/' \
+       `; \
        test -n "$$list" || exit 0; \
        echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
        cd "$(DESTDIR)$(bindir)" && rm -f $$files
@@ -593,10 +650,12 @@ install-sbinPROGRAMS: $(sbin_PROGRAMS)
        fi; \
        for p in $$list; do echo "$$p $$p"; done | \
        sed 's/$(EXEEXT)$$//' | \
-       while read p p1; do if test -f $$p || test -f $$p1; \
-         then echo "$$p"; echo "$$p"; else :; fi; \
+       while read p p1; do if test -f $$p \
+        || test -f $$p1 \
+         ; then echo "$$p"; echo "$$p"; else :; fi; \
        done | \
-       sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+       sed -e 'p;s,.*/,,;n;h' \
+           -e 's|.*|.|' \
            -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
        sed 'N;N;N;s,\n, ,g' | \
        $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
@@ -617,7 +676,8 @@ uninstall-sbinPROGRAMS:
        @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
        files=`for p in $$list; do echo "$$p"; done | \
          sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
-             -e 's/$$/$(EXEEXT)/' `; \
+             -e 's/$$/$(EXEEXT)/' \
+       `; \
        test -n "$$list" || exit 0; \
        echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
        cd "$(DESTDIR)$(sbindir)" && rm -f $$files
@@ -630,18 +690,23 @@ clean-sbinPROGRAMS:
        list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
        echo " rm -f" $$list; \
        rm -f $$list
+
 dumpsexp$(EXEEXT): $(dumpsexp_OBJECTS) $(dumpsexp_DEPENDENCIES) $(EXTRA_dumpsexp_DEPENDENCIES) 
        @rm -f dumpsexp$(EXEEXT)
        $(AM_V_CCLD)$(dumpsexp_LINK) $(dumpsexp_OBJECTS) $(dumpsexp_LDADD) $(LIBS)
+
 gcryptrnd$(EXEEXT): $(gcryptrnd_OBJECTS) $(gcryptrnd_DEPENDENCIES) $(EXTRA_gcryptrnd_DEPENDENCIES) 
        @rm -f gcryptrnd$(EXEEXT)
        $(AM_V_CCLD)$(gcryptrnd_LINK) $(gcryptrnd_OBJECTS) $(gcryptrnd_LDADD) $(LIBS)
+
 getrandom$(EXEEXT): $(getrandom_OBJECTS) $(getrandom_DEPENDENCIES) $(EXTRA_getrandom_DEPENDENCIES) 
        @rm -f getrandom$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(getrandom_OBJECTS) $(getrandom_LDADD) $(LIBS)
+
 hmac256$(EXEEXT): $(hmac256_OBJECTS) $(hmac256_DEPENDENCIES) $(EXTRA_hmac256_DEPENDENCIES) 
        @rm -f hmac256$(EXEEXT)
        $(AM_V_CCLD)$(hmac256_LINK) $(hmac256_OBJECTS) $(hmac256_LDADD) $(LIBS)
+
 mpicalc$(EXEEXT): $(mpicalc_OBJECTS) $(mpicalc_DEPENDENCIES) $(EXTRA_mpicalc_DEPENDENCIES) 
        @rm -f mpicalc$(EXEEXT)
        $(AM_V_CCLD)$(mpicalc_LINK) $(mpicalc_OBJECTS) $(mpicalc_LDADD) $(LIBS)
@@ -691,7 +756,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gcryptrnd-gcryptrnd.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getrandom.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmac256-hmac256.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-ath.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-context.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-fips.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-global.Plo@am__quote@
@@ -712,14 +776,14 @@ distclean-compile:
 @am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
 
 .c.obj:
 @am__fastdepCC_TRUE@   $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
 @am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
 
 .c.lo:
 @am__fastdepCC_TRUE@   $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -805,13 +869,6 @@ libgcrypt_la-context.lo: context.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-context.lo `test -f 'context.c' || echo '$(srcdir)/'`context.c
 
-libgcrypt_la-ath.lo: ath.c
-@am__fastdepCC_TRUE@   $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-ath.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-ath.Tpo -c -o libgcrypt_la-ath.lo `test -f 'ath.c' || echo '$(srcdir)/'`ath.c
-@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-ath.Tpo $(DEPDIR)/libgcrypt_la-ath.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='ath.c' object='libgcrypt_la-ath.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-ath.lo `test -f 'ath.c' || echo '$(srcdir)/'`ath.c
-
 libgcrypt_la-hwf-x86.lo: hwf-x86.c
 @am__fastdepCC_TRUE@   $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-hwf-x86.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-hwf-x86.Tpo -c -o libgcrypt_la-hwf-x86.lo `test -f 'hwf-x86.c' || echo '$(srcdir)/'`hwf-x86.c
 @am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-hwf-x86.Tpo $(DEPDIR)/libgcrypt_la-hwf-x86.Plo
@@ -908,9 +965,9 @@ uninstall-m4dataDATA:
        @list='$(m4data_DATA)'; test -n "$(m4datadir)" || list=; \
        files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
        dir='$(DESTDIR)$(m4datadir)'; $(am__uninstall_files_from_dir)
-install-includeHEADERS: $(include_HEADERS)
+install-nodist_includeHEADERS: $(nodist_include_HEADERS)
        @$(NORMAL_INSTALL)
-       @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+       @list='$(nodist_include_HEADERS)'; test -n "$(includedir)" || list=; \
        if test -n "$$list"; then \
          echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \
          $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \
@@ -924,32 +981,21 @@ install-includeHEADERS: $(include_HEADERS)
          $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \
        done
 
-uninstall-includeHEADERS:
+uninstall-nodist_includeHEADERS:
        @$(NORMAL_UNINSTALL)
-       @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+       @list='$(nodist_include_HEADERS)'; test -n "$(includedir)" || list=; \
        files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
        dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
 
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
-       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
-       unique=`for i in $$list; do \
-           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-         done | \
-         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-             END { if (nonempty) { for (i in files) print i; }; }'`; \
-       mkid -fID $$unique
-tags: TAGS
-
-TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-               $(TAGS_FILES) $(LISP)
+ID: $(am__tagged_files)
+       $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
        set x; \
        here=`pwd`; \
-       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-       unique=`for i in $$list; do \
-           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-         done | \
-         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-             END { if (nonempty) { for (i in files) print i; }; }'`; \
+       $(am__define_uniq_tagged_files); \
        shift; \
        if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
@@ -961,15 +1007,11 @@ TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
              $$unique; \
          fi; \
        fi
-ctags: CTAGS
-CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-               $(TAGS_FILES) $(LISP)
-       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-       unique=`for i in $$list; do \
-           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-         done | \
-         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-             END { if (nonempty) { for (i in files) print i; }; }'`; \
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+       $(am__define_uniq_tagged_files); \
        test -z "$(CTAGS_ARGS)$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$unique
@@ -978,6 +1020,21 @@ GTAGS:
        here=`$(am__cd) $(top_builddir) && pwd` \
          && $(am__cd) $(top_srcdir) \
          && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+       list='$(am__tagged_files)'; \
+       case "$(srcdir)" in \
+         [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+         *) sdir=$(subdir)/$(srcdir) ;; \
+       esac; \
+       for i in $$list; do \
+         if test -f "$$i"; then \
+           echo "$(subdir)/$$i"; \
+         else \
+           echo "$$sdir/$$i"; \
+         fi; \
+       done >> $(top_builddir)/cscope.files
 
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
@@ -1075,8 +1132,8 @@ info: info-am
 
 info-am:
 
-install-data-am: install-data-local install-includeHEADERS \
-       install-m4dataDATA
+install-data-am: install-data-local install-m4dataDATA \
+       install-nodist_includeHEADERS
 
 install-dvi: install-dvi-am
 
@@ -1124,30 +1181,30 @@ ps: ps-am
 ps-am:
 
 uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
-       uninstall-includeHEADERS uninstall-libLTLIBRARIES \
-       uninstall-local uninstall-m4dataDATA uninstall-sbinPROGRAMS
+       uninstall-libLTLIBRARIES uninstall-local uninstall-m4dataDATA \
+       uninstall-nodist_includeHEADERS uninstall-sbinPROGRAMS
 
 .MAKE: install-am install-strip
 
-.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
-       clean-generic clean-libLTLIBRARIES clean-libtool \
-       clean-sbinPROGRAMS ctags distclean distclean-compile \
-       distclean-generic distclean-libtool distclean-tags distdir dvi \
-       dvi-am html html-am info info-am install install-am \
-       install-binPROGRAMS install-binSCRIPTS install-data \
-       install-data-am install-data-local install-dvi install-dvi-am \
-       install-exec install-exec-am install-html install-html-am \
-       install-includeHEADERS install-info install-info-am \
-       install-libLTLIBRARIES install-m4dataDATA install-man \
-       install-pdf install-pdf-am install-ps install-ps-am \
-       install-sbinPROGRAMS install-strip installcheck \
-       installcheck-am installdirs maintainer-clean \
-       maintainer-clean-generic mostlyclean mostlyclean-compile \
-       mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-       tags uninstall uninstall-am uninstall-binPROGRAMS \
-       uninstall-binSCRIPTS uninstall-includeHEADERS \
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
+       clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
+       clean-libtool clean-sbinPROGRAMS cscopelist-am ctags ctags-am \
+       distclean distclean-compile distclean-generic \
+       distclean-libtool distclean-tags distdir dvi dvi-am html \
+       html-am info info-am install install-am install-binPROGRAMS \
+       install-binSCRIPTS install-data install-data-am \
+       install-data-local install-dvi install-dvi-am install-exec \
+       install-exec-am install-html install-html-am install-info \
+       install-info-am install-libLTLIBRARIES install-m4dataDATA \
+       install-man install-nodist_includeHEADERS install-pdf \
+       install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \
+       install-strip installcheck installcheck-am installdirs \
+       maintainer-clean maintainer-clean-generic mostlyclean \
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+       pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \
+       uninstall-binPROGRAMS uninstall-binSCRIPTS \
        uninstall-libLTLIBRARIES uninstall-local uninstall-m4dataDATA \
-       uninstall-sbinPROGRAMS
+       uninstall-nodist_includeHEADERS uninstall-sbinPROGRAMS
 
 
 @HAVE_W32_SYSTEM_TRUE@.rc.lo:
diff --git a/src/Manifest b/src/Manifest
deleted file mode 100644 (file)
index 2d003d8..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-# Manifest - checksums of the src directory
-# Copyright 2004 Free Software Foundation, Inc.
-#
-# This file is part of Libgcrypt.
-#
-# Libgcrypt is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser general Public License as
-# published by the Free Software Foundation; either version 2.1 of
-# the License, or (at your option) any later version.
-#
-# Libgcrypt is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
-# Checksums for all source files in this directory. Format is
-# filename, blanks, base-64 part of an OpenPGP detached signature
-# without the header lines.  Blank lines and lines beginning with a
-# hash mark are ignored.  A tool to process this file is available by
-# cvs -d :pserver:anoncvs@cvs.gnupg.org:/cvs/wk co misc-scripts/manifest-tool
-#
-# The special entry "$names$" holds a signature over all sorted
-# filenames excluding itself.
-
-gcrypt.h iQCVAwUAQH5RsTEAnp832S/7AQK7xgP+Kc3NY9lipZkaAMrnHDkQVLdHYwTbZWuGOYdTLp8Xy7Auh9wtWV9hrWVUqs+kxDzT/2iF6XkO3WT3rf/PmQ/Q0TIGfOyjE3c/qvB/jVippaxoGda3tnGpODytdI3XPhfPS0Ss8nDzfCStPBGAEq0OVU7imnExrFzhRXt+Gljr0o0==Yagz
-gcrypt-module.h iQCVAwUAQH5UXzEAnp832S/7AQJMQgQAzumz9aaZelhw+FxTCeVadphBxt1bbNQvMrnddYYblyJv+AcxZ9ZxGz2oPeusN58Qg54DQcaW3lYhTgnWfXultsi+Ruxlz7400OUrzSXOl3At7KssdODAoscFzZIgh94G9lzQxEBr9lTXI9R3LsPFJP6muNG4frcNBAA42yckK7w==BBp5
-
-ath.c iQCVAwUAQH5E+DEAnp832S/7AQKFpgP+KSZHtVcnh9FFggIyHKbALUljW2FXauasZvFyN8Sk/mIMgKxyXFOG1THBAUzWLaKWIEWU+WkYU7uThqBtpnEImM5AenWzbQuJjftPC3gVHO8yjjmBWD4zmJj28htoKDoa/xDsoqumrHxae3FYcaCWtYGVjM/Pbl+OMRMOFAhp0ho==lQZ3
-ath.h iQCVAwUAQH5FODEAnp832S/7AQKiuQQAg4K+KOAn1LWBZN32MAhms4FeZKoce0fAuZW7BpyY4cCxIVgxqrtUC90CDykw8XegFfOyyYrgd0NmaMVdY7HZDncNOvIPxpgFQPCZrycsMOoAtoVwjK704RDeNo3zmeyxTKeDH+3M1J7JmLiafaEdSbOC8flX/W0icaV0Ol4dmBc==Ll6w
-
-cipher.h iQCVAwUAQH5FUzEAnp832S/7AQJKLgP9GSSk9f7EINIRqSQH1XKX+dYzt3phDHdqFTUGIfYNh7YzGdy0drvgFhG4k15nqDouKRuFVM/hKY3ZVY7JccmKXKGAH6+ZYShoG6LMFfIGgDX8zne0dNxc72PLfns3fVxNn/RlHmHBkrQ+ppjR9HnSthFmOqzbQaW1BKmc3Z2x5GU==lIeW
-g10lib.h iQCVAwUAQH5FejEAnp832S/7AQJ75wP/ZjOybwRix5eoXdfVeXPjoPygejzpYJJdMUGN3Y5UtkfBu9mPREsKfvZ6tH+Evjx+3xfeAb4bU/k2mRMp0tiWnk2koToS08vI9uxnioKQr9oulZH6r28S+NLSgMQuEGN1JNUky6RQ9TTNRndeTjKKSrEjZ7V6bv+rb8A1bYCKChs==P5mk
-mpi.h iQCVAwUAQH5FwzEAnp832S/7AQJJ4wP9E3jVkcO9M0YtSBHIbjG3hDWKWXzi86AlUh51qiE8/2XP0FfjA4TosyvmicZs7j48HitAByr9tHOSxnbeo7NBf17ICwAo6Eqty+wKDg+eyLeEGUy7VpVK3RJRQAA4H+kl3S2l3YMTKf3WJlbc7qkWSXZspdy5c9sAxeodCKrAubU==oALf
-
-global.c iQCVAwUAQH5HFzEAnp832S/7AQJc+QQAvi53ZkMCzLnVULHvhI6W+EX537zi9n8cplYguvIJqUhAZrP68yGAIyqyCONbZVDyB7wqeXdUMLzMk7W8fg+xuk5JSDpppAQf2m/bdQyze6XVqJso682eYBM8+b9z/IVEvLaFwhZcOKO1bcXudBlBCcJgVDpupfTtAWgPnewil9Q==Xwy1
-misc.c iQCVAwUAQH5IIjEAnp832S/7AQKNJAQAkEpyY3fCG7tvADJFAW9xA7DEQwLCa8YmiUhHvrEsWOI4YgvS7LUbWWc7VqK+ryORvXLKRAVieznbnHAuy0TKtqdnmA/kUmiurS0ah5SWqR/iuAeJtt0RGsmZaZ6oa2m4PZ2Y2GCHSTZqcclvwsetS9eq5AipxHxYFUltu5wGZNI==twM2
-missing-string.c iQCVAwUAQH5JfjEAnp832S/7AQI3ZQQAg55eEJbGQQHyBEJGxvt/FXpQiXcoDit3ZHzvdaQn/NUgdLjCHiWVzhyCXACGivLWMNModDaSaZk073NXxVkWfPcX9vkF//Wugwzidd5P3Bfu5k35o+Xxz82fsk5KuFGGq1mBUZ07xUYQ8KkKkhADUkr0QiQAuypp079Yq0uUC7Q==zvKn
-module.c iQCVAwUAQH5JvjEAnp832S/7AQKlMgQAjZYTXMpWb5kHxCMXzRi069Ku/4/xnWsD+S0dje1LiKzCnRpwTTxARzc/y10Y8OcygkMuR4unEaWedO+9syjjty3fBCcue/j7YlLitq5EC9UE4o23poWvWCuX9Tadm2DK5qf4p7smMJ22O22cLTYTVCyAoYTQ2xC8ajzBsBRkX80==yRRD
-secmem.c iQCVAwUAQH5LLDEAnp832S/7AQKtFwQAwY2wBr6WJC1cwqp/1DQoKzHx9C3plONxbZMazwR7VMI83NUbBAbv1mcxpeZWXmb2dRrnsR1VBbNPDSbJLN5T6czLQ2nIb6mnq9u8Ip4SAa+GCWfDV4AUtAJ4hN/yvWo8iEKu+KD5iJ6xJh31NdXjt5yk6vnk46SA6R4FkHdIEXc==UKVr
-secmem.h iQCVAwUAQH5LTDEAnp832S/7AQIsJwQAkZUu4hvmh9NXCLNm98+tGZFzWYvZO/NffC2wdPE8Q/OTa/m3g+oBbEhaV1ze3oY4t1F/p7ZHFx5CsIp4zVjyPkxlni8AAVMUOQr/LopyxouHn2OjKO+dVqecWQf01+nPWjklbL2FZ3mQ99k2qeWZlVSkz0nm8u39F3v7z3OTCss==AJqE
-sexp.c iQCVAwUAQH5LojEAnp832S/7AQKCTQQArlrj1KGwR2x93fcyN3M0iXuGkBq5R9KNu+1Bq04G4SLlpZ1RRY0OjV3L9To1BHTd01lXlO8MNz7NpRxWlG1Sw5FohbBlhWZQRcW8GdAawJPcfIY2Y8Ek6Yx8quZKbk9uD3bcBmStmg0P+TIA0nr20bmtfB3uX2KQVHQqWZQT5qU==P8FE
-stdmem.c iQCVAwUAQH5LzjEAnp832S/7AQLOUAP9FU16itXBBrkfRDGmhUjAOeEEKdd+brQ3XdT8xoLvP/IH/6U1Kq3ampP2/xcL4kwVdz2rw6NRzP7jlL/yM3tW722lSS/JPJkH+2+qUkcb0fYNoql/WYPMYp1/Mzu6ttXnjag1cQGlKIyYAD+G6h3FtpLwQy0hEJopnF9+Ovd8U7A==CkiZ
-stdmem.h iQCVAwUAQH5L8jEAnp832S/7AQIH0wP+Lyqh0tj++s2L79Tmf/gqgCK+HLMxTddcewF3XbsYf9T5FmLez1gz6Ggti4Ss9VjozOA3ti3trCiA/YNRmV9AYw4zLUPm+MsjJuveL/AgB9HdoD2v+RfJm0WwgSKiysp+8iyjg3Plopmhba4cGuOP5MJ3CWTqYwPmJVscUKC6g38==02MN
-
-types.h iQCVAwUAQH5MKTEAnp832S/7AQLqTAP6A3mUMD5MMkBkebq4bRY6Bq0KsgdKfZ8TLhc2o87gFay8YD0Uom3YJNG2LF/rAIct2ih4jYJaIb5dRfJ0KJoPi2ETd462J8OFCL4fjq9TaSjB2pXcB+kWoxzPasGNg2Ukk0dQ6lvF1tSYrtt32PVI7q/UaPsjTylgRmzLfX/VxrU==OMu3
-
-
-# Configuration
-Makefile.am iQCVAwUAQH5WVjEAnp832S/7AQLmsQP/bbI8/UWAC5yITVhGcCOCbN/FaMqXVKjxESzo6GTs02jxK1y3RuuaoNU1ssQZGAxpFiMJW8u933V3yTHFMxWpwHemDnEyv/a8YACxJBQ0tQgpgHS716BjMbHOfcuOis2WlCOOm0ErjhAYNa4NQ1q3jwkOvTDLFpdnqaWI2wWn08U==Yjun
-libgcrypt.m4 iQCVAwUAQH5MbTEAnp832S/7AQJ1uAQA1C6xI7qXiKVtUeXawhPytAldosrzcXmqz34xi7JklQqw83d68WtWHFMBEUa7MKfi4WCbuQb7FjGUvMRw5z/T9ez7CoDekHc63+cIIZLQ23weUK8GaA1uQLoD0scmT41J5RkBlJbH7ck1zRd3d04o75rWNEUNit6KBvrQ4Pd8oQ8==uMgB
-libgcrypt-config.in iQCVAwUAQH5UbzEAnp832S/7AQJISgP+Nbd2AQnDM/k8sQLbvz8YZjwX3LigZM+AkF1VAwyAm6YOU3nrXnz5t+cXkQD2dkz4L2F0AAsIkFiJsrgmZgCp2h1L6LeFnH+hoId9RhbYw4NkDaHb+MC9JcalpcfFvvxq6vM/W37bSFimM78P+5RLKypXCytVQNAAaIRgZjVfXY8==IGDS
-libgcrypt.vers iQCVAwUAQH5MjTEAnp832S/7AQKCdQQAotG6Z3zdcePI0V33YY2sh91uYkLBNhQw+PzyE3BRRAVhMGLOBD1nSWJHJvE3eyCVOqFY0ZmvpVex51Fa0D/TwsJOO4RVxf1L9bbAncu9OuEXaGXKytLZp54TliDTAWGDq0lvtx1TvDDgtM8TbbaXvMbjfQ4wXBxdLvaenFCTlR4==kgHq
-
-$names$ iQCVAwUAQH5UhDEAnp832S/7AQK/jwP9H7A3mI99M1NGuhD+16C+2gJIITB8GJeYeUd3vm8kWQ5n76WyMCdeA62qn0JUddIBjAbagtfvTL5aesnD9MlhEGaNlHauU7SINTIJ8njKf87EAAfDZrhS/tGDziC2nakMPweRxXQCLDWHkBPjYfrspSLLohjdegqBvTNyVM76+KE==3p9Z
diff --git a/src/ath.c b/src/ath.c
deleted file mode 100644 (file)
index 9085d3e..0000000
--- a/src/ath.c
+++ /dev/null
@@ -1,406 +0,0 @@
-/* ath.c - A Thread-safeness library.
- *  Copyright (C) 2002, 2003, 2004, 2011 Free Software Foundation, Inc.
- *  Copyright (C) 2014 g10 Code GmbH
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser general Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <assert.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#if USE_POSIX_THREADS
-# include <pthread.h>
-#endif
-
-#include "ath.h"
-
-#if USE_POSIX_THREADS_WEAK
-# if  !USE_POSIX_THREADS
-#  error USE_POSIX_THREADS_WEAK but no USE_POSIX_THREADS
-# endif
-#endif
-
-\f
-/* On an ELF system it is easy to use pthreads using weak references.
-   Take care not to test the address of a weak referenced function we
-   actually use; some GCC versions have a bug were &foo != NULL is
-   always evaluated to true in PIC mode.  USING_PTHREAD_AS_DEFAULT is
-   used by ath_install to detect the default usage of pthread.  */
-#if USE_POSIX_THREADS_WEAK
-# pragma weak pthread_cancel
-# pragma weak pthread_mutex_init
-# pragma weak pthread_mutex_lock
-# pragma weak pthread_mutex_unlock
-# pragma weak pthread_mutex_destroy
-#endif
-
-/* For the dummy interface.  The MUTEX_NOTINIT value is used to check
-   that a mutex has been initialized.  */
-#define MUTEX_NOTINIT  ((ath_mutex_t) 0)
-#define MUTEX_UNLOCKED ((ath_mutex_t) 1)
-#define MUTEX_LOCKED   ((ath_mutex_t) 2)
-#define MUTEX_DESTROYED        ((ath_mutex_t) 3)
-
-
-/* Return the thread type from the option field. */
-#define GET_OPTION(a)    ((a) & 0xff)
-
-
-\f
-enum ath_thread_model {
-  ath_model_undefined = 0,
-  ath_model_none,          /* No thread support.  */
-  ath_model_pthreads_weak, /* POSIX threads using weak symbols.  */
-  ath_model_pthreads,      /* POSIX threads directly linked.  */
-  ath_model_w32            /* Microsoft Windows threads.  */
-};
-
-
-/* The thread model in use.  */
-static enum ath_thread_model thread_model;
-
-
-/* Initialize the ath subsystem.  This is called as part of the
-   Libgcrypt initialization.  It's purpose is to initialize the
-   locking system.  It returns 0 on sucess or an ERRNO value on error.
-   In the latter case it is not defined whether ERRNO was changed.
-
-   Note: This should be called as early as possible because it is not
-   always possible to detect the thread model to use while already
-   running multi threaded.  */
-int
-ath_init (void)
-{
-  int err = 0;
-
-  if (thread_model)
-    return 0; /* Already initialized - no error.  */
-
-  if (0)
-    ;
-#if USE_POSIX_THREADS_WEAK
-  else if (pthread_cancel)
-    {
-      thread_model = ath_model_pthreads_weak;
-    }
-#endif
-  else
-    {
-#if HAVE_W32_SYSTEM
-      thread_model = ath_model_w32;
-#elif USE_POSIX_THREADS && !USE_POSIX_THREADS_WEAK
-      thread_model = ath_model_pthreads;
-#else /*!USE_POSIX_THREADS*/
-      /* Assume a single threaded application.  */
-      thread_model = ath_model_none;
-#endif /*!USE_POSIX_THREADS*/
-    }
-
-  return err;
-}
-
-
-/* Return the used thread model as string for display purposes an if
-   R_MODEL is not null store its internal number at R_MODEL.  */
-const char *
-ath_get_model (int *r_model)
-{
-  if (r_model)
-    *r_model = thread_model;
-  switch (thread_model)
-    {
-    case ath_model_undefined:     return "undefined";
-    case ath_model_none:          return "none";
-    case ath_model_pthreads_weak: return "pthread(weak)";
-    case ath_model_pthreads:      return "pthread";
-    case ath_model_w32:           return "w32";
-    default:                      return "?";
-    }
-}
-
-
-/* This function was used in old Libgcrypt versions (via
-   GCRYCTL_SET_THREAD_CBS) to register the thread callback functions.
-   It is not anymore required.  However to allow existing code to
-   continue to work, we keep this function and check that no user
-   defined callbacks are used and that the requested thread system
-   matches the one Libgcrypt is using.  */
-gpg_err_code_t
-ath_install (struct ath_ops *ath_ops)
-{
-  gpg_err_code_t rc;
-  unsigned int thread_option;
-
-  /* Fist call ath_init so that we know our thread model.  */
-  rc = ath_init ();
-  if (rc)
-    return rc;
-
-  /* Check if the requested thread option is compatible to the
-     thread option we are already committed to.  */
-  thread_option = ath_ops? GET_OPTION (ath_ops->option) : 0;
-
-  /* Return an error if the requested thread model does not match the
-     configured one.  */
-  if (0)
-    ;
-#if USE_POSIX_THREADS
-  else if (thread_model == ath_model_pthreads
-           || thread_model == ath_model_pthreads_weak)
-    {
-      if (thread_option == ATH_THREAD_OPTION_PTHREAD)
-        return 0; /* Okay - compatible.  */
-      if (thread_option == ATH_THREAD_OPTION_PTH)
-        return 0; /* Okay - compatible.  */
-    }
-#endif /*USE_POSIX_THREADS*/
-  else if (thread_option == ATH_THREAD_OPTION_PTH)
-    {
-      if (thread_model == ath_model_none)
-        return 0; /* Okay - compatible.  */
-    }
-  else if (thread_option == ATH_THREAD_OPTION_DEFAULT)
-    return 0; /* No thread support requested.  */
-#if HAVE_W32_SYSTEM
-  else
-    return 0; /* It is always enabled.  */
-#endif /*HAVE_W32_SYSTEM*/
-
-  return GPG_ERR_NOT_SUPPORTED;
-}
-
-
-/* Initialize a new mutex.  This function returns 0 on success or an
-   system error code (i.e. an ERRNO value).  ERRNO may or may not be
-   changed on error.  */
-int
-ath_mutex_init (ath_mutex_t *lock)
-{
-  int err;
-
-  switch (thread_model)
-    {
-    case ath_model_none:
-      *lock = MUTEX_UNLOCKED;
-      err = 0;
-      break;
-
-#if USE_POSIX_THREADS
-    case ath_model_pthreads:
-    case ath_model_pthreads_weak:
-      {
-        pthread_mutex_t *plck;
-
-        plck = malloc (sizeof *plck);
-        if (!plck)
-          err = errno? errno : ENOMEM;
-        else
-          {
-            err = pthread_mutex_init (plck, NULL);
-            if (err)
-              free (plck);
-            else
-              *lock = (void*)plck;
-          }
-      }
-      break;
-#endif /*USE_POSIX_THREADS*/
-
-#if HAVE_W32_SYSTEM
-    case ath_model_w32:
-      {
-        CRITICAL_SECTION *csec;
-
-        csec = malloc (sizeof *csec);
-        if (!csec)
-          err = errno? errno : ENOMEM;
-        else
-          {
-            InitializeCriticalSection (csec);
-            *lock = (void*)csec;
-            err = 0;
-          }
-      }
-      break;
-#endif /*HAVE_W32_SYSTEM*/
-
-    default:
-      err = EINVAL;
-      break;
-    }
-
-  return err;
-}
-
-
-/* Destroy a mutex.  This function is a NOP if LOCK is NULL.  If the
-   mutex is still locked it can't be destroyed and the function
-   returns EBUSY.  ERRNO may or may not be changed on error.  */
-int
-ath_mutex_destroy (ath_mutex_t *lock)
-{
-  int err;
-
-  if (!*lock)
-    return 0;
-
-  switch (thread_model)
-    {
-    case ath_model_none:
-      if (*lock != MUTEX_UNLOCKED)
-        err = EBUSY;
-      else
-        {
-          *lock = MUTEX_DESTROYED;
-          err = 0;
-        }
-      break;
-
-#if USE_POSIX_THREADS
-    case ath_model_pthreads:
-    case ath_model_pthreads_weak:
-      {
-        pthread_mutex_t *plck = (pthread_mutex_t*) (*lock);
-
-        err = pthread_mutex_destroy (plck);
-        if (!err)
-          {
-            free (plck);
-            lock = NULL;
-          }
-      }
-      break;
-#endif /*USE_POSIX_THREADS*/
-
-#if HAVE_W32_SYSTEM
-    case ath_model_w32:
-      {
-        CRITICAL_SECTION *csec = (CRITICAL_SECTION *)(*lock);
-
-        DeleteCriticalSection (csec);
-        free (csec);
-        err = 0;
-      }
-      break;
-#endif /*HAVE_W32_SYSTEM*/
-
-    default:
-      err = EINVAL;
-      break;
-    }
-
-  return err;
-}
-
-
-/* Lock the mutex LOCK.  On success the function returns 0; on error
-   an error code.  ERRNO may or may not be changed on error.  */
-int
-ath_mutex_lock (ath_mutex_t *lock)
-{
-  int err;
-
-  switch (thread_model)
-    {
-    case ath_model_none:
-      if (*lock == MUTEX_NOTINIT)
-       err = EINVAL;
-      else if (*lock == MUTEX_UNLOCKED)
-        {
-          *lock = MUTEX_LOCKED;
-          err = 0;
-        }
-      else
-        err = EDEADLK;
-      break;
-
-#if USE_POSIX_THREADS
-    case ath_model_pthreads:
-    case ath_model_pthreads_weak:
-      err = pthread_mutex_lock ((pthread_mutex_t*)(*lock));
-      break;
-#endif /*USE_POSIX_THREADS*/
-
-#if HAVE_W32_SYSTEM
-    case ath_model_w32:
-      {
-        CRITICAL_SECTION *csec = (CRITICAL_SECTION *)(*lock);
-
-        EnterCriticalSection (csec);
-        err = 0;
-      }
-      break;
-#endif /*HAVE_W32_SYSTEM*/
-
-    default:
-      err = EINVAL;
-      break;
-    }
-
-  return err;
-}
-
-/* Unlock the mutex LOCK.  On success the function returns 0; on error
-   an error code.  ERRNO may or may not be changed on error.  */
-int
-ath_mutex_unlock (ath_mutex_t *lock)
-{
-  int err;
-
-  switch (thread_model)
-    {
-    case ath_model_none:
-      if (*lock == MUTEX_NOTINIT)
-       err = EINVAL;
-      else if (*lock == MUTEX_LOCKED)
-        {
-          *lock = MUTEX_UNLOCKED;
-          err = 0;
-        }
-      else
-        err = EPERM;
-      break;
-
-#if USE_POSIX_THREADS
-    case ath_model_pthreads:
-    case ath_model_pthreads_weak:
-      err = pthread_mutex_unlock ((pthread_mutex_t*)(*lock));
-      break;
-#endif /*USE_POSIX_THREADS*/
-
-#if HAVE_W32_SYSTEM
-    case ath_model_w32:
-      {
-        CRITICAL_SECTION *csec = (CRITICAL_SECTION *)(*lock);
-
-        LeaveCriticalSection (csec);
-        err = 0;
-      }
-      break;
-#endif /*HAVE_W32_SYSTEM*/
-
-    default:
-      err = EINVAL;
-      break;
-    }
-
-  return err;
-}
diff --git a/src/ath.h b/src/ath.h
deleted file mode 100644 (file)
index a132e0b..0000000
--- a/src/ath.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/* ath.h - Thread-safeness library.
- * Copyright (C) 2002, 2003, 2004, 2011 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser general Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef ATH_H
-#define ATH_H
-
-#include <config.h>
-
-#ifdef _WIN32
-# include <winsock2.h>
-# include <windows.h>
-#else /* !_WIN32 */
-# ifdef HAVE_SYS_SELECT_H
-#  include <sys/select.h>
-# else
-#  include <sys/time.h>
-# endif
-# include <sys/types.h>
-# ifdef HAVE_SYS_MSG_H
-#  include <sys/msg.h>  /* (e.g. for zOS) */
-# endif
-# include <sys/socket.h>
-#endif /* !_WIN32 */
-#include <gpg-error.h>
-
-
-\f
-/* Define _ATH_EXT_SYM_PREFIX if you want to give all external symbols
-   a prefix.  */
-#define _ATH_EXT_SYM_PREFIX _gcry_
-
-#ifdef _ATH_EXT_SYM_PREFIX
-#define _ATH_PREFIX1(x,y) x ## y
-#define _ATH_PREFIX2(x,y) _ATH_PREFIX1(x,y)
-#define _ATH_PREFIX(x) _ATH_PREFIX2(_ATH_EXT_SYM_PREFIX,x)
-#define ath_install _ATH_PREFIX(ath_install)
-#define ath_init _ATH_PREFIX(ath_init)
-#define ath_get_model _ATH_PREFIX(ath_get_model)
-#define ath_mutex_init _ATH_PREFIX(ath_mutex_init)
-#define ath_mutex_destroy _ATH_PREFIX(ath_mutex_destroy)
-#define ath_mutex_lock _ATH_PREFIX(ath_mutex_lock)
-#define ath_mutex_unlock _ATH_PREFIX(ath_mutex_unlock)
-#endif
-
-\f
-enum ath_thread_option
-  {
-    ATH_THREAD_OPTION_DEFAULT = 0,
-    ATH_THREAD_OPTION_USER = 1,
-    ATH_THREAD_OPTION_PTH = 2,
-    ATH_THREAD_OPTION_PTHREAD = 3
-  };
-
-struct ath_ops
-{
-  /* The OPTION field encodes the thread model and the version number
-     of this structure.
-       Bits  7 - 0  are used for the thread model
-       Bits 15 - 8  are used for the version number.
-  */
-  unsigned int option;
-
-};
-
-gpg_err_code_t ath_install (struct ath_ops *ath_ops);
-int ath_init (void);
-const char *ath_get_model (int *r_model);
-
-/* Functions for mutual exclusion.  */
-typedef void *ath_mutex_t;
-
-int ath_mutex_init (ath_mutex_t *mutex);
-int ath_mutex_destroy (ath_mutex_t *mutex);
-int ath_mutex_lock (ath_mutex_t *mutex);
-int ath_mutex_unlock (ath_mutex_t *mutex);
-
-#endif /* ATH_H */
index 8267791..d1ddc5d 100644 (file)
@@ -92,7 +92,7 @@ typedef const char *(*pk_get_curve_t)(gcry_sexp_t keyparms, int iterator,
 typedef gcry_sexp_t (*pk_get_curve_param_t)(const char *name);
 
 
-/* Module specification structure for public key algoritms.  */
+/* Module specification structure for public key algorithms.  */
 typedef struct gcry_pk_spec
 {
   int algo;
@@ -215,6 +215,9 @@ typedef void (*gcry_md_final_t) (void *c);
 /* Type for the md_read function.  */
 typedef unsigned char *(*gcry_md_read_t) (void *c);
 
+/* Type for the md_extract function.  */
+typedef void (*gcry_md_extract_t) (void *c, void *outbuf, size_t nbytes);
+
 typedef struct gcry_md_oid_spec
 {
   const char *oidstring;
@@ -237,6 +240,7 @@ typedef struct gcry_md_spec
   gcry_md_write_t write;
   gcry_md_final_t final;
   gcry_md_read_t read;
+  gcry_md_extract_t extract;
   size_t contextsize; /* allocate this amount of context */
   selftest_func_t selftest;
 } gcry_md_spec_t;
index 10bfe0c..c4b306a 100644 (file)
@@ -40,6 +40,8 @@
 #define PUBKEY_FLAG_NOCOMP         (1 << 11)
 #define PUBKEY_FLAG_EDDSA          (1 << 12)
 #define PUBKEY_FLAG_GOST           (1 << 13)
+#define PUBKEY_FLAG_NO_KEYTEST     (1 << 14)
+#define PUBKEY_FLAG_DJB_TWEAK      (1 << 15)
 
 
 enum pk_operation
@@ -54,6 +56,7 @@ enum pk_encoding
   {
     PUBKEY_ENC_RAW,
     PUBKEY_ENC_PKCS1,
+    PUBKEY_ENC_PKCS1_RAW,
     PUBKEY_ENC_OAEP,
     PUBKEY_ENC_PSS,
     PUBKEY_ENC_UNKNOWN
@@ -134,6 +137,10 @@ void _gcry_aes_cbc_dec (void *context, unsigned char *iv,
 void _gcry_aes_ctr_enc (void *context, unsigned char *ctr,
                         void *outbuf_arg, const void *inbuf_arg,
                         size_t nblocks);
+size_t _gcry_aes_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
+                           const void *inbuf_arg, size_t nblocks, int encrypt);
+size_t _gcry_aes_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
+                          size_t nblocks);
 
 /*-- blowfish.c --*/
 void _gcry_blowfish_cfb_dec (void *context, unsigned char *iv,
@@ -171,6 +178,24 @@ void _gcry_camellia_cbc_dec (void *context, unsigned char *iv,
 void _gcry_camellia_cfb_dec (void *context, unsigned char *iv,
                              void *outbuf_arg, const void *inbuf_arg,
                              size_t nblocks);
+size_t _gcry_camellia_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
+                                const void *inbuf_arg, size_t nblocks,
+                                int encrypt);
+size_t _gcry_camellia_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
+                               size_t nblocks);
+
+/*-- des.c --*/
+void _gcry_3des_ctr_enc (void *context, unsigned char *ctr,
+                         void *outbuf_arg, const void *inbuf_arg,
+                         size_t nblocks);
+
+void _gcry_3des_cbc_dec (void *context, unsigned char *iv,
+                         void *outbuf_arg, const void *inbuf_arg,
+                         size_t nblocks);
+
+void _gcry_3des_cfb_dec (void *context, unsigned char *iv,
+                         void *outbuf_arg, const void *inbuf_arg,
+                         size_t nblocks);
 
 /*-- serpent.c --*/
 void _gcry_serpent_ctr_enc (void *context, unsigned char *ctr,
@@ -182,6 +207,11 @@ void _gcry_serpent_cbc_dec (void *context, unsigned char *iv,
 void _gcry_serpent_cfb_dec (void *context, unsigned char *iv,
                             void *outbuf_arg, const void *inbuf_arg,
                             size_t nblocks);
+size_t _gcry_serpent_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
+                               const void *inbuf_arg, size_t nblocks,
+                               int encrypt);
+size_t _gcry_serpent_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
+                              size_t nblocks);
 
 /*-- twofish.c --*/
 void _gcry_twofish_ctr_enc (void *context, unsigned char *ctr,
@@ -193,6 +223,11 @@ void _gcry_twofish_cbc_dec (void *context, unsigned char *iv,
 void _gcry_twofish_cfb_dec (void *context, unsigned char *iv,
                             void *outbuf_arg, const void *inbuf_arg,
                             size_t nblocks);
+size_t _gcry_twofish_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
+                               const void *inbuf_arg, size_t nblocks,
+                               int encrypt);
+size_t _gcry_twofish_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
+                              size_t nblocks);
 
 /*-- dsa.c --*/
 void _gcry_register_pk_dsa_progress (gcry_handler_progress_t cbc, void *cb_data);
@@ -237,22 +272,31 @@ extern gcry_cipher_spec_t _gcry_cipher_spec_idea;
 extern gcry_cipher_spec_t _gcry_cipher_spec_salsa20;
 extern gcry_cipher_spec_t _gcry_cipher_spec_salsa20r12;
 extern gcry_cipher_spec_t _gcry_cipher_spec_gost28147;
+extern gcry_cipher_spec_t _gcry_cipher_spec_chacha20;
 
 /* Declarations for the digest specifications.  */
 extern gcry_md_spec_t _gcry_digest_spec_crc32;
 extern gcry_md_spec_t _gcry_digest_spec_crc32_rfc1510;
 extern gcry_md_spec_t _gcry_digest_spec_crc24_rfc2440;
 extern gcry_md_spec_t _gcry_digest_spec_gost3411_94;
+extern gcry_md_spec_t _gcry_digest_spec_gost3411_cp;
 extern gcry_md_spec_t _gcry_digest_spec_stribog_256;
 extern gcry_md_spec_t _gcry_digest_spec_stribog_512;
+extern gcry_md_spec_t _gcry_digest_spec_md2;
 extern gcry_md_spec_t _gcry_digest_spec_md4;
 extern gcry_md_spec_t _gcry_digest_spec_md5;
 extern gcry_md_spec_t _gcry_digest_spec_rmd160;
 extern gcry_md_spec_t _gcry_digest_spec_sha1;
 extern gcry_md_spec_t _gcry_digest_spec_sha224;
 extern gcry_md_spec_t _gcry_digest_spec_sha256;
-extern gcry_md_spec_t _gcry_digest_spec_sha512;
 extern gcry_md_spec_t _gcry_digest_spec_sha384;
+extern gcry_md_spec_t _gcry_digest_spec_sha512;
+extern gcry_md_spec_t _gcry_digest_spec_sha3_224;
+extern gcry_md_spec_t _gcry_digest_spec_sha3_256;
+extern gcry_md_spec_t _gcry_digest_spec_sha3_512;
+extern gcry_md_spec_t _gcry_digest_spec_sha3_384;
+extern gcry_md_spec_t _gcry_digest_spec_shake128;
+extern gcry_md_spec_t _gcry_digest_spec_shake256;
 extern gcry_md_spec_t _gcry_digest_spec_tiger;
 extern gcry_md_spec_t _gcry_digest_spec_tiger1;
 extern gcry_md_spec_t _gcry_digest_spec_tiger2;
index 94e5be9..f77878b 100644 (file)
@@ -47,7 +47,7 @@ struct gcry_context
 
 /* Allocate a fresh generic context of contect TYPE and allocate
    LENGTH extra bytes for private use of the type handler. DEINIT is a
-   fucntion used called to deinitialize the private part; it may be
+   function used called to deinitialize the private part; it may be
    NULL if de-initialization is not required.  Returns NULL and sets
    ERRNO if memory allocation failed.  */
 gcry_ctx_t
index 60ca759..d74fb69 100644 (file)
@@ -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.   */
@@ -80,5 +81,17 @@ gpg_err_code_t   _gcry_ecc_set_mpi (const char *name,
 gpg_err_code_t   _gcry_ecc_set_point (const char *name,
                                       gcry_mpi_point_t newvalue, mpi_ec_t ec);
 
+/*-- cipher/ecc-misc.c --*/
+gcry_err_code_t _gcry_ecc_os2ec (mpi_point_t result, gcry_mpi_t value);
+gpg_err_code_t _gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx,
+                                           mpi_point_t result);
+
+/*-- cipher/ecc-eddsa.c --*/
+gpg_err_code_t _gcry_ecc_eddsa_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx,
+                                            mpi_point_t result,
+                                            unsigned char **r_encpk,
+                                            unsigned int *r_encpklen);
+
+
 
 #endif /*GCRY_EC_CONTEXT_H*/
index 3ab33f9..af3fe2c 100644 (file)
@@ -31,7 +31,6 @@
 #endif /*HAVE_SYSLOG*/
 
 #include "g10lib.h"
-#include "ath.h"
 #include "cipher-proto.h"
 #include "hmac256.h"
 
@@ -69,7 +68,7 @@ static int enforced_fips_mode;
 static int inactive_fips_mode;
 
 /* This is the lock we use to protect the FSM.  */
-static ath_mutex_t fsm_lock;
+GPGRT_LOCK_DEFINE (fsm_lock);
 
 /* The current state of the FSM.  The whole state machinery is only
    used while in fips mode. Change this only while holding fsm_lock. */
@@ -103,7 +102,7 @@ _gcry_initialize_fips_mode (int force)
   static int done;
   gpg_error_t err;
 
-  /* Make sure we are not accidently called twice.  */
+  /* Make sure we are not accidentally called twice.  */
   if (done)
     {
       if ( fips_mode () )
@@ -181,18 +180,18 @@ _gcry_initialize_fips_mode (int force)
       FILE *fp;
 
       /* Intitialize the lock to protect the FSM.  */
-      err = ath_mutex_init (&fsm_lock);
+      err = gpgrt_lock_init (&fsm_lock);
       if (err)
         {
           /* If that fails we can't do anything but abort the
              process. We need to use log_info so that the FSM won't
              get involved.  */
           log_info ("FATAL: failed to create the FSM lock in libgcrypt: %s\n",
-                     strerror (err));
+                    gpg_strerror (err));
 #ifdef HAVE_SYSLOG
           syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
                   "creating FSM lock failed: %s - abort",
-                  strerror (err));
+                  gpg_strerror (err));
 #endif /*HAVE_SYSLOG*/
           abort ();
         }
@@ -222,15 +221,15 @@ lock_fsm (void)
 {
   gpg_error_t err;
 
-  err = ath_mutex_lock (&fsm_lock);
+  err = gpgrt_lock_lock (&fsm_lock);
   if (err)
     {
       log_info ("FATAL: failed to acquire the FSM lock in libgrypt: %s\n",
-                strerror (err));
+                gpg_strerror (err));
 #ifdef HAVE_SYSLOG
       syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
               "acquiring FSM lock failed: %s - abort",
-              strerror (err));
+              gpg_strerror (err));
 #endif /*HAVE_SYSLOG*/
       abort ();
     }
@@ -241,15 +240,15 @@ unlock_fsm (void)
 {
   gpg_error_t err;
 
-  err = ath_mutex_unlock (&fsm_lock);
+  err = gpgrt_lock_unlock (&fsm_lock);
   if (err)
     {
       log_info ("FATAL: failed to release the FSM lock in libgrypt: %s\n",
-                strerror (err));
+                gpg_strerror (err));
 #ifdef HAVE_SYSLOG
       syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
               "releasing FSM lock failed: %s - abort",
-              strerror (err));
+              gpg_strerror (err));
 #endif /*HAVE_SYSLOG*/
       abort ();
     }
@@ -378,7 +377,7 @@ _gcry_fips_is_operational (void)
              (GCRYCTL_INITIALIZATION_FINISHED) where the latter will
              run the selftests.  The drawback of these on-demand
              self-tests are a small chance that self-tests are
-             performed by severeal threads; that is no problem because
+             performed by several threads; that is no problem because
              our FSM make sure that we won't oversee any error. */
           unlock_fsm ();
           _gcry_fips_run_selftests (0);
@@ -519,6 +518,10 @@ run_hmac_selftests (int extended)
       GCRY_MD_SHA256,
       GCRY_MD_SHA384,
       GCRY_MD_SHA512,
+      GCRY_MD_SHA3_224,
+      GCRY_MD_SHA3_256,
+      GCRY_MD_SHA3_384,
+      GCRY_MD_SHA3_512,
       0
     };
   int idx;
@@ -546,7 +549,7 @@ run_pubkey_selftests (int extended)
     {
       GCRY_PK_RSA,
       GCRY_PK_DSA,
-      /* GCRY_PK_ECC is not enabled in fips mode.  */
+      GCRY_PK_ECC,
       0
     };
   int idx;
@@ -634,11 +637,15 @@ check_binary_integrity (void)
                   int n;
 
                   /* The HMAC files consists of lowercase hex digits
-                     only with an optional trailing linefeed.  Fail if
-                     there is any garbage.  */
+                     with an optional trailing linefeed or optional
+                     with two trailing spaces.  The latter format
+                     allows the use of the usual sha1sum format.  Fail
+                     if there is any garbage.  */
                   err = gpg_error (GPG_ERR_SELFTEST_FAILED);
                   n = fread (buffer, 1, sizeof buffer, fp);
-                  if (n == 64 || (n == 65 && buffer[64] == '\n'))
+                  if (n == 64
+                      || (n == 65 && buffer[64] == '\n')
+                      || (n == 66 && buffer[64] == ' ' && buffer[65] == ' '))
                     {
                       buffer[64] = 0;
                       for (n=0, s= buffer;
index 238871d..170ffa1 100644 (file)
@@ -92,7 +92,7 @@
 
 /*-- src/global.c -*/
 int _gcry_global_is_operational (void);
-gcry_error_t _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr);
+gcry_err_code_t _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr);
 void  _gcry_check_heap (const void *a);
 int _gcry_get_debug_flag (unsigned int mask);
 
@@ -189,24 +189,28 @@ int _gcry_log_verbosity( int level );
 /* Compatibility macro.  */
 #define log_mpidump _gcry_log_printmpi
 
+/* Tokeninze STRING and return a malloced array.  */
+char **_gcry_strtokenize (const char *string, const char *delim);
+
 
 /*-- src/hwfeatures.c --*/
-/* (Do not change these values unless synced with the asm code.)  */
-#define HWF_PADLOCK_RNG  1
-#define HWF_PADLOCK_AES  2
-#define HWF_PADLOCK_SHA  4
-#define HWF_PADLOCK_MMUL 8
+#define HWF_PADLOCK_RNG     (1 << 0)
+#define HWF_PADLOCK_AES     (1 << 1)
+#define HWF_PADLOCK_SHA     (1 << 2)
+#define HWF_PADLOCK_MMUL    (1 << 3)
 
-#define HWF_INTEL_CPU    16
-#define HWF_INTEL_BMI2   32
-#define HWF_INTEL_SSSE3  64
-#define HWF_INTEL_PCLMUL 128
-#define HWF_INTEL_AESNI  256
-#define HWF_INTEL_RDRAND 512
-#define HWF_INTEL_AVX    1024
-#define HWF_INTEL_AVX2   2048
+#define HWF_INTEL_CPU       (1 << 4)
+#define HWF_INTEL_FAST_SHLD (1 << 5)
+#define HWF_INTEL_BMI2      (1 << 6)
+#define HWF_INTEL_SSSE3     (1 << 7)
+#define HWF_INTEL_SSE4_1    (1 << 8)
+#define HWF_INTEL_PCLMUL    (1 << 9)
+#define HWF_INTEL_AESNI     (1 << 10)
+#define HWF_INTEL_RDRAND    (1 << 11)
+#define HWF_INTEL_AVX       (1 << 12)
+#define HWF_INTEL_AVX2      (1 << 13)
 
-#define HWF_ARM_NEON     4096
+#define HWF_ARM_NEON        (1 << 14)
 
 
 gpg_err_code_t _gcry_disable_hw_feature (const char *name);
@@ -259,6 +263,9 @@ gpg_err_code_t _gcry_generate_fips186_3_prime
                   int *r_counter,
                   void **r_seed, size_t *r_seedlen, int *r_hashalgo);
 
+gpg_err_code_t _gcry_fips186_4_prime_check (const gcry_mpi_t x,
+                                            unsigned int bits);
+
 
 /* Replacements of missing functions (missing-string.c).  */
 #ifndef HAVE_STPCPY
@@ -314,25 +321,30 @@ void __gcry_burn_stack (unsigned int bytes);
                   } while(0)
 #define wipememory(_ptr,_len) wipememory2(_ptr,0,_len)
 
-#ifdef HAVE_U64_TYPEDEF
-  #define FASTWIPE_T u64
-  #define FASTWIPE_MULT (U64_C(0x0101010101010101))
-#else
-  #define FASTWIPE_T u32
-  #define FASTWIPE_MULT (0x01010101U)
-#endif
+#define FASTWIPE_T u64
+#define FASTWIPE_MULT (U64_C(0x0101010101010101))
 
 /* Following architectures can handle unaligned accesses fast.  */
-#if defined(__i386__) || defined(__x86_64__) || \
-    defined(__powerpc__) || defined(__powerpc64__) || \
-    (defined(__arm__) && defined(__ARM_FEATURE_UNALIGNED)) || \
-    defined(__aarch64__)
+#if defined(HAVE_GCC_ATTRIBUTE_PACKED) && \
+    defined(HAVE_GCC_ATTRIBUTE_ALIGNED) && \
+    (defined(__i386__) || defined(__x86_64__) || \
+     defined(__powerpc__) || defined(__powerpc64__) || \
+     (defined(__arm__) && defined(__ARM_FEATURE_UNALIGNED)) || \
+     defined(__aarch64__))
 #define fast_wipememory2_unaligned_head(_ptr,_set,_len) /*do nothing*/
+typedef struct fast_wipememory_s
+{
+  FASTWIPE_T a;
+} __attribute__((packed, aligned(1))) fast_wipememory_t;
 #else
 #define fast_wipememory2_unaligned_head(_vptr,_vset,_vlen) do { \
               while((size_t)(_vptr)&(sizeof(FASTWIPE_T)-1) && _vlen) \
                 { *_vptr=(_vset); _vptr++; _vlen--; } \
                   } while(0)
+typedef struct fast_wipememory_s
+{
+  FASTWIPE_T a;
+} fast_wipememory_t;
 #endif
 
 /* fast_wipememory2 may leave tail bytes unhandled, in which case tail bytes
@@ -344,8 +356,9 @@ void __gcry_burn_stack (unsigned int bytes);
                 break; \
               _vset_long *= FASTWIPE_MULT; \
               do { \
-                volatile FASTWIPE_T *_vptr_long = (volatile void *)_vptr; \
-                *_vptr_long = _vset_long; \
+                volatile fast_wipememory_t *_vptr_long = \
+                  (volatile void *)_vptr; \
+                _vptr_long->a = _vset_long; \
                 _vlen -= sizeof(FASTWIPE_T); \
                 _vptr += sizeof(FASTWIPE_T); \
               } while (_vlen >= sizeof(FASTWIPE_T)); \
@@ -366,6 +379,7 @@ void __gcry_burn_stack (unsigned int bytes);
 
 gcry_err_code_t _gcry_cipher_init (void);
 gcry_err_code_t _gcry_md_init (void);
+gcry_err_code_t _gcry_mac_init (void);
 gcry_err_code_t _gcry_pk_init (void);
 gcry_err_code_t _gcry_secmem_module_init (void);
 gcry_err_code_t _gcry_mpi_init (void);
index 65dcb4d..d367307 100644 (file)
@@ -129,6 +129,8 @@ gpg_err_code_t _gcry_md_ctl (gcry_md_hd_t hd, int cmd,
                           void *buffer, size_t buflen);
 void _gcry_md_write (gcry_md_hd_t hd, const void *buffer, size_t length);
 unsigned char *_gcry_md_read (gcry_md_hd_t hd, int algo);
+gpg_error_t _gcry_md_extract (gcry_md_hd_t hd, int algo, void *buffer,
+                              size_t length);
 void _gcry_md_hash_buffer (int algo, void *digest,
                            const void *buffer, size_t length);
 gpg_err_code_t _gcry_md_hash_buffers (int algo, unsigned int flags,
@@ -180,6 +182,7 @@ gpg_err_code_t _gcry_mac_write (gcry_mac_hd_t hd, const void *buffer,
 gpg_err_code_t _gcry_mac_read (gcry_mac_hd_t hd, void *buffer, size_t *buflen);
 gpg_err_code_t _gcry_mac_verify (gcry_mac_hd_t hd, const void *buffer,
                                  size_t buflen);
+int _gcry_mac_get_algo (gcry_mac_hd_t hd);
 unsigned int _gcry_mac_get_algo_maclen (int algo);
 unsigned int _gcry_mac_get_algo_keylen (int algo);
 const char *_gcry_mac_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE;
@@ -276,7 +279,7 @@ _gcry_err_code_to_errno (gcry_err_code_t code)
 
 /* Return an error value with the error source SOURCE and the system
    error ERR.  */
-static inline gcry_err_code_t
+static inline gcry_error_t
 _gcry_err_make_from_errno (gpg_err_source_t source, int err)
 {
   return gpg_err_make_from_errno (source, err);
@@ -284,7 +287,7 @@ _gcry_err_make_from_errno (gpg_err_source_t source, int err)
 
 
 /* Return an error value with the system error ERR.  */
-static inline gcry_err_code_t
+static inline gcry_error_t
 _gcry_error_from_errno (int err)
 {
   return gpg_error (gpg_err_code_from_errno (err));
@@ -415,20 +418,17 @@ gcry_mpi_point_t _gcry_mpi_point_set (gcry_mpi_point_t point,
 gcry_mpi_point_t _gcry_mpi_point_snatch_set (gcry_mpi_point_t point,
                                             gcry_mpi_t x, gcry_mpi_t y,
                                             gcry_mpi_t z);
-gpg_error_t _gcry_mpi_ec_new (gcry_ctx_t *r_ctx,
-                             gcry_sexp_t keyparam, const char *curvename);
+
 gcry_mpi_t _gcry_mpi_ec_get_mpi (const char *name, gcry_ctx_t ctx, int copy);
 gcry_mpi_point_t _gcry_mpi_ec_get_point (const char *name,
                                         gcry_ctx_t ctx, int copy);
-gpg_error_t _gcry_mpi_ec_set_mpi (const char *name, gcry_mpi_t newvalue,
-                                 gcry_ctx_t ctx);
-gpg_error_t _gcry_mpi_ec_set_point (const char *name, gcry_mpi_point_t newvalue,
-                                   gcry_ctx_t ctx);
 int _gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_point_t point,
                              mpi_ec_t ctx);
 void _gcry_mpi_ec_dup (gcry_mpi_point_t w, gcry_mpi_point_t u, gcry_ctx_t ctx);
 void _gcry_mpi_ec_add (gcry_mpi_point_t w,
                        gcry_mpi_point_t u, gcry_mpi_point_t v, mpi_ec_t ctx);
+void _gcry_mpi_ec_sub (gcry_mpi_point_t w,
+                       gcry_mpi_point_t u, gcry_mpi_point_t v, mpi_ec_t ctx);
 void _gcry_mpi_ec_mul (gcry_mpi_point_t w, gcry_mpi_t n, gcry_mpi_point_t u,
                        mpi_ec_t ctx);
 int _gcry_mpi_ec_curve_point (gcry_mpi_point_t w, mpi_ec_t ctx);
diff --git a/src/gcrypt-testapi.h b/src/gcrypt-testapi.h
new file mode 100644 (file)
index 0000000..23d3800
--- /dev/null
@@ -0,0 +1,68 @@
+/* gcrypt-testapi.h - Definitiona for the Regression test API
+ * Copyright (C) 2016 g10 Code GmbH
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * WARNING: This is a private API to be used by regression tests.  In
+ * particular this API does not constitute a well defined ABI.  The
+ * header may only be used with its matching Libgcrypt version.
+ */
+
+#ifndef GCRY_GCRYPT_TESTAPI_H
+#define GCRY_GCRYPT_TESTAPI_H
+
+/* For use with gcry_control:  */
+#define PRIV_CTL_INIT_EXTRNG_TEST   58
+#define PRIV_CTL_RUN_EXTRNG_TEST    59
+#define PRIV_CTL_DEINIT_EXTRNG_TEST 60
+#define PRIV_CTL_EXTERNAL_LOCK_TEST 61
+
+#define EXTERNAL_LOCK_TEST_INIT       30111
+#define EXTERNAL_LOCK_TEST_LOCK       30112
+#define EXTERNAL_LOCK_TEST_UNLOCK     30113
+#define EXTERNAL_LOCK_TEST_DESTROY    30114
+
+/* For use with gcry_cipher_ctl:  */
+#define PRIV_CIPHERCTL_DISABLE_WEAK_KEY   61
+#define PRIV_CIPHERCTL_GET_INPUT_VECTOR   62
+
+
+/* Private interfaces for testing of random-drbg.c. */
+struct gcry_drbg_test_vector
+{
+  const char *flagstr;
+  unsigned char *entropy;
+  size_t entropylen;
+  unsigned char *entpra;
+  unsigned char *entprb;
+  size_t entprlen;
+  unsigned char *addtla;
+  unsigned char *addtlb;
+  size_t addtllen;
+  unsigned char *pers;
+  size_t perslen;
+  unsigned char *expected;
+  size_t expectedlen;
+  unsigned char *entropyreseed;
+  size_t entropyreseed_len;
+  unsigned char *addtl_reseed;
+  size_t addtl_reseed_len;
+};
+
+
+#endif /*GCRY_GCRYPT_TESTAPI_H*/
diff --git a/src/gcrypt.h b/src/gcrypt.h
deleted file mode 100644 (file)
index e8768e0..0000000
+++ /dev/null
@@ -1,1683 +0,0 @@
-/* gcrypt.h -  GNU Cryptographic Library Interface              -*- c -*-
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- *               2006, 2007, 2008, 2009, 2010, 2011,
- *               2012  Free Software Foundation, Inc.
- * Copyright (C) 2012, 2013  g10 Code GmbH
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * File: src/gcrypt.h.  Generated from gcrypt.h.in by configure.
- */
-
-#ifndef _GCRYPT_H
-#define _GCRYPT_H
-
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-
-#include <gpg-error.h>
-
-#include <sys/types.h>
-
-#if defined _WIN32 || defined __WIN32__
-# include <winsock2.h>
-# include <ws2tcpip.h>
-# include <time.h>
-# ifndef __GNUC__
-  typedef long ssize_t;
-  typedef int  pid_t;
-# endif /*!__GNUC__*/
-#else
-# include <sys/socket.h>
-# include <sys/time.h>
-# include <sys/select.h>
-#endif /*!_WIN32*/
-
-typedef socklen_t gcry_socklen_t;
-
-/* This is required for error code compatibility. */
-#define _GCRY_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_GCRYPT
-
-#ifdef __cplusplus
-extern "C" {
-#if 0 /* (Keep Emacsens' auto-indent happy.) */
-}
-#endif
-#endif
-
-/* The version of this header should match the one of the library. It
-   should not be used by a program because gcry_check_version() should
-   return the same version.  The purpose of this macro is to let
-   autoconf (using the AM_PATH_GCRYPT macro) check that this header
-   matches the installed library.  */
-#define GCRYPT_VERSION "1.6.2"
-
-/* The version number of this header.  It may be used to handle minor
-   API incompatibilities.  */
-#define GCRYPT_VERSION_NUMBER 0x010602
-
-
-/* Internal: We can't use the convenience macros for the multi
-   precision integer functions when building this library. */
-#ifdef _GCRYPT_IN_LIBGCRYPT
-#ifndef GCRYPT_NO_MPI_MACROS
-#define GCRYPT_NO_MPI_MACROS 1
-#endif
-#endif
-
-/* We want to use gcc attributes when possible.  Warning: Don't use
-   these macros in your programs: As indicated by the leading
-   underscore they are subject to change without notice. */
-#ifdef __GNUC__
-
-#define _GCRY_GCC_VERSION (__GNUC__ * 10000 \
-                             + __GNUC_MINOR__ * 100 \
-                             + __GNUC_PATCHLEVEL__)
-
-#if _GCRY_GCC_VERSION >= 30100
-#define _GCRY_GCC_ATTR_DEPRECATED __attribute__ ((__deprecated__))
-#endif
-
-#if _GCRY_GCC_VERSION >= 29600
-#define _GCRY_GCC_ATTR_PURE  __attribute__ ((__pure__))
-#endif
-
-#if _GCRY_GCC_VERSION >= 30200
-#define _GCRY_GCC_ATTR_MALLOC  __attribute__ ((__malloc__))
-#endif
-
-#define _GCRY_GCC_ATTR_PRINTF(f,a)  __attribute__ ((format (printf,f,a)))
-
-#if _GCRY_GCC_VERSION >= 40000
-#define _GCRY_GCC_ATTR_SENTINEL(a) __attribute__ ((sentinel(a)))
-#endif
-
-#endif /*__GNUC__*/
-
-#ifndef _GCRY_GCC_ATTR_DEPRECATED
-#define _GCRY_GCC_ATTR_DEPRECATED
-#endif
-#ifndef _GCRY_GCC_ATTR_PURE
-#define _GCRY_GCC_ATTR_PURE
-#endif
-#ifndef _GCRY_GCC_ATTR_MALLOC
-#define _GCRY_GCC_ATTR_MALLOC
-#endif
-#ifndef _GCRY_GCC_ATTR_PRINTF
-#define _GCRY_GCC_ATTR_PRINTF(f,a)
-#endif
-#ifndef _GCRY_GCC_ATTR_SENTINEL
-#define _GCRY_GCC_ATTR_SENTINEL(a)
-#endif
-
-/* Make up an attribute to mark functions and types as deprecated but
-   allow internal use by Libgcrypt.  */
-#ifdef _GCRYPT_IN_LIBGCRYPT
-#define _GCRY_ATTR_INTERNAL
-#else
-#define _GCRY_ATTR_INTERNAL    _GCRY_GCC_ATTR_DEPRECATED
-#endif
-
-/* Wrappers for the libgpg-error library.  */
-
-typedef gpg_error_t gcry_error_t;
-typedef gpg_err_code_t gcry_err_code_t;
-typedef gpg_err_source_t gcry_err_source_t;
-
-static GPG_ERR_INLINE gcry_error_t
-gcry_err_make (gcry_err_source_t source, gcry_err_code_t code)
-{
-  return gpg_err_make (source, code);
-}
-
-/* The user can define GPG_ERR_SOURCE_DEFAULT before including this
-   file to specify a default source for gpg_error.  */
-#ifndef GCRY_ERR_SOURCE_DEFAULT
-#define GCRY_ERR_SOURCE_DEFAULT  GPG_ERR_SOURCE_USER_1
-#endif
-
-static GPG_ERR_INLINE gcry_error_t
-gcry_error (gcry_err_code_t code)
-{
-  return gcry_err_make (GCRY_ERR_SOURCE_DEFAULT, code);
-}
-
-static GPG_ERR_INLINE gcry_err_code_t
-gcry_err_code (gcry_error_t err)
-{
-  return gpg_err_code (err);
-}
-
-
-static GPG_ERR_INLINE gcry_err_source_t
-gcry_err_source (gcry_error_t err)
-{
-  return gpg_err_source (err);
-}
-
-/* Return a pointer to a string containing a description of the error
-   code in the error value ERR.  */
-const char *gcry_strerror (gcry_error_t err);
-
-/* Return a pointer to a string containing a description of the error
-   source in the error value ERR.  */
-const char *gcry_strsource (gcry_error_t err);
-
-/* Retrieve the error code for the system error ERR.  This returns
-   GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report
-   this).  */
-gcry_err_code_t gcry_err_code_from_errno (int err);
-
-/* Retrieve the system error for the error code CODE.  This returns 0
-   if CODE is not a system error code.  */
-int gcry_err_code_to_errno (gcry_err_code_t code);
-
-/* Return an error value with the error source SOURCE and the system
-   error ERR.  */
-gcry_error_t gcry_err_make_from_errno (gcry_err_source_t source, int err);
-
-/* Return an error value with the system error ERR.  */
-gcry_err_code_t gcry_error_from_errno (int err);
-
-\f
-/* 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.  */
-
-/* Constants defining the thread model to use.  Used with the OPTION
-   field of the struct gcry_thread_cbs.  */
-#define GCRY_THREAD_OPTION_DEFAULT  0
-#define GCRY_THREAD_OPTION_USER     1
-#define GCRY_THREAD_OPTION_PTH      2
-#define GCRY_THREAD_OPTION_PTHREAD  3
-
-/* The version number encoded in the OPTION field of the struct
-   gcry_thread_cbs.  */
-#define GCRY_THREAD_OPTION_VERSION  1
-
-/* Wrapper for struct ath_ops.  */
-struct gcry_thread_cbs
-{
-  /* The OPTION field encodes the thread model and the version number
-     of this structure.
-       Bits  7 - 0  are used for the thread model
-       Bits 15 - 8  are used for the version number.  */
-  unsigned int option;
-} _GCRY_ATTR_INTERNAL;
-
-#define GCRY_THREAD_OPTION_PTH_IMPL                                     \
-  static struct gcry_thread_cbs gcry_threads_pth = {                    \
-    (GCRY_THREAD_OPTION_PTH | (GCRY_THREAD_OPTION_VERSION << 8))}
-
-#define GCRY_THREAD_OPTION_PTHREAD_IMPL                                 \
-  static struct gcry_thread_cbs gcry_threads_pthread = {                \
-    (GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8))}
-
-
-\f
-/* A generic context object as used by some functions.  */
-struct gcry_context;
-typedef struct gcry_context *gcry_ctx_t;
-
-/* The data objects used to hold multi precision integers.  */
-struct gcry_mpi;
-typedef struct gcry_mpi *gcry_mpi_t;
-struct gcry_mpi_point;
-typedef struct gcry_mpi_point *gcry_mpi_point_t;
-
-#ifndef GCRYPT_NO_DEPRECATED
-typedef struct gcry_mpi *GCRY_MPI _GCRY_GCC_ATTR_DEPRECATED;
-typedef struct gcry_mpi *GcryMPI _GCRY_GCC_ATTR_DEPRECATED;
-#endif
-
-/* A structure used for scatter gather hashing.  */
-typedef struct
-{
-  size_t size;  /* The allocated size of the buffer or 0.  */
-  size_t off;   /* Offset into the buffer.  */
-  size_t len;   /* The used length of the buffer.  */
-  void *data;   /* The buffer.  */
-} gcry_buffer_t;
-
-
-\f
-
-/* Check that the library fulfills the version requirement.  */
-const char *gcry_check_version (const char *req_version);
-
-/* Codes for function dispatchers.  */
-
-/* Codes used with the gcry_control function. */
-enum gcry_ctl_cmds
-  {
-    /* Note: 1 .. 2 are not anymore used. */
-    GCRYCTL_CFB_SYNC = 3,
-    GCRYCTL_RESET    = 4,   /* e.g. for MDs */
-    GCRYCTL_FINALIZE = 5,
-    GCRYCTL_GET_KEYLEN = 6,
-    GCRYCTL_GET_BLKLEN = 7,
-    GCRYCTL_TEST_ALGO = 8,
-    GCRYCTL_IS_SECURE = 9,
-    GCRYCTL_GET_ASNOID = 10,
-    GCRYCTL_ENABLE_ALGO = 11,
-    GCRYCTL_DISABLE_ALGO = 12,
-    GCRYCTL_DUMP_RANDOM_STATS = 13,
-    GCRYCTL_DUMP_SECMEM_STATS = 14,
-    GCRYCTL_GET_ALGO_NPKEY    = 15,
-    GCRYCTL_GET_ALGO_NSKEY    = 16,
-    GCRYCTL_GET_ALGO_NSIGN    = 17,
-    GCRYCTL_GET_ALGO_NENCR    = 18,
-    GCRYCTL_SET_VERBOSITY     = 19,
-    GCRYCTL_SET_DEBUG_FLAGS   = 20,
-    GCRYCTL_CLEAR_DEBUG_FLAGS = 21,
-    GCRYCTL_USE_SECURE_RNDPOOL= 22,
-    GCRYCTL_DUMP_MEMORY_STATS = 23,
-    GCRYCTL_INIT_SECMEM       = 24,
-    GCRYCTL_TERM_SECMEM       = 25,
-    GCRYCTL_DISABLE_SECMEM_WARN = 27,
-    GCRYCTL_SUSPEND_SECMEM_WARN = 28,
-    GCRYCTL_RESUME_SECMEM_WARN  = 29,
-    GCRYCTL_DROP_PRIVS          = 30,
-    GCRYCTL_ENABLE_M_GUARD      = 31,
-    GCRYCTL_START_DUMP          = 32,
-    GCRYCTL_STOP_DUMP           = 33,
-    GCRYCTL_GET_ALGO_USAGE      = 34,
-    GCRYCTL_IS_ALGO_ENABLED     = 35,
-    GCRYCTL_DISABLE_INTERNAL_LOCKING = 36,
-    GCRYCTL_DISABLE_SECMEM      = 37,
-    GCRYCTL_INITIALIZATION_FINISHED = 38,
-    GCRYCTL_INITIALIZATION_FINISHED_P = 39,
-    GCRYCTL_ANY_INITIALIZATION_P = 40,
-    GCRYCTL_SET_CBC_CTS = 41,
-    GCRYCTL_SET_CBC_MAC = 42,
-    /* Note: 43 is not anymore used. */
-    GCRYCTL_ENABLE_QUICK_RANDOM = 44,
-    GCRYCTL_SET_RANDOM_SEED_FILE = 45,
-    GCRYCTL_UPDATE_RANDOM_SEED_FILE = 46,
-    GCRYCTL_SET_THREAD_CBS = 47,
-    GCRYCTL_FAST_POLL = 48,
-    GCRYCTL_SET_RANDOM_DAEMON_SOCKET = 49,
-    GCRYCTL_USE_RANDOM_DAEMON = 50,
-    GCRYCTL_FAKED_RANDOM_P = 51,
-    GCRYCTL_SET_RNDEGD_SOCKET = 52,
-    GCRYCTL_PRINT_CONFIG = 53,
-    GCRYCTL_OPERATIONAL_P = 54,
-    GCRYCTL_FIPS_MODE_P = 55,
-    GCRYCTL_FORCE_FIPS_MODE = 56,
-    GCRYCTL_SELFTEST = 57,
-    /* Note: 58 .. 62 are used internally.  */
-    GCRYCTL_DISABLE_HWF = 63,
-    GCRYCTL_SET_ENFORCED_FIPS_FLAG = 64,
-    GCRYCTL_SET_PREFERRED_RNG_TYPE = 65,
-    GCRYCTL_GET_CURRENT_RNG_TYPE = 66,
-    GCRYCTL_DISABLE_LOCKED_SECMEM = 67,
-    GCRYCTL_DISABLE_PRIV_DROP = 68,
-    GCRYCTL_SET_CCM_LENGTHS = 69,
-    GCRYCTL_CLOSE_RANDOM_DEVICE = 70,
-    GCRYCTL_INACTIVATE_FIPS_FLAG = 71,
-    GCRYCTL_REACTIVATE_FIPS_FLAG = 72
-  };
-
-/* Perform various operations defined by CMD. */
-gcry_error_t gcry_control (enum gcry_ctl_cmds CMD, ...);
-
-\f
-/* S-expression management. */
-
-/* The object to represent an S-expression as used with the public key
-   functions.  */
-struct gcry_sexp;
-typedef struct gcry_sexp *gcry_sexp_t;
-
-#ifndef GCRYPT_NO_DEPRECATED
-typedef struct gcry_sexp *GCRY_SEXP _GCRY_GCC_ATTR_DEPRECATED;
-typedef struct gcry_sexp *GcrySexp _GCRY_GCC_ATTR_DEPRECATED;
-#endif
-
-/* The possible values for the S-expression format. */
-enum gcry_sexp_format
-  {
-    GCRYSEXP_FMT_DEFAULT   = 0,
-    GCRYSEXP_FMT_CANON     = 1,
-    GCRYSEXP_FMT_BASE64    = 2,
-    GCRYSEXP_FMT_ADVANCED  = 3
-  };
-
-/* Create an new S-expression object from BUFFER of size LENGTH and
-   return it in RETSEXP.  With AUTODETECT set to 0 the data in BUFFER
-   is expected to be in canonized format.  */
-gcry_error_t gcry_sexp_new (gcry_sexp_t *retsexp,
-                            const void *buffer, size_t length,
-                            int autodetect);
-
- /* Same as gcry_sexp_new but allows to pass a FREEFNC which has the
-    effect to transfer ownership of BUFFER to the created object.  */
-gcry_error_t gcry_sexp_create (gcry_sexp_t *retsexp,
-                               void *buffer, size_t length,
-                               int autodetect, void (*freefnc) (void *));
-
-/* Scan BUFFER and return a new S-expression object in RETSEXP.  This
-   function expects a printf like string in BUFFER.  */
-gcry_error_t gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
-                              const char *buffer, size_t length);
-
-/* Same as gcry_sexp_sscan but expects a string in FORMAT and can thus
-   only be used for certain encodings.  */
-gcry_error_t gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff,
-                              const char *format, ...);
-
-/* Like gcry_sexp_build, but uses an array instead of variable
-   function arguments.  */
-gcry_error_t gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff,
-                                   const char *format, void **arg_list);
-
-/* Release the S-expression object SEXP */
-void gcry_sexp_release (gcry_sexp_t sexp);
-
-/* Calculate the length of an canonized S-expresion in BUFFER and
-   check for a valid encoding. */
-size_t gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
-                            size_t *erroff, gcry_error_t *errcode);
-
-/* Copies the S-expression object SEXP into BUFFER using the format
-   specified in MODE.  */
-size_t gcry_sexp_sprint (gcry_sexp_t sexp, int mode, void *buffer,
-                         size_t maxlength);
-
-/* Dumps the S-expression object A in a format suitable for debugging
-   to Libgcrypt's logging stream.  */
-void gcry_sexp_dump (const gcry_sexp_t a);
-
-gcry_sexp_t gcry_sexp_cons (const gcry_sexp_t a, const gcry_sexp_t b);
-gcry_sexp_t gcry_sexp_alist (const gcry_sexp_t *array);
-gcry_sexp_t gcry_sexp_vlist (const gcry_sexp_t a, ...);
-gcry_sexp_t gcry_sexp_append (const gcry_sexp_t a, const gcry_sexp_t n);
-gcry_sexp_t gcry_sexp_prepend (const gcry_sexp_t a, const gcry_sexp_t n);
-
-/* Scan the S-expression for a sublist with a type (the car of the
-   list) matching the string TOKEN.  If TOKLEN is not 0, the token is
-   assumed to be raw memory of this length.  The function returns a
-   newly allocated S-expression consisting of the found sublist or
-   `NULL' when not found.  */
-gcry_sexp_t gcry_sexp_find_token (gcry_sexp_t list,
-                                const char *tok, size_t toklen);
-/* Return the length of the LIST.  For a valid S-expression this
-   should be at least 1.  */
-int gcry_sexp_length (const gcry_sexp_t list);
-
-/* Create and return a new S-expression from the element with index
-   NUMBER in LIST.  Note that the first element has the index 0.  If
-   there is no such element, `NULL' is returned.  */
-gcry_sexp_t gcry_sexp_nth (const gcry_sexp_t list, int number);
-
-/* Create and return a new S-expression from the first element in
-   LIST; this called the "type" and should always exist and be a
-   string. `NULL' is returned in case of a problem.  */
-gcry_sexp_t gcry_sexp_car (const gcry_sexp_t list);
-
-/* Create and return a new list form all elements except for the first
-   one.  Note, that this function may return an invalid S-expression
-   because it is not guaranteed, that the type exists and is a string.
-   However, for parsing a complex S-expression it might be useful for
-   intermediate lists.  Returns `NULL' on error.  */
-gcry_sexp_t gcry_sexp_cdr (const gcry_sexp_t list);
-
-gcry_sexp_t gcry_sexp_cadr (const gcry_sexp_t list);
-
-
-/* This function is used to get data from a LIST.  A pointer to the
-   actual data with index NUMBER is returned and the length of this
-   data will be stored to DATALEN.  If there is no data at the given
-   index or the index represents another list, `NULL' is returned.
-   *Note:* The returned pointer is valid as long as LIST is not
-   modified or released.  */
-const char *gcry_sexp_nth_data (const gcry_sexp_t list, int number,
-                                size_t *datalen);
-
-/* This function is used to get data from a LIST.  A malloced buffer to the
-   data with index NUMBER is returned and the length of this
-   data will be stored to RLENGTH.  If there is no data at the given
-   index or the index represents another list, `NULL' is returned.  */
-void *gcry_sexp_nth_buffer (const gcry_sexp_t list, int number,
-                            size_t *rlength);
-
-/* This function is used to get and convert data from a LIST.  The
-   data is assumed to be a Nul terminated string.  The caller must
-   release the returned value using `gcry_free'.  If there is no data
-   at the given index, the index represents a list or the value can't
-   be converted to a string, `NULL' is returned.  */
-char *gcry_sexp_nth_string (gcry_sexp_t list, int number);
-
-/* This function is used to get and convert data from a LIST. This
-   data is assumed to be an MPI stored in the format described by
-   MPIFMT and returned as a standard Libgcrypt MPI.  The caller must
-   release this returned value using `gcry_mpi_release'.  If there is
-   no data at the given index, the index represents a list or the
-   value can't be converted to an MPI, `NULL' is returned.  */
-gcry_mpi_t gcry_sexp_nth_mpi (gcry_sexp_t list, int number, int mpifmt);
-
-/* Convenience fucntion to extract parameters from an S-expression
- * using a list of single letter parameters.  */
-gpg_error_t gcry_sexp_extract_param (gcry_sexp_t sexp,
-                                     const char *path,
-                                     const char *list,
-                                     ...) _GCRY_GCC_ATTR_SENTINEL(0);
-
-\f
-/*******************************************
- *                                         *
- *  Multi Precision Integer Functions      *
- *                                         *
- *******************************************/
-
-/* Different formats of external big integer representation. */
-enum gcry_mpi_format
-  {
-    GCRYMPI_FMT_NONE= 0,
-    GCRYMPI_FMT_STD = 1,    /* Twos complement stored without length.  */
-    GCRYMPI_FMT_PGP = 2,    /* As used by OpenPGP (unsigned only).  */
-    GCRYMPI_FMT_SSH = 3,    /* As used by SSH (like STD but with length).  */
-    GCRYMPI_FMT_HEX = 4,    /* Hex format. */
-    GCRYMPI_FMT_USG = 5,    /* Like STD but unsigned. */
-    GCRYMPI_FMT_OPAQUE = 8  /* Opaque format (some functions only).  */
-  };
-
-/* Flags used for creating big integers.  */
-enum gcry_mpi_flag
-  {
-    GCRYMPI_FLAG_SECURE = 1,  /* Allocate the number in "secure" memory.  */
-    GCRYMPI_FLAG_OPAQUE = 2,  /* The number is not a real one but just
-                                 a way to store some bytes.  This is
-                                 useful for encrypted big integers.  */
-    GCRYMPI_FLAG_IMMUTABLE = 4, /* Mark the MPI as immutable.  */
-    GCRYMPI_FLAG_CONST     = 8, /* Mark the MPI as a constant.  */
-    GCRYMPI_FLAG_USER1 = 0x0100,/* User flag 1.  */
-    GCRYMPI_FLAG_USER2 = 0x0200,/* User flag 2.  */
-    GCRYMPI_FLAG_USER3 = 0x0400,/* User flag 3.  */
-    GCRYMPI_FLAG_USER4 = 0x0800,/* User flag 4.  */
-  };
-
-
-/* Macros to return pre-defined MPI constants.  */
-#define GCRYMPI_CONST_ONE   (_gcry_mpi_get_const (1))
-#define GCRYMPI_CONST_TWO   (_gcry_mpi_get_const (2))
-#define GCRYMPI_CONST_THREE (_gcry_mpi_get_const (3))
-#define GCRYMPI_CONST_FOUR  (_gcry_mpi_get_const (4))
-#define GCRYMPI_CONST_EIGHT (_gcry_mpi_get_const (8))
-
-/* Allocate a new big integer object, initialize it with 0 and
-   initially allocate memory for a number of at least NBITS. */
-gcry_mpi_t gcry_mpi_new (unsigned int nbits);
-
-/* Same as gcry_mpi_new() but allocate in "secure" memory. */
-gcry_mpi_t gcry_mpi_snew (unsigned int nbits);
-
-/* Release the number A and free all associated resources. */
-void gcry_mpi_release (gcry_mpi_t a);
-
-/* Create a new number with the same value as A. */
-gcry_mpi_t gcry_mpi_copy (const gcry_mpi_t a);
-
-/* Store the big integer value U in W and release U.  */
-void gcry_mpi_snatch (gcry_mpi_t w, gcry_mpi_t u);
-
-/* Store the big integer value U in W. */
-gcry_mpi_t gcry_mpi_set (gcry_mpi_t w, const gcry_mpi_t u);
-
-/* Store the unsigned integer value U in W. */
-gcry_mpi_t gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u);
-
-/* Swap the values of A and B. */
-void gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b);
-
-/* Return 1 if A is negative; 0 if zero or positive.  */
-int gcry_mpi_is_neg (gcry_mpi_t a);
-
-/* W = - U */
-void gcry_mpi_neg (gcry_mpi_t w, gcry_mpi_t u);
-
-/* W = [W] */
-void gcry_mpi_abs (gcry_mpi_t w);
-
-/* Compare the big integer number U and V returning 0 for equality, a
-   positive value for U > V and a negative for U < V. */
-int gcry_mpi_cmp (const gcry_mpi_t u, const gcry_mpi_t v);
-
-/* Compare the big integer number U with the unsigned integer V
-   returning 0 for equality, a positive value for U > V and a negative
-   for U < V. */
-int gcry_mpi_cmp_ui (const gcry_mpi_t u, unsigned long v);
-
-/* Convert the external representation of an integer stored in BUFFER
-   with a length of BUFLEN into a newly create MPI returned in
-   RET_MPI.  If NSCANNED is not NULL, it will receive the number of
-   bytes actually scanned after a successful operation. */
-gcry_error_t gcry_mpi_scan (gcry_mpi_t *ret_mpi, enum gcry_mpi_format format,
-                            const void *buffer, size_t buflen,
-                            size_t *nscanned);
-
-/* Convert the big integer A into the external representation
-   described by FORMAT and store it in the provided BUFFER which has
-   been allocated by the user with a size of BUFLEN bytes.  NWRITTEN
-   receives the actual length of the external representation unless it
-   has been passed as NULL. */
-gcry_error_t gcry_mpi_print (enum gcry_mpi_format format,
-                             unsigned char *buffer, size_t buflen,
-                             size_t *nwritten,
-                             const gcry_mpi_t a);
-
-/* Convert the big integer A int the external representation described
-   by FORMAT and store it in a newly allocated buffer which address
-   will be put into BUFFER.  NWRITTEN receives the actual lengths of the
-   external representation. */
-gcry_error_t gcry_mpi_aprint (enum gcry_mpi_format format,
-                              unsigned char **buffer, size_t *nwritten,
-                              const gcry_mpi_t a);
-
-/* Dump the value of A in a format suitable for debugging to
-   Libgcrypt's logging stream.  Note that one leading space but no
-   trailing space or linefeed will be printed.  It is okay to pass
-   NULL for A. */
-void gcry_mpi_dump (const gcry_mpi_t a);
-
-
-/* W = U + V.  */
-void gcry_mpi_add (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v);
-
-/* W = U + V.  V is an unsigned integer. */
-void gcry_mpi_add_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v);
-
-/* W = U + V mod M. */
-void gcry_mpi_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m);
-
-/* W = U - V. */
-void gcry_mpi_sub (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v);
-
-/* W = U - V.  V is an unsigned integer. */
-void gcry_mpi_sub_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v );
-
-/* W = U - V mod M */
-void gcry_mpi_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m);
-
-/* W = U * V. */
-void gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v);
-
-/* W = U * V.  V is an unsigned integer. */
-void gcry_mpi_mul_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v );
-
-/* W = U * V mod M. */
-void gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m);
-
-/* W = U * (2 ^ CNT). */
-void gcry_mpi_mul_2exp (gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt);
-
-/* Q = DIVIDEND / DIVISOR, R = DIVIDEND % DIVISOR,
-   Q or R may be passed as NULL.  ROUND should be negative or 0. */
-void gcry_mpi_div (gcry_mpi_t q, gcry_mpi_t r,
-                   gcry_mpi_t dividend, gcry_mpi_t divisor, int round);
-
-/* R = DIVIDEND % DIVISOR */
-void gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor);
-
-/* W = B ^ E mod M. */
-void gcry_mpi_powm (gcry_mpi_t w,
-                    const gcry_mpi_t b, const gcry_mpi_t e,
-                    const gcry_mpi_t m);
-
-/* Set G to the greatest common divisor of A and B.
-   Return true if the G is 1. */
-int gcry_mpi_gcd (gcry_mpi_t g, gcry_mpi_t a, gcry_mpi_t b);
-
-/* Set X to the multiplicative inverse of A mod M.
-   Return true if the value exists. */
-int gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m);
-
-/* Create a new point object.  NBITS is usually 0.  */
-gcry_mpi_point_t gcry_mpi_point_new (unsigned int nbits);
-
-/* Release the object POINT.  POINT may be NULL. */
-void gcry_mpi_point_release (gcry_mpi_point_t point);
-
-/* Store the projective coordinates from POINT into X, Y, and Z.  */
-void gcry_mpi_point_get (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z,
-                         gcry_mpi_point_t point);
-
-/* Store the projective coordinates from POINT into X, Y, and Z and
-   release POINT.  */
-void gcry_mpi_point_snatch_get (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z,
-                                gcry_mpi_point_t point);
-
-/* Store the projective coordinates X, Y, and Z into POINT.  */
-gcry_mpi_point_t gcry_mpi_point_set (gcry_mpi_point_t point,
-                                     gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z);
-
-/* Store the projective coordinates X, Y, and Z into POINT and release
-   X, Y, and Z.  */
-gcry_mpi_point_t gcry_mpi_point_snatch_set (gcry_mpi_point_t point,
-                                            gcry_mpi_t x, gcry_mpi_t y,
-                                            gcry_mpi_t z);
-
-/* Allocate a new context for elliptic curve operations based on the
-   parameters given by KEYPARAM or using CURVENAME.  */
-gpg_error_t gcry_mpi_ec_new (gcry_ctx_t *r_ctx,
-                             gcry_sexp_t keyparam, const char *curvename);
-
-/* Get a named MPI from an elliptic curve context.  */
-gcry_mpi_t gcry_mpi_ec_get_mpi (const char *name, gcry_ctx_t ctx, int copy);
-
-/* Get a named point from an elliptic curve context.  */
-gcry_mpi_point_t gcry_mpi_ec_get_point (const char *name,
-                                        gcry_ctx_t ctx, int copy);
-
-/* Store a named MPI into an elliptic curve context.  */
-gpg_error_t gcry_mpi_ec_set_mpi (const char *name, gcry_mpi_t newvalue,
-                                 gcry_ctx_t ctx);
-
-/* Store a named point into an elliptic curve context.  */
-gpg_error_t gcry_mpi_ec_set_point (const char *name, gcry_mpi_point_t newvalue,
-                                   gcry_ctx_t ctx);
-
-/* Store the affine coordinates of POINT into X and Y.  */
-int gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_point_t point,
-                            gcry_ctx_t ctx);
-
-/* W = 2 * U.  */
-void gcry_mpi_ec_dup (gcry_mpi_point_t w, gcry_mpi_point_t u, gcry_ctx_t ctx);
-
-/* W = U + V.  */
-void gcry_mpi_ec_add (gcry_mpi_point_t w,
-                      gcry_mpi_point_t u, gcry_mpi_point_t v, gcry_ctx_t ctx);
-
-/* W = N * U.  */
-void gcry_mpi_ec_mul (gcry_mpi_point_t w, gcry_mpi_t n, gcry_mpi_point_t u,
-                      gcry_ctx_t ctx);
-
-/* Return true if POINT is on the curve described by CTX.  */
-int gcry_mpi_ec_curve_point (gcry_mpi_point_t w, gcry_ctx_t ctx);
-
-/* Return the number of bits required to represent A. */
-unsigned int gcry_mpi_get_nbits (gcry_mpi_t a);
-
-/* Return true when bit number N (counting from 0) is set in A. */
-int      gcry_mpi_test_bit (gcry_mpi_t a, unsigned int n);
-
-/* Set bit number N in A. */
-void     gcry_mpi_set_bit (gcry_mpi_t a, unsigned int n);
-
-/* Clear bit number N in A. */
-void     gcry_mpi_clear_bit (gcry_mpi_t a, unsigned int n);
-
-/* Set bit number N in A and clear all bits greater than N. */
-void     gcry_mpi_set_highbit (gcry_mpi_t a, unsigned int n);
-
-/* Clear bit number N in A and all bits greater than N. */
-void     gcry_mpi_clear_highbit (gcry_mpi_t a, unsigned int n);
-
-/* Shift the value of A by N bits to the right and store the result in X. */
-void     gcry_mpi_rshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n);
-
-/* Shift the value of A by N bits to the left and store the result in X. */
-void     gcry_mpi_lshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n);
-
-/* Store NBITS of the value P points to in A and mark A as an opaque
-   value.  On success A received the the ownership of the value P.
-   WARNING: Never use an opaque MPI for anything thing else than
-   gcry_mpi_release, gcry_mpi_get_opaque. */
-gcry_mpi_t gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits);
-
-/* Store NBITS of the value P points to in A and mark A as an opaque
-   value.  The function takes a copy of the provided value P.
-   WARNING: Never use an opaque MPI for anything thing else than
-   gcry_mpi_release, gcry_mpi_get_opaque. */
-gcry_mpi_t gcry_mpi_set_opaque_copy (gcry_mpi_t a,
-                                     const void *p, unsigned int nbits);
-
-/* Return a pointer to an opaque value stored in A and return its size
-   in NBITS.  Note that the returned pointer is still owned by A and
-   that the function should never be used for an non-opaque MPI. */
-void *gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits);
-
-/* Set the FLAG for the big integer A.  Currently only the flag
-   GCRYMPI_FLAG_SECURE is allowed to convert A into an big intger
-   stored in "secure" memory. */
-void gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
-
-/* Clear FLAG for the big integer A.  Note that this function is
-   currently useless as no flags are allowed. */
-void gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
-
-/* Return true if the FLAG is set for A. */
-int gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
-
-/* Private function - do not use.  */
-gcry_mpi_t _gcry_mpi_get_const (int no);
-
-/* Unless the GCRYPT_NO_MPI_MACROS is used, provide a couple of
-   convenience macros for the big integer functions. */
-#ifndef GCRYPT_NO_MPI_MACROS
-#define mpi_new(n)          gcry_mpi_new( (n) )
-#define mpi_secure_new( n ) gcry_mpi_snew( (n) )
-#define mpi_release(a)      \
-  do \
-    { \
-      gcry_mpi_release ((a)); \
-      (a) = NULL; \
-    } \
-  while (0)
-
-#define mpi_copy( a )          gcry_mpi_copy( (a) )
-#define mpi_snatch( w, u)      gcry_mpi_snatch( (w), (u) )
-#define mpi_set( w, u)         gcry_mpi_set( (w), (u) )
-#define mpi_set_ui( w, u)      gcry_mpi_set_ui( (w), (u) )
-#define mpi_abs( w )           gcry_mpi_abs( (w) )
-#define mpi_neg( w, u)         gcry_mpi_neg( (w), (u) )
-#define mpi_cmp( u, v )        gcry_mpi_cmp( (u), (v) )
-#define mpi_cmp_ui( u, v )     gcry_mpi_cmp_ui( (u), (v) )
-#define mpi_is_neg( a )        gcry_mpi_is_neg ((a))
-
-#define mpi_add_ui(w,u,v)      gcry_mpi_add_ui((w),(u),(v))
-#define mpi_add(w,u,v)         gcry_mpi_add ((w),(u),(v))
-#define mpi_addm(w,u,v,m)      gcry_mpi_addm ((w),(u),(v),(m))
-#define mpi_sub_ui(w,u,v)      gcry_mpi_sub_ui ((w),(u),(v))
-#define mpi_sub(w,u,v)         gcry_mpi_sub ((w),(u),(v))
-#define mpi_subm(w,u,v,m)      gcry_mpi_subm ((w),(u),(v),(m))
-#define mpi_mul_ui(w,u,v)      gcry_mpi_mul_ui ((w),(u),(v))
-#define mpi_mul_2exp(w,u,v)    gcry_mpi_mul_2exp ((w),(u),(v))
-#define mpi_mul(w,u,v)         gcry_mpi_mul ((w),(u),(v))
-#define mpi_mulm(w,u,v,m)      gcry_mpi_mulm ((w),(u),(v),(m))
-#define mpi_powm(w,b,e,m)      gcry_mpi_powm ( (w), (b), (e), (m) )
-#define mpi_tdiv(q,r,a,m)      gcry_mpi_div ( (q), (r), (a), (m), 0)
-#define mpi_fdiv(q,r,a,m)      gcry_mpi_div ( (q), (r), (a), (m), -1)
-#define mpi_mod(r,a,m)         gcry_mpi_mod ((r), (a), (m))
-#define mpi_gcd(g,a,b)         gcry_mpi_gcd ( (g), (a), (b) )
-#define mpi_invm(g,a,b)        gcry_mpi_invm ( (g), (a), (b) )
-
-#define mpi_point_new(n)              gcry_mpi_point_new((n))
-#define mpi_point_release(p)                    \
-  do                                            \
-    {                                           \
-      gcry_mpi_point_release ((p));             \
-      (p) = NULL;                               \
-    }                                           \
-  while (0)
-#define mpi_point_get(x,y,z,p)        gcry_mpi_point_get((x),(y),(z),(p))
-#define mpi_point_snatch_get(x,y,z,p) gcry_mpi_point_snatch_get((x),(y),(z),(p))
-#define mpi_point_set(p,x,y,z)        gcry_mpi_point_set((p),(x),(y),(z))
-#define mpi_point_snatch_set(p,x,y,z) gcry_mpi_point_snatch_set((p),(x),(y),(z))
-
-#define mpi_get_nbits(a)       gcry_mpi_get_nbits ((a))
-#define mpi_test_bit(a,b)      gcry_mpi_test_bit ((a),(b))
-#define mpi_set_bit(a,b)       gcry_mpi_set_bit ((a),(b))
-#define mpi_set_highbit(a,b)   gcry_mpi_set_highbit ((a),(b))
-#define mpi_clear_bit(a,b)     gcry_mpi_clear_bit ((a),(b))
-#define mpi_clear_highbit(a,b) gcry_mpi_clear_highbit ((a),(b))
-#define mpi_rshift(a,b,c)      gcry_mpi_rshift ((a),(b),(c))
-#define mpi_lshift(a,b,c)      gcry_mpi_lshift ((a),(b),(c))
-
-#define mpi_set_opaque(a,b,c)  gcry_mpi_set_opaque( (a), (b), (c) )
-#define mpi_get_opaque(a,b)    gcry_mpi_get_opaque( (a), (b) )
-#endif /* GCRYPT_NO_MPI_MACROS */
-
-
-\f
-/************************************
- *                                  *
- *   Symmetric Cipher Functions     *
- *                                  *
- ************************************/
-
-/* The data object used to hold a handle to an encryption object.  */
-struct gcry_cipher_handle;
-typedef struct gcry_cipher_handle *gcry_cipher_hd_t;
-
-#ifndef GCRYPT_NO_DEPRECATED
-typedef struct gcry_cipher_handle *GCRY_CIPHER_HD _GCRY_GCC_ATTR_DEPRECATED;
-typedef struct gcry_cipher_handle *GcryCipherHd _GCRY_GCC_ATTR_DEPRECATED;
-#endif
-
-/* All symmetric encryption algorithms are identified by their IDs.
-   More IDs may be registered at runtime. */
-enum gcry_cipher_algos
-  {
-    GCRY_CIPHER_NONE        = 0,
-    GCRY_CIPHER_IDEA        = 1,
-    GCRY_CIPHER_3DES        = 2,
-    GCRY_CIPHER_CAST5       = 3,
-    GCRY_CIPHER_BLOWFISH    = 4,
-    GCRY_CIPHER_SAFER_SK128 = 5,
-    GCRY_CIPHER_DES_SK      = 6,
-    GCRY_CIPHER_AES         = 7,
-    GCRY_CIPHER_AES192      = 8,
-    GCRY_CIPHER_AES256      = 9,
-    GCRY_CIPHER_TWOFISH     = 10,
-
-    /* Other cipher numbers are above 300 for OpenPGP reasons. */
-    GCRY_CIPHER_ARCFOUR     = 301,  /* Fully compatible with RSA's RC4 (tm). */
-    GCRY_CIPHER_DES         = 302,  /* Yes, this is single key 56 bit DES. */
-    GCRY_CIPHER_TWOFISH128  = 303,
-    GCRY_CIPHER_SERPENT128  = 304,
-    GCRY_CIPHER_SERPENT192  = 305,
-    GCRY_CIPHER_SERPENT256  = 306,
-    GCRY_CIPHER_RFC2268_40  = 307,  /* Ron's Cipher 2 (40 bit). */
-    GCRY_CIPHER_RFC2268_128 = 308,  /* Ron's Cipher 2 (128 bit). */
-    GCRY_CIPHER_SEED        = 309,  /* 128 bit cipher described in RFC4269. */
-    GCRY_CIPHER_CAMELLIA128 = 310,
-    GCRY_CIPHER_CAMELLIA192 = 311,
-    GCRY_CIPHER_CAMELLIA256 = 312,
-    GCRY_CIPHER_SALSA20     = 313,
-    GCRY_CIPHER_SALSA20R12  = 314,
-    GCRY_CIPHER_GOST28147   = 315
-  };
-
-/* The Rijndael algorithm is basically AES, so provide some macros. */
-#define GCRY_CIPHER_AES128      GCRY_CIPHER_AES
-#define GCRY_CIPHER_RIJNDAEL    GCRY_CIPHER_AES
-#define GCRY_CIPHER_RIJNDAEL128 GCRY_CIPHER_AES128
-#define GCRY_CIPHER_RIJNDAEL192 GCRY_CIPHER_AES192
-#define GCRY_CIPHER_RIJNDAEL256 GCRY_CIPHER_AES256
-
-/* The supported encryption modes.  Note that not all of them are
-   supported for each algorithm. */
-enum gcry_cipher_modes
-  {
-    GCRY_CIPHER_MODE_NONE   = 0,  /* Not yet specified. */
-    GCRY_CIPHER_MODE_ECB    = 1,  /* Electronic codebook. */
-    GCRY_CIPHER_MODE_CFB    = 2,  /* Cipher feedback. */
-    GCRY_CIPHER_MODE_CBC    = 3,  /* Cipher block chaining. */
-    GCRY_CIPHER_MODE_STREAM = 4,  /* Used with stream ciphers. */
-    GCRY_CIPHER_MODE_OFB    = 5,  /* Outer feedback. */
-    GCRY_CIPHER_MODE_CTR    = 6,  /* Counter. */
-    GCRY_CIPHER_MODE_AESWRAP= 7,  /* AES-WRAP algorithm.  */
-    GCRY_CIPHER_MODE_CCM    = 8,  /* Counter with CBC-MAC.  */
-    GCRY_CIPHER_MODE_GCM    = 9   /* Galois Counter Mode. */
-  };
-
-/* Flags used with the open function. */
-enum gcry_cipher_flags
-  {
-    GCRY_CIPHER_SECURE      = 1,  /* Allocate in secure memory. */
-    GCRY_CIPHER_ENABLE_SYNC = 2,  /* Enable CFB sync mode. */
-    GCRY_CIPHER_CBC_CTS     = 4,  /* Enable CBC cipher text stealing (CTS). */
-    GCRY_CIPHER_CBC_MAC     = 8   /* Enable CBC message auth. code (MAC). */
-  };
-
-/* GCM works only with blocks of 128 bits */
-#define GCRY_GCM_BLOCK_LEN  (128 / 8)
-
-/* CCM works only with blocks of 128 bits.  */
-#define GCRY_CCM_BLOCK_LEN  (128 / 8)
-
-/* Create a handle for algorithm ALGO to be used in MODE.  FLAGS may
-   be given as an bitwise OR of the gcry_cipher_flags values. */
-gcry_error_t gcry_cipher_open (gcry_cipher_hd_t *handle,
-                              int algo, int mode, unsigned int flags);
-
-/* Close the cioher handle H and release all resource. */
-void gcry_cipher_close (gcry_cipher_hd_t h);
-
-/* Perform various operations on the cipher object H. */
-gcry_error_t gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer,
-                             size_t buflen);
-
-/* Retrieve various information about the cipher object H. */
-gcry_error_t gcry_cipher_info (gcry_cipher_hd_t h, int what, void *buffer,
-                              size_t *nbytes);
-
-/* Retrieve various information about the cipher algorithm ALGO. */
-gcry_error_t gcry_cipher_algo_info (int algo, int what, void *buffer,
-                                   size_t *nbytes);
-
-/* Map the cipher algorithm whose ID is contained in ALGORITHM to a
-   string representation of the algorithm name.  For unknown algorithm
-   IDs this function returns "?".  */
-const char *gcry_cipher_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE;
-
-/* Map the algorithm name NAME to an cipher algorithm ID.  Return 0 if
-   the algorithm name is not known. */
-int gcry_cipher_map_name (const char *name) _GCRY_GCC_ATTR_PURE;
-
-/* Given an ASN.1 object identifier in standard IETF dotted decimal
-   format in STRING, return the encryption mode associated with that
-   OID or 0 if not known or applicable. */
-int gcry_cipher_mode_from_oid (const char *string) _GCRY_GCC_ATTR_PURE;
-
-/* Encrypt the plaintext of size INLEN in IN using the cipher handle H
-   into the buffer OUT which has an allocated length of OUTSIZE.  For
-   most algorithms it is possible to pass NULL for in and 0 for INLEN
-   and do a in-place decryption of the data provided in OUT.  */
-gcry_error_t gcry_cipher_encrypt (gcry_cipher_hd_t h,
-                                  void *out, size_t outsize,
-                                  const void *in, size_t inlen);
-
-/* The counterpart to gcry_cipher_encrypt.  */
-gcry_error_t gcry_cipher_decrypt (gcry_cipher_hd_t h,
-                                  void *out, size_t outsize,
-                                  const void *in, size_t inlen);
-
-/* Set KEY of length KEYLEN bytes for the cipher handle HD.  */
-gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t hd,
-                                 const void *key, size_t keylen);
-
-
-/* Set initialization vector IV of length IVLEN for the cipher handle HD. */
-gcry_error_t gcry_cipher_setiv (gcry_cipher_hd_t hd,
-                                const void *iv, size_t ivlen);
-
-/* Provide additional authentication data for AEAD modes/ciphers.  */
-gcry_error_t gcry_cipher_authenticate (gcry_cipher_hd_t hd, const void *abuf,
-                                       size_t abuflen);
-
-/* Get authentication tag for AEAD modes/ciphers.  */
-gcry_error_t gcry_cipher_gettag (gcry_cipher_hd_t hd, void *outtag,
-                                 size_t taglen);
-
-/* Check authentication tag for AEAD modes/ciphers.  */
-gcry_error_t gcry_cipher_checktag (gcry_cipher_hd_t hd, const void *intag,
-                                   size_t taglen);
-
-/* Reset the handle to the state after open.  */
-#define gcry_cipher_reset(h)  gcry_cipher_ctl ((h), GCRYCTL_RESET, NULL, 0)
-
-/* Perform the OpenPGP sync operation if this is enabled for the
-   cipher handle H. */
-#define gcry_cipher_sync(h)  gcry_cipher_ctl( (h), GCRYCTL_CFB_SYNC, NULL, 0)
-
-/* Enable or disable CTS in future calls to gcry_encrypt(). CBC mode only. */
-#define gcry_cipher_cts(h,on)  gcry_cipher_ctl( (h), GCRYCTL_SET_CBC_CTS, \
-                                                                   NULL, on )
-
-/* Set counter for CTR mode.  (CTR,CTRLEN) must denote a buffer of
-   block size length, or (NULL,0) to set the CTR to the all-zero block. */
-gpg_error_t gcry_cipher_setctr (gcry_cipher_hd_t hd,
-                                const void *ctr, size_t ctrlen);
-
-/* Retrieve the key length in bytes used with algorithm A. */
-size_t gcry_cipher_get_algo_keylen (int algo);
-
-/* Retrieve the block length in bytes used with algorithm A. */
-size_t gcry_cipher_get_algo_blklen (int algo);
-
-/* Return 0 if the algorithm A is available for use. */
-#define gcry_cipher_test_algo(a) \
-            gcry_cipher_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
-
-\f
-/************************************
- *                                  *
- *    Asymmetric Cipher Functions   *
- *                                  *
- ************************************/
-
-/* The algorithms and their IDs we support.  */
-enum gcry_pk_algos
-  {
-    GCRY_PK_RSA   = 1,      /* RSA */
-    GCRY_PK_RSA_E = 2,      /* (deprecated: use 1).  */
-    GCRY_PK_RSA_S = 3,      /* (deprecated: use 1).  */
-    GCRY_PK_ELG_E = 16,     /* (deprecated: use 20). */
-    GCRY_PK_DSA   = 17,     /* Digital Signature Algorithm.  */
-    GCRY_PK_ECC   = 18,     /* Generic ECC.  */
-    GCRY_PK_ELG   = 20,     /* Elgamal       */
-    GCRY_PK_ECDSA = 301,    /* (deprecated: use 18).  */
-    GCRY_PK_ECDH  = 302     /* (deprecated: use 18).  */
-  };
-
-/* Flags describing usage capabilities of a PK algorithm. */
-#define GCRY_PK_USAGE_SIGN 1   /* Good for signatures. */
-#define GCRY_PK_USAGE_ENCR 2   /* Good for encryption. */
-#define GCRY_PK_USAGE_CERT 4   /* Good to certify other keys. */
-#define GCRY_PK_USAGE_AUTH 8   /* Good for authentication. */
-#define GCRY_PK_USAGE_UNKN 128 /* Unknown usage flag. */
-
-/* Modes used with gcry_pubkey_get_sexp.  */
-#define GCRY_PK_GET_PUBKEY 1
-#define GCRY_PK_GET_SECKEY 2
-
-/* Encrypt the DATA using the public key PKEY and store the result as
-   a newly created S-expression at RESULT. */
-gcry_error_t gcry_pk_encrypt (gcry_sexp_t *result,
-                              gcry_sexp_t data, gcry_sexp_t pkey);
-
-/* Decrypt the DATA using the private key SKEY and store the result as
-   a newly created S-expression at RESULT. */
-gcry_error_t gcry_pk_decrypt (gcry_sexp_t *result,
-                              gcry_sexp_t data, gcry_sexp_t skey);
-
-/* Sign the DATA using the private key SKEY and store the result as
-   a newly created S-expression at RESULT. */
-gcry_error_t gcry_pk_sign (gcry_sexp_t *result,
-                           gcry_sexp_t data, gcry_sexp_t skey);
-
-/* Check the signature SIGVAL on DATA using the public key PKEY. */
-gcry_error_t gcry_pk_verify (gcry_sexp_t sigval,
-                             gcry_sexp_t data, gcry_sexp_t pkey);
-
-/* Check that private KEY is sane. */
-gcry_error_t gcry_pk_testkey (gcry_sexp_t key);
-
-/* Generate a new key pair according to the parameters given in
-   S_PARMS.  The new key pair is returned in as an S-expression in
-   R_KEY. */
-gcry_error_t gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms);
-
-/* Catch all function for miscellaneous operations. */
-gcry_error_t gcry_pk_ctl (int cmd, void *buffer, size_t buflen);
-
-/* Retrieve information about the public key algorithm ALGO. */
-gcry_error_t gcry_pk_algo_info (int algo, int what,
-                                void *buffer, size_t *nbytes);
-
-/* Map the public key algorithm whose ID is contained in ALGORITHM to
-   a string representation of the algorithm name.  For unknown
-   algorithm IDs this functions returns "?". */
-const char *gcry_pk_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE;
-
-/* Map the algorithm NAME to a public key algorithm Id.  Return 0 if
-   the algorithm name is not known. */
-int gcry_pk_map_name (const char* name) _GCRY_GCC_ATTR_PURE;
-
-/* Return what is commonly referred as the key length for the given
-   public or private KEY.  */
-unsigned int gcry_pk_get_nbits (gcry_sexp_t key) _GCRY_GCC_ATTR_PURE;
-
-/* Return the so called KEYGRIP which is the SHA-1 hash of the public
-   key parameters expressed in a way depending on the algorithm.  */
-unsigned char *gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array);
-
-/* Return the name of the curve matching KEY.  */
-const char *gcry_pk_get_curve (gcry_sexp_t key, int iterator,
-                               unsigned int *r_nbits);
-
-/* Return an S-expression with the parameters of the named ECC curve
-   NAME.  ALGO must be set to an ECC algorithm.  */
-gcry_sexp_t gcry_pk_get_param (int algo, const char *name);
-
-/* Return 0 if the public key algorithm A is available for use. */
-#define gcry_pk_test_algo(a) \
-            gcry_pk_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
-
-/* Return an S-expression representing the context CTX.  */
-gcry_error_t gcry_pubkey_get_sexp (gcry_sexp_t *r_sexp,
-                                   int mode, gcry_ctx_t ctx);
-
-\f
-
-/************************************
- *                                  *
- *   Cryptograhic Hash Functions    *
- *                                  *
- ************************************/
-
-/* Algorithm IDs for the hash functions we know about. Not all of them
-   are implemnted. */
-enum gcry_md_algos
-  {
-    GCRY_MD_NONE    = 0,
-    GCRY_MD_MD5     = 1,
-    GCRY_MD_SHA1    = 2,
-    GCRY_MD_RMD160  = 3,
-    GCRY_MD_MD2     = 5,
-    GCRY_MD_TIGER   = 6,   /* TIGER/192 as used by gpg <= 1.3.2. */
-    GCRY_MD_HAVAL   = 7,   /* HAVAL, 5 pass, 160 bit. */
-    GCRY_MD_SHA256  = 8,
-    GCRY_MD_SHA384  = 9,
-    GCRY_MD_SHA512  = 10,
-    GCRY_MD_SHA224  = 11,
-    GCRY_MD_MD4     = 301,
-    GCRY_MD_CRC32         = 302,
-    GCRY_MD_CRC32_RFC1510 = 303,
-    GCRY_MD_CRC24_RFC2440 = 304,
-    GCRY_MD_WHIRLPOOL     = 305,
-    GCRY_MD_TIGER1        = 306, /* TIGER fixed.  */
-    GCRY_MD_TIGER2        = 307, /* TIGER2 variant.   */
-    GCRY_MD_GOSTR3411_94  = 308, /* GOST R 34.11-94.  */
-    GCRY_MD_STRIBOG256    = 309, /* GOST R 34.11-2012, 256 bit.  */
-    GCRY_MD_STRIBOG512    = 310  /* GOST R 34.11-2012, 512 bit.  */
-  };
-
-/* Flags used with the open function.  */
-enum gcry_md_flags
-  {
-    GCRY_MD_FLAG_SECURE = 1,  /* Allocate all buffers in "secure" memory.  */
-    GCRY_MD_FLAG_HMAC   = 2,  /* Make an HMAC out of this algorithm.  */
-    GCRY_MD_FLAG_BUGEMU1 = 0x0100
-  };
-
-/* (Forward declaration.)  */
-struct gcry_md_context;
-
-/* This object is used to hold a handle to a message digest object.
-   This structure is private - only to be used by the public gcry_md_*
-   macros.  */
-typedef struct gcry_md_handle
-{
-  /* Actual context.  */
-  struct gcry_md_context *ctx;
-
-  /* Buffer management.  */
-  int  bufpos;
-  int  bufsize;
-  unsigned char buf[1];
-} *gcry_md_hd_t;
-
-/* Compatibility types, do not use them.  */
-#ifndef GCRYPT_NO_DEPRECATED
-typedef struct gcry_md_handle *GCRY_MD_HD _GCRY_GCC_ATTR_DEPRECATED;
-typedef struct gcry_md_handle *GcryMDHd _GCRY_GCC_ATTR_DEPRECATED;
-#endif
-
-/* Create a message digest object for algorithm ALGO.  FLAGS may be
-   given as an bitwise OR of the gcry_md_flags values.  ALGO may be
-   given as 0 if the algorithms to be used are later set using
-   gcry_md_enable.  */
-gcry_error_t gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags);
-
-/* Release the message digest object HD.  */
-void gcry_md_close (gcry_md_hd_t hd);
-
-/* Add the message digest algorithm ALGO to the digest object HD.  */
-gcry_error_t gcry_md_enable (gcry_md_hd_t hd, int algo);
-
-/* Create a new digest object as an exact copy of the object HD.  */
-gcry_error_t gcry_md_copy (gcry_md_hd_t *bhd, gcry_md_hd_t ahd);
-
-/* Reset the digest object HD to its initial state.  */
-void gcry_md_reset (gcry_md_hd_t hd);
-
-/* Perform various operations on the digest object HD. */
-gcry_error_t gcry_md_ctl (gcry_md_hd_t hd, int cmd,
-                          void *buffer, size_t buflen);
-
-/* Pass LENGTH bytes of data in BUFFER to the digest object HD so that
-   it can update the digest values.  This is the actual hash
-   function. */
-void gcry_md_write (gcry_md_hd_t hd, const void *buffer, size_t length);
-
-/* Read out the final digest from HD return the digest value for
-   algorithm ALGO. */
-unsigned char *gcry_md_read (gcry_md_hd_t hd, int algo);
-
-/* Convenience function to calculate the hash from the data in BUFFER
-   of size LENGTH using the algorithm ALGO avoiding the creating of a
-   hash object.  The hash is returned in the caller provided buffer
-   DIGEST which must be large enough to hold the digest of the given
-   algorithm. */
-void gcry_md_hash_buffer (int algo, void *digest,
-                          const void *buffer, size_t length);
-
-/* Convenience function to hash multiple buffers.  */
-gpg_error_t gcry_md_hash_buffers (int algo, unsigned int flags, void *digest,
-                                  const gcry_buffer_t *iov, int iovcnt);
-
-/* Retrieve the algorithm used with HD.  This does not work reliable
-   if more than one algorithm is enabled in HD. */
-int gcry_md_get_algo (gcry_md_hd_t hd);
-
-/* Retrieve the length in bytes of the digest yielded by algorithm
-   ALGO. */
-unsigned int gcry_md_get_algo_dlen (int algo);
-
-/* Return true if the the algorithm ALGO is enabled in the digest
-   object A. */
-int gcry_md_is_enabled (gcry_md_hd_t a, int algo);
-
-/* Return true if the digest object A is allocated in "secure" memory. */
-int gcry_md_is_secure (gcry_md_hd_t a);
-
-/* Retrieve various information about the object H.  */
-gcry_error_t gcry_md_info (gcry_md_hd_t h, int what, void *buffer,
-                          size_t *nbytes);
-
-/* Retrieve various information about the algorithm ALGO.  */
-gcry_error_t gcry_md_algo_info (int algo, int what, void *buffer,
-                               size_t *nbytes);
-
-/* Map the digest algorithm id ALGO to a string representation of the
-   algorithm name.  For unknown algorithms this function returns
-   "?". */
-const char *gcry_md_algo_name (int algo) _GCRY_GCC_ATTR_PURE;
-
-/* Map the algorithm NAME to a digest algorithm Id.  Return 0 if
-   the algorithm name is not known. */
-int gcry_md_map_name (const char* name) _GCRY_GCC_ATTR_PURE;
-
-/* For use with the HMAC feature, the set MAC key to the KEY of
-   KEYLEN bytes. */
-gcry_error_t gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen);
-
-/* Start or stop debugging for digest handle HD; i.e. create a file
-   named dbgmd-<n>.<suffix> while hashing.  If SUFFIX is NULL,
-   debugging stops and the file will be closed. */
-void gcry_md_debug (gcry_md_hd_t hd, const char *suffix);
-
-
-/* Update the hash(s) of H with the character C.  This is a buffered
-   version of the gcry_md_write function. */
-#define gcry_md_putc(h,c)  \
-            do {                                          \
-                gcry_md_hd_t h__ = (h);                   \
-                if( (h__)->bufpos == (h__)->bufsize )     \
-                    gcry_md_write( (h__), NULL, 0 );      \
-                (h__)->buf[(h__)->bufpos++] = (c) & 0xff; \
-            } while(0)
-
-/* Finalize the digest calculation.  This is not really needed because
-   gcry_md_read() does this implicitly. */
-#define gcry_md_final(a) \
-            gcry_md_ctl ((a), GCRYCTL_FINALIZE, NULL, 0)
-
-/* Return 0 if the algorithm A is available for use. */
-#define gcry_md_test_algo(a) \
-            gcry_md_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
-
-/* Return an DER encoded ASN.1 OID for the algorithm A in buffer B. N
-   must point to size_t variable with the available size of buffer B.
-   After return it will receive the actual size of the returned
-   OID. */
-#define gcry_md_get_asnoid(a,b,n) \
-            gcry_md_algo_info((a), GCRYCTL_GET_ASNOID, (b), (n))
-
-\f
-
-/**********************************************
- *                                            *
- *   Message Authentication Code Functions    *
- *                                            *
- **********************************************/
-
-/* The data object used to hold a handle to an encryption object.  */
-struct gcry_mac_handle;
-typedef struct gcry_mac_handle *gcry_mac_hd_t;
-
-/* Algorithm IDs for the hash functions we know about. Not all of them
-   are implemented. */
-enum gcry_mac_algos
-  {
-    GCRY_MAC_NONE               = 0,
-
-    GCRY_MAC_HMAC_SHA256        = 101,
-    GCRY_MAC_HMAC_SHA224        = 102,
-    GCRY_MAC_HMAC_SHA512        = 103,
-    GCRY_MAC_HMAC_SHA384        = 104,
-    GCRY_MAC_HMAC_SHA1          = 105,
-    GCRY_MAC_HMAC_MD5           = 106,
-    GCRY_MAC_HMAC_MD4           = 107,
-    GCRY_MAC_HMAC_RMD160        = 108,
-    GCRY_MAC_HMAC_TIGER1        = 109, /* The fixed TIGER variant */
-    GCRY_MAC_HMAC_WHIRLPOOL     = 110,
-    GCRY_MAC_HMAC_GOSTR3411_94  = 111,
-    GCRY_MAC_HMAC_STRIBOG256    = 112,
-    GCRY_MAC_HMAC_STRIBOG512    = 113,
-
-    GCRY_MAC_CMAC_AES           = 201,
-    GCRY_MAC_CMAC_3DES          = 202,
-    GCRY_MAC_CMAC_CAMELLIA      = 203,
-    GCRY_MAC_CMAC_CAST5         = 204,
-    GCRY_MAC_CMAC_BLOWFISH      = 205,
-    GCRY_MAC_CMAC_TWOFISH       = 206,
-    GCRY_MAC_CMAC_SERPENT       = 207,
-    GCRY_MAC_CMAC_SEED          = 208,
-    GCRY_MAC_CMAC_RFC2268       = 209,
-    GCRY_MAC_CMAC_IDEA          = 210,
-    GCRY_MAC_CMAC_GOST28147     = 211,
-
-    GCRY_MAC_GMAC_AES           = 401,
-    GCRY_MAC_GMAC_CAMELLIA      = 402,
-    GCRY_MAC_GMAC_TWOFISH       = 403,
-    GCRY_MAC_GMAC_SERPENT       = 404,
-    GCRY_MAC_GMAC_SEED          = 405
-  };
-
-/* Flags used with the open function.  */
-enum gcry_mac_flags
-  {
-    GCRY_MAC_FLAG_SECURE = 1,  /* Allocate all buffers in "secure" memory.  */
-  };
-
-/* Create a MAC handle for algorithm ALGO.  FLAGS may be given as an bitwise OR
-   of the gcry_mac_flags values.  CTX maybe NULL or gcry_ctx_t object to be
-   associated with HANDLE.  */
-gcry_error_t gcry_mac_open (gcry_mac_hd_t *handle, int algo,
-                            unsigned int flags, gcry_ctx_t ctx);
-
-/* Close the MAC handle H and release all resource. */
-void gcry_mac_close (gcry_mac_hd_t h);
-
-/* Perform various operations on the MAC object H. */
-gcry_error_t gcry_mac_ctl (gcry_mac_hd_t h, int cmd, void *buffer,
-                           size_t buflen);
-
-/* Retrieve various information about the MAC algorithm ALGO. */
-gcry_error_t gcry_mac_algo_info (int algo, int what, void *buffer,
-                                 size_t *nbytes);
-
-/* Set KEY of length KEYLEN bytes for the MAC handle HD.  */
-gcry_error_t gcry_mac_setkey (gcry_mac_hd_t hd, const void *key,
-                              size_t keylen);
-
-/* Set initialization vector IV of length IVLEN for the MAC handle HD. */
-gcry_error_t gcry_mac_setiv (gcry_mac_hd_t hd, const void *iv,
-                             size_t ivlen);
-
-/* Pass LENGTH bytes of data in BUFFER to the MAC object HD so that
-   it can update the MAC values.  */
-gcry_error_t gcry_mac_write (gcry_mac_hd_t hd, const void *buffer,
-                             size_t length);
-
-/* Read out the final authentication code from the MAC object HD to BUFFER. */
-gcry_error_t gcry_mac_read (gcry_mac_hd_t hd, void *buffer, size_t *buflen);
-
-/* Verify the final authentication code from the MAC object HD with BUFFER. */
-gcry_error_t gcry_mac_verify (gcry_mac_hd_t hd, const void *buffer,
-                              size_t buflen);
-
-/* Retrieve the length in bytes of the MAC yielded by algorithm ALGO. */
-unsigned int gcry_mac_get_algo_maclen (int algo);
-
-/* Retrieve the default key length in bytes used with algorithm A. */
-unsigned int gcry_mac_get_algo_keylen (int algo);
-
-/* Map the MAC algorithm whose ID is contained in ALGORITHM to a
-   string representation of the algorithm name.  For unknown algorithm
-   IDs this function returns "?".  */
-const char *gcry_mac_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE;
-
-/* Map the algorithm name NAME to an MAC algorithm ID.  Return 0 if
-   the algorithm name is not known. */
-int gcry_mac_map_name (const char *name) _GCRY_GCC_ATTR_PURE;
-
-/* Reset the handle to the state after open/setkey.  */
-#define gcry_mac_reset(h)  gcry_mac_ctl ((h), GCRYCTL_RESET, NULL, 0)
-
-/* Return 0 if the algorithm A is available for use. */
-#define gcry_mac_test_algo(a) \
-            gcry_mac_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
-
-\f
-/******************************
- *                            *
- *  Key Derivation Functions  *
- *                            *
- ******************************/
-
-/* Algorithm IDs for the KDFs.  */
-enum gcry_kdf_algos
-  {
-    GCRY_KDF_NONE = 0,
-    GCRY_KDF_SIMPLE_S2K = 16,
-    GCRY_KDF_SALTED_S2K = 17,
-    GCRY_KDF_ITERSALTED_S2K = 19,
-    GCRY_KDF_PBKDF1 = 33,
-    GCRY_KDF_PBKDF2 = 34,
-    GCRY_KDF_SCRYPT = 48
-  };
-
-/* Derive a key from a passphrase.  */
-gpg_error_t gcry_kdf_derive (const void *passphrase, size_t passphraselen,
-                             int algo, int subalgo,
-                             const void *salt, size_t saltlen,
-                             unsigned long iterations,
-                             size_t keysize, void *keybuffer);
-
-
-
-\f
-/************************************
- *                                  *
- *   Random Generating Functions    *
- *                                  *
- ************************************/
-
-/* The type of the random number generator.  */
-enum gcry_rng_types
-  {
-    GCRY_RNG_TYPE_STANDARD   = 1, /* The default CSPRNG generator.  */
-    GCRY_RNG_TYPE_FIPS       = 2, /* The FIPS X9.31 AES generator.  */
-    GCRY_RNG_TYPE_SYSTEM     = 3  /* The system's native generator. */
-  };
-
-/* The possible values for the random quality.  The rule of thumb is
-   to use STRONG for session keys and VERY_STRONG for key material.
-   WEAK is usually an alias for STRONG and should not be used anymore
-   (except with gcry_mpi_randomize); use gcry_create_nonce instead. */
-typedef enum gcry_random_level
-  {
-    GCRY_WEAK_RANDOM = 0,
-    GCRY_STRONG_RANDOM = 1,
-    GCRY_VERY_STRONG_RANDOM = 2
-  }
-gcry_random_level_t;
-
-/* Fill BUFFER with LENGTH bytes of random, using random numbers of
-   quality LEVEL. */
-void gcry_randomize (void *buffer, size_t length,
-                     enum gcry_random_level level);
-
-/* Add the external random from BUFFER with LENGTH bytes into the
-   pool. QUALITY should either be -1 for unknown or in the range of 0
-   to 100 */
-gcry_error_t gcry_random_add_bytes (const void *buffer, size_t length,
-                                    int quality);
-
-/* If random numbers are used in an application, this macro should be
-   called from time to time so that new stuff gets added to the
-   internal pool of the RNG.  */
-#define gcry_fast_random_poll()  gcry_control (GCRYCTL_FAST_POLL, NULL)
-
-
-/* Return NBYTES of allocated random using a random numbers of quality
-   LEVEL. */
-void *gcry_random_bytes (size_t nbytes, enum gcry_random_level level)
-                         _GCRY_GCC_ATTR_MALLOC;
-
-/* Return NBYTES of allocated random using a random numbers of quality
-   LEVEL.  The random numbers are created returned in "secure"
-   memory. */
-void *gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level)
-                                _GCRY_GCC_ATTR_MALLOC;
-
-
-/* Set the big integer W to a random value of NBITS using a random
-   generator with quality LEVEL.  Note that by using a level of
-   GCRY_WEAK_RANDOM gcry_create_nonce is used internally. */
-void gcry_mpi_randomize (gcry_mpi_t w,
-                         unsigned int nbits, enum gcry_random_level level);
-
-
-/* Create an unpredicable nonce of LENGTH bytes in BUFFER. */
-void gcry_create_nonce (void *buffer, size_t length);
-
-
-
-
-\f
-/*******************************/
-/*                             */
-/*    Prime Number Functions   */
-/*                             */
-/*******************************/
-
-/* Mode values passed to a gcry_prime_check_func_t. */
-#define GCRY_PRIME_CHECK_AT_FINISH      0
-#define GCRY_PRIME_CHECK_AT_GOT_PRIME   1
-#define GCRY_PRIME_CHECK_AT_MAYBE_PRIME 2
-
-/* The function should return 1 if the operation shall continue, 0 to
-   reject the prime candidate. */
-typedef int (*gcry_prime_check_func_t) (void *arg, int mode,
-                                        gcry_mpi_t candidate);
-
-/* Flags for gcry_prime_generate():  */
-
-/* Allocate prime numbers and factors in secure memory.  */
-#define GCRY_PRIME_FLAG_SECRET         (1 << 0)
-
-/* Make sure that at least one prime factor is of size
-   `FACTOR_BITS'.  */
-#define GCRY_PRIME_FLAG_SPECIAL_FACTOR (1 << 1)
-
-/* Generate a new prime number of PRIME_BITS bits and store it in
-   PRIME.  If FACTOR_BITS is non-zero, one of the prime factors of
-   (prime - 1) / 2 must be FACTOR_BITS bits long.  If FACTORS is
-   non-zero, allocate a new, NULL-terminated array holding the prime
-   factors and store it in FACTORS.  FLAGS might be used to influence
-   the prime number generation process.  */
-gcry_error_t gcry_prime_generate (gcry_mpi_t *prime,
-                                  unsigned int prime_bits,
-                                  unsigned int factor_bits,
-                                  gcry_mpi_t **factors,
-                                  gcry_prime_check_func_t cb_func,
-                                  void *cb_arg,
-                                  gcry_random_level_t random_level,
-                                  unsigned int flags);
-
-/* Find a generator for PRIME where the factorization of (prime-1) is
-   in the NULL terminated array FACTORS. Return the generator as a
-   newly allocated MPI in R_G.  If START_G is not NULL, use this as
-   teh start for the search. */
-gcry_error_t gcry_prime_group_generator (gcry_mpi_t *r_g,
-                                         gcry_mpi_t prime,
-                                         gcry_mpi_t *factors,
-                                         gcry_mpi_t start_g);
-
-
-/* Convenience function to release the FACTORS array. */
-void gcry_prime_release_factors (gcry_mpi_t *factors);
-
-
-/* Check wether the number X is prime.  */
-gcry_error_t gcry_prime_check (gcry_mpi_t x, unsigned int flags);
-
-
-\f
-/************************************
- *                                  *
- *     Miscellaneous Stuff          *
- *                                  *
- ************************************/
-
-/* Release the context object CTX.  */
-void gcry_ctx_release (gcry_ctx_t ctx);
-
-/* Log data using Libgcrypt's own log interface.  */
-void gcry_log_debug (const char *fmt, ...) _GCRY_GCC_ATTR_PRINTF(1,2);
-void gcry_log_debughex (const char *text, const void *buffer, size_t length);
-void gcry_log_debugmpi (const char *text, gcry_mpi_t mpi);
-void gcry_log_debugpnt (const char *text,
-                        gcry_mpi_point_t point, gcry_ctx_t ctx);
-void gcry_log_debugsxp (const char *text, gcry_sexp_t sexp);
-
-
-/* Log levels used by the internal logging facility. */
-enum gcry_log_levels
-  {
-    GCRY_LOG_CONT   = 0,    /* (Continue the last log line.) */
-    GCRY_LOG_INFO   = 10,
-    GCRY_LOG_WARN   = 20,
-    GCRY_LOG_ERROR  = 30,
-    GCRY_LOG_FATAL  = 40,
-    GCRY_LOG_BUG    = 50,
-    GCRY_LOG_DEBUG  = 100
-  };
-
-/* Type for progress handlers.  */
-typedef void (*gcry_handler_progress_t) (void *, const char *, int, int, int);
-
-/* Type for memory allocation handlers.  */
-typedef void *(*gcry_handler_alloc_t) (size_t n);
-
-/* Type for secure memory check handlers.  */
-typedef int (*gcry_handler_secure_check_t) (const void *);
-
-/* Type for memory reallocation handlers.  */
-typedef void *(*gcry_handler_realloc_t) (void *p, size_t n);
-
-/* Type for memory free handlers.  */
-typedef void (*gcry_handler_free_t) (void *);
-
-/* Type for out-of-memory handlers.  */
-typedef int (*gcry_handler_no_mem_t) (void *, size_t, unsigned int);
-
-/* Type for fatal error handlers.  */
-typedef void (*gcry_handler_error_t) (void *, int, const char *);
-
-/* Type for logging handlers.  */
-typedef void (*gcry_handler_log_t) (void *, int, const char *, va_list);
-
-/* Certain operations can provide progress information.  This function
-   is used to register a handler for retrieving these information. */
-void gcry_set_progress_handler (gcry_handler_progress_t cb, void *cb_data);
-
-
-/* Register a custom memory allocation functions. */
-void gcry_set_allocation_handler (
-                             gcry_handler_alloc_t func_alloc,
-                             gcry_handler_alloc_t func_alloc_secure,
-                             gcry_handler_secure_check_t func_secure_check,
-                             gcry_handler_realloc_t func_realloc,
-                             gcry_handler_free_t func_free);
-
-/* Register a function used instead of the internal out of memory
-   handler. */
-void gcry_set_outofcore_handler (gcry_handler_no_mem_t h, void *opaque);
-
-/* Register a function used instead of the internal fatal error
-   handler. */
-void gcry_set_fatalerror_handler (gcry_handler_error_t fnc, void *opaque);
-
-/* Register a function used instead of the internal logging
-   facility. */
-void gcry_set_log_handler (gcry_handler_log_t f, void *opaque);
-
-/* Reserved for future use. */
-void gcry_set_gettext_handler (const char *(*f)(const char*));
-
-/* Libgcrypt uses its own memory allocation.  It is important to use
-   gcry_free () to release memory allocated by libgcrypt. */
-void *gcry_malloc (size_t n) _GCRY_GCC_ATTR_MALLOC;
-void *gcry_calloc (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
-void *gcry_malloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC;
-void *gcry_calloc_secure (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
-void *gcry_realloc (void *a, size_t n);
-char *gcry_strdup (const char *string) _GCRY_GCC_ATTR_MALLOC;
-void *gcry_xmalloc (size_t n) _GCRY_GCC_ATTR_MALLOC;
-void *gcry_xcalloc (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
-void *gcry_xmalloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC;
-void *gcry_xcalloc_secure (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
-void *gcry_xrealloc (void *a, size_t n);
-char *gcry_xstrdup (const char * a) _GCRY_GCC_ATTR_MALLOC;
-void  gcry_free (void *a);
-
-/* Return true if A is allocated in "secure" memory. */
-int gcry_is_secure (const void *a) _GCRY_GCC_ATTR_PURE;
-
-/* Return true if Libgcrypt is in FIPS mode.  */
-#define gcry_fips_mode_active()  !!gcry_control (GCRYCTL_FIPS_MODE_P, 0)
-
-
-#if 0 /* (Keep Emacsens' auto-indent happy.) */
-{
-#endif
-#ifdef __cplusplus
-}
-#endif
-#endif /* _GCRYPT_H */
-/*
-Local Variables:
-buffer-read-only: t
-End:
-*/
index 81c2128..02b8772 100644 (file)
@@ -1,8 +1,6 @@
 /* gcrypt.h -  GNU Cryptographic Library Interface              -*- c -*-
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- *               2006, 2007, 2008, 2009, 2010, 2011,
- *               2012  Free Software Foundation, Inc.
- * Copyright (C) 2012, 2013  g10 Code GmbH
+ * Copyright (C) 1998-2016 Free Software Foundation, Inc.
+ * Copyright (C) 2012-2016 g10 Code GmbH
  *
  * This file is part of Libgcrypt.
  *
@@ -329,7 +327,11 @@ enum gcry_ctl_cmds
     GCRYCTL_SET_CCM_LENGTHS = 69,
     GCRYCTL_CLOSE_RANDOM_DEVICE = 70,
     GCRYCTL_INACTIVATE_FIPS_FLAG = 71,
-    GCRYCTL_REACTIVATE_FIPS_FLAG = 72
+    GCRYCTL_REACTIVATE_FIPS_FLAG = 72,
+    GCRYCTL_SET_SBOX = 73,
+    GCRYCTL_DRBG_REINIT = 74,
+    GCRYCTL_SET_TAGLEN = 75,
+    GCRYCTL_GET_TAGLEN = 76
   };
 
 /* Perform various operations defined by CMD. */
@@ -470,8 +472,51 @@ char *gcry_sexp_nth_string (gcry_sexp_t list, int number);
    value can't be converted to an MPI, `NULL' is returned.  */
 gcry_mpi_t gcry_sexp_nth_mpi (gcry_sexp_t list, int number, int mpifmt);
 
-/* Convenience fucntion to extract parameters from an S-expression
- * using a list of single letter parameters.  */
+/* Extract MPIs from an s-expression using a list of parameters.  The
+ * names of these parameters are given by the string LIST.  Some
+ * special characters may be given to control the conversion:
+ *
+ *    + :: Switch to unsigned integer format (default).
+ *    - :: Switch to standard signed format.
+ *    / :: Switch to opaque format.
+ *    & :: Switch to buffer descriptor mode - see below.
+ *    ? :: The previous parameter is optional.
+ *
+ * In general parameter names are single letters.  To use a string for
+ * a parameter name, enclose the name in single quotes.
+ *
+ * Unless in gcry_buffer_t mode for each parameter name a pointer to
+ * an MPI variable is expected that must be set to NULL prior to
+ * invoking this function, and finally a NULL is expected.  Example:
+ *
+ *   _gcry_sexp_extract_param (key, NULL, "n/x+ed",
+ *                             &mpi_n, &mpi_x, &mpi_e, NULL)
+ *
+ * This stores the parameter "N" from KEY as an unsigned MPI into
+ * MPI_N, the parameter "X" as an opaque MPI into MPI_X, and the
+ * parameter "E" again as an unsigned MPI into MPI_E.
+ *
+ * If in buffer descriptor mode a pointer to gcry_buffer_t descriptor
+ * is expected instead of a pointer to an MPI.  The caller may use two
+ * different operation modes: If the DATA field of the provided buffer
+ * descriptor is NULL, the function allocates a new buffer and stores
+ * it at DATA; the other fields are set accordingly with OFF being 0.
+ * If DATA is not NULL, the function assumes that DATA, SIZE, and OFF
+ * describe a buffer where to but the data; on return the LEN field
+ * receives the number of bytes copied to that buffer; if the buffer
+ * is too small, the function immediately returns with an error code
+ * (and LEN set to 0).
+ *
+ * PATH is an optional string used to locate a token.  The exclamation
+ * mark separated tokens are used to via gcry_sexp_find_token to find
+ * a start point inside SEXP.
+ *
+ * The function returns 0 on success.  On error an error code is
+ * returned, all passed MPIs that might have been allocated up to this
+ * point are deallocated and set to NULL, and all passed buffers are
+ * either truncated if the caller supplied the buffer, or deallocated
+ * if the function allocated the buffer.
+ */
 gpg_error_t gcry_sexp_extract_param (gcry_sexp_t sexp,
                                      const char *path,
                                      const char *list,
@@ -508,7 +553,7 @@ enum gcry_mpi_flag
     GCRYMPI_FLAG_USER1 = 0x0100,/* User flag 1.  */
     GCRYMPI_FLAG_USER2 = 0x0200,/* User flag 2.  */
     GCRYMPI_FLAG_USER3 = 0x0400,/* User flag 3.  */
-    GCRYMPI_FLAG_USER4 = 0x0800,/* User flag 4.  */
+    GCRYMPI_FLAG_USER4 = 0x0800 /* User flag 4.  */
   };
 
 
@@ -580,7 +625,7 @@ gcry_error_t gcry_mpi_print (enum gcry_mpi_format format,
                              size_t *nwritten,
                              const gcry_mpi_t a);
 
-/* Convert the big integer A int the external representation described
+/* Convert the big integer A into the external representation described
    by FORMAT and store it in a newly allocated buffer which address
    will be put into BUFFER.  NWRITTEN receives the actual lengths of the
    external representation. */
@@ -691,6 +736,10 @@ gpg_error_t gcry_mpi_ec_set_mpi (const char *name, gcry_mpi_t newvalue,
 gpg_error_t gcry_mpi_ec_set_point (const char *name, gcry_mpi_point_t newvalue,
                                    gcry_ctx_t ctx);
 
+/* Decode and store VALUE into RESULT.  */
+gpg_error_t gcry_mpi_ec_decode_point (gcry_mpi_point_t result,
+                                      gcry_mpi_t value, gcry_ctx_t ctx);
+
 /* Store the affine coordinates of POINT into X and Y.  */
 int gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_point_t point,
                             gcry_ctx_t ctx);
@@ -702,6 +751,10 @@ void gcry_mpi_ec_dup (gcry_mpi_point_t w, gcry_mpi_point_t u, gcry_ctx_t ctx);
 void gcry_mpi_ec_add (gcry_mpi_point_t w,
                       gcry_mpi_point_t u, gcry_mpi_point_t v, gcry_ctx_t ctx);
 
+/* W = U - V.  */
+void gcry_mpi_ec_sub (gcry_mpi_point_t w,
+                      gcry_mpi_point_t u, gcry_mpi_point_t v, gcry_ctx_t ctx);
+
 /* W = N * U.  */
 void gcry_mpi_ec_mul (gcry_mpi_point_t w, gcry_mpi_t n, gcry_mpi_point_t u,
                       gcry_ctx_t ctx);
@@ -880,7 +933,8 @@ enum gcry_cipher_algos
     GCRY_CIPHER_CAMELLIA256 = 312,
     GCRY_CIPHER_SALSA20     = 313,
     GCRY_CIPHER_SALSA20R12  = 314,
-    GCRY_CIPHER_GOST28147   = 315
+    GCRY_CIPHER_GOST28147   = 315,
+    GCRY_CIPHER_CHACHA20    = 316
   };
 
 /* The Rijndael algorithm is basically AES, so provide some macros. */
@@ -894,16 +948,19 @@ enum gcry_cipher_algos
    supported for each algorithm. */
 enum gcry_cipher_modes
   {
-    GCRY_CIPHER_MODE_NONE   = 0,  /* Not yet specified. */
-    GCRY_CIPHER_MODE_ECB    = 1,  /* Electronic codebook. */
-    GCRY_CIPHER_MODE_CFB    = 2,  /* Cipher feedback. */
-    GCRY_CIPHER_MODE_CBC    = 3,  /* Cipher block chaining. */
-    GCRY_CIPHER_MODE_STREAM = 4,  /* Used with stream ciphers. */
-    GCRY_CIPHER_MODE_OFB    = 5,  /* Outer feedback. */
-    GCRY_CIPHER_MODE_CTR    = 6,  /* Counter. */
-    GCRY_CIPHER_MODE_AESWRAP= 7,  /* AES-WRAP algorithm.  */
-    GCRY_CIPHER_MODE_CCM    = 8,  /* Counter with CBC-MAC.  */
-    GCRY_CIPHER_MODE_GCM    = 9   /* Galois Counter Mode. */
+    GCRY_CIPHER_MODE_NONE     = 0,   /* Not yet specified. */
+    GCRY_CIPHER_MODE_ECB      = 1,   /* Electronic codebook. */
+    GCRY_CIPHER_MODE_CFB      = 2,   /* Cipher feedback. */
+    GCRY_CIPHER_MODE_CBC      = 3,   /* Cipher block chaining. */
+    GCRY_CIPHER_MODE_STREAM   = 4,   /* Used with stream ciphers. */
+    GCRY_CIPHER_MODE_OFB      = 5,   /* Outer feedback. */
+    GCRY_CIPHER_MODE_CTR      = 6,   /* Counter. */
+    GCRY_CIPHER_MODE_AESWRAP  = 7,   /* AES-WRAP algorithm.  */
+    GCRY_CIPHER_MODE_CCM      = 8,   /* Counter with CBC-MAC.  */
+    GCRY_CIPHER_MODE_GCM      = 9,   /* Galois Counter Mode. */
+    GCRY_CIPHER_MODE_POLY1305 = 10,  /* Poly1305 based AEAD mode. */
+    GCRY_CIPHER_MODE_OCB      = 11,  /* OCB3 mode.  */
+    GCRY_CIPHER_MODE_CFB8     = 12   /* Cipher feedback (8 bit mode). */
   };
 
 /* Flags used with the open function. */
@@ -921,12 +978,15 @@ enum gcry_cipher_flags
 /* CCM works only with blocks of 128 bits.  */
 #define GCRY_CCM_BLOCK_LEN  (128 / 8)
 
+/* OCB works only with blocks of 128 bits.  */
+#define GCRY_OCB_BLOCK_LEN  (128 / 8)
+
 /* Create a handle for algorithm ALGO to be used in MODE.  FLAGS may
    be given as an bitwise OR of the gcry_cipher_flags values. */
 gcry_error_t gcry_cipher_open (gcry_cipher_hd_t *handle,
                               int algo, int mode, unsigned int flags);
 
-/* Close the cioher handle H and release all resource. */
+/* Close the cipher handle H and release all resource. */
 void gcry_cipher_close (gcry_cipher_hd_t h);
 
 /* Perform various operations on the cipher object H. */
@@ -1000,6 +1060,14 @@ gcry_error_t gcry_cipher_checktag (gcry_cipher_hd_t hd, const void *intag,
 #define gcry_cipher_cts(h,on)  gcry_cipher_ctl( (h), GCRYCTL_SET_CBC_CTS, \
                                                                    NULL, on )
 
+#define gcry_cipher_set_sbox(h,oid) gcry_cipher_ctl( (h), GCRYCTL_SET_SBOX, \
+                                                     (oid), 0);
+
+/* Indicate to the encrypt and decrypt functions that the next call
+   provides the final data.  Only used with some modes.  */
+#define gcry_cipher_final(a) \
+            gcry_cipher_ctl ((a), GCRYCTL_FINALIZE, NULL, 0)
+
 /* Set counter for CTR mode.  (CTR,CTRLEN) must denote a buffer of
    block size length, or (NULL,0) to set the CTR to the all-zero block. */
 gpg_error_t gcry_cipher_setctr (gcry_cipher_hd_t hd,
@@ -1032,8 +1100,9 @@ enum gcry_pk_algos
     GCRY_PK_DSA   = 17,     /* Digital Signature Algorithm.  */
     GCRY_PK_ECC   = 18,     /* Generic ECC.  */
     GCRY_PK_ELG   = 20,     /* Elgamal       */
-    GCRY_PK_ECDSA = 301,    /* (deprecated: use 18).  */
-    GCRY_PK_ECDH  = 302     /* (deprecated: use 18).  */
+    GCRY_PK_ECDSA = 301,    /* (only for external use).  */
+    GCRY_PK_ECDH  = 302,    /* (only for external use).  */
+    GCRY_PK_EDDSA = 303     /* (only for external use).  */
   };
 
 /* Flags describing usage capabilities of a PK algorithm. */
@@ -1123,7 +1192,7 @@ gcry_error_t gcry_pubkey_get_sexp (gcry_sexp_t *r_sexp,
  ************************************/
 
 /* Algorithm IDs for the hash functions we know about. Not all of them
-   are implemnted. */
+   are implemented. */
 enum gcry_md_algos
   {
     GCRY_MD_NONE    = 0,
@@ -1137,7 +1206,8 @@ enum gcry_md_algos
     GCRY_MD_SHA384  = 9,
     GCRY_MD_SHA512  = 10,
     GCRY_MD_SHA224  = 11,
-    GCRY_MD_MD4     = 301,
+
+    GCRY_MD_MD4           = 301,
     GCRY_MD_CRC32         = 302,
     GCRY_MD_CRC32_RFC1510 = 303,
     GCRY_MD_CRC24_RFC2440 = 304,
@@ -1146,7 +1216,14 @@ enum gcry_md_algos
     GCRY_MD_TIGER2        = 307, /* TIGER2 variant.   */
     GCRY_MD_GOSTR3411_94  = 308, /* GOST R 34.11-94.  */
     GCRY_MD_STRIBOG256    = 309, /* GOST R 34.11-2012, 256 bit.  */
-    GCRY_MD_STRIBOG512    = 310  /* GOST R 34.11-2012, 512 bit.  */
+    GCRY_MD_STRIBOG512    = 310, /* GOST R 34.11-2012, 512 bit.  */
+    GCRY_MD_GOSTR3411_CP  = 311, /* GOST R 34.11-94 with CryptoPro-A S-Box.  */
+    GCRY_MD_SHA3_224      = 312,
+    GCRY_MD_SHA3_256      = 313,
+    GCRY_MD_SHA3_384      = 314,
+    GCRY_MD_SHA3_512      = 315,
+    GCRY_MD_SHAKE128      = 316,
+    GCRY_MD_SHAKE256      = 317
   };
 
 /* Flags used with the open function.  */
@@ -1211,6 +1288,11 @@ void gcry_md_write (gcry_md_hd_t hd, const void *buffer, size_t length);
    algorithm ALGO. */
 unsigned char *gcry_md_read (gcry_md_hd_t hd, int algo);
 
+/* Read more output from algorithm ALGO to BUFFER of size LENGTH from
+ * digest object HD. Algorithm needs to be 'expendable-output function'. */
+gpg_error_t gcry_md_extract (gcry_md_hd_t hd, int algo, void *buffer,
+                             size_t length);
+
 /* Convenience function to calculate the hash from the data in BUFFER
    of size LENGTH using the algorithm ALGO avoiding the creating of a
    hash object.  The hash is returned in the caller provided buffer
@@ -1322,6 +1404,11 @@ enum gcry_mac_algos
     GCRY_MAC_HMAC_GOSTR3411_94  = 111,
     GCRY_MAC_HMAC_STRIBOG256    = 112,
     GCRY_MAC_HMAC_STRIBOG512    = 113,
+    GCRY_MAC_HMAC_MD2           = 114,
+    GCRY_MAC_HMAC_SHA3_224      = 115,
+    GCRY_MAC_HMAC_SHA3_256      = 116,
+    GCRY_MAC_HMAC_SHA3_384      = 117,
+    GCRY_MAC_HMAC_SHA3_512      = 118,
 
     GCRY_MAC_CMAC_AES           = 201,
     GCRY_MAC_CMAC_3DES          = 202,
@@ -1339,13 +1426,20 @@ enum gcry_mac_algos
     GCRY_MAC_GMAC_CAMELLIA      = 402,
     GCRY_MAC_GMAC_TWOFISH       = 403,
     GCRY_MAC_GMAC_SERPENT       = 404,
-    GCRY_MAC_GMAC_SEED          = 405
+    GCRY_MAC_GMAC_SEED          = 405,
+
+    GCRY_MAC_POLY1305           = 501,
+    GCRY_MAC_POLY1305_AES       = 502,
+    GCRY_MAC_POLY1305_CAMELLIA  = 503,
+    GCRY_MAC_POLY1305_TWOFISH   = 504,
+    GCRY_MAC_POLY1305_SERPENT   = 505,
+    GCRY_MAC_POLY1305_SEED      = 506
   };
 
 /* Flags used with the open function.  */
 enum gcry_mac_flags
   {
-    GCRY_MAC_FLAG_SECURE = 1,  /* Allocate all buffers in "secure" memory.  */
+    GCRY_MAC_FLAG_SECURE = 1   /* Allocate all buffers in "secure" memory.  */
   };
 
 /* Create a MAC handle for algorithm ALGO.  FLAGS may be given as an bitwise OR
@@ -1385,6 +1479,9 @@ gcry_error_t gcry_mac_read (gcry_mac_hd_t hd, void *buffer, size_t *buflen);
 gcry_error_t gcry_mac_verify (gcry_mac_hd_t hd, const void *buffer,
                               size_t buflen);
 
+/* Retrieve the algorithm used with MAC. */
+int gcry_mac_get_algo (gcry_mac_hd_t hd);
+
 /* Retrieve the length in bytes of the MAC yielded by algorithm ALGO. */
 unsigned int gcry_mac_get_algo_maclen (int algo);
 
@@ -1548,7 +1645,7 @@ gcry_error_t gcry_prime_generate (gcry_mpi_t *prime,
 /* Find a generator for PRIME where the factorization of (prime-1) is
    in the NULL terminated array FACTORS. Return the generator as a
    newly allocated MPI in R_G.  If START_G is not NULL, use this as
-   teh start for the search. */
+   the start for the search. */
 gcry_error_t gcry_prime_group_generator (gcry_mpi_t *r_g,
                                          gcry_mpi_t prime,
                                          gcry_mpi_t *factors,
index 6f9cbf9..8669a46 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
  *               2004, 2005, 2006, 2008, 2011,
  *               2012  Free Software Foundation, Inc.
- * Copyright (C) 2013 g10 Code GmbH
+ * Copyright (C) 2013, 2014 g10 Code GmbH
  *
  * This file is part of Libgcrypt.
  *
 #endif /*HAVE_SYSLOG*/
 
 #include "g10lib.h"
+#include "gcrypt-testapi.h"
 #include "cipher.h"
 #include "stdmem.h" /* our own memory allocator */
 #include "secmem.h" /* our own secmem allocator */
-#include "ath.h"
+
 
 \f
 
@@ -88,14 +89,6 @@ global_init (void)
   /* Tell the random module that we have seen an init call.  */
   _gcry_set_preferred_rng_type (0);
 
-  /* Initialize our portable thread/mutex wrapper.  */
-  err = ath_init ();
-  if (err)
-    {
-      err = gpg_error_from_errno (err);
-      goto fail;
-    }
-
   /* See whether the system is in FIPS mode.  This needs to come as
      early as possible but after ATH has been initialized.  */
   _gcry_initialize_fips_mode (force_fips_mode);
@@ -112,6 +105,9 @@ global_init (void)
   err = _gcry_md_init ();
   if (err)
     goto fail;
+  err = _gcry_mac_init ();
+  if (err)
+    goto fail;
   err = _gcry_pk_init ();
   if (err)
     goto fail;
@@ -306,7 +302,6 @@ print_config ( int (*fnc)(FILE *fp, const char *format, ...), FILE *fp)
 #endif
        ":\n");
   fnc (fp, "mpi-asm:%s:\n", _gcry_mpi_get_hw_config ());
-  fnc (fp, "threads:%s:\n", ath_get_model (NULL));
   hwfeatures = _gcry_get_hw_features ();
   fnc (fp, "hwflist:");
   for (i=0; (s = _gcry_enum_hw_features (i, &afeature)); i++)
@@ -314,7 +309,7 @@ print_config ( int (*fnc)(FILE *fp, const char *format, ...), FILE *fp)
       fnc (fp, "%s:", s);
   fnc (fp, "\n");
   /* We use y/n instead of 1/0 for the simple reason that Emacsen's
-     compile error parser would accidently flag that line when printed
+     compile error parser would accidentally flag that line when printed
      during "make check" as an error.  */
   fnc (fp, "fips-mode:%c:%c:\n",
        fips_mode ()? 'y':'n',
@@ -478,10 +473,10 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
       break;
 
     case GCRYCTL_SET_THREAD_CBS:
+      /* This is now a dummy call.  We used to install our own thread
+         library here. */
       _gcry_set_preferred_rng_type (0);
-      rc = ath_install (va_arg (arg_ptr, void *));
-      if (!rc)
-       global_init ();
+      global_init ();
       break;
 
     case GCRYCTL_FAST_POLL:
@@ -499,7 +494,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
       _gcry_set_preferred_rng_type (0);
       rc = _gcry_rndegd_set_socket_name (va_arg (arg_ptr, const char *));
 #else
-      rc = gpg_error (GPG_ERR_NOT_SUPPORTED);
+      rc = GPG_ERR_NOT_SUPPORTED;
 #endif
       break;
 
@@ -584,41 +579,25 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
 # pragma GCC diagnostic push
 # pragma GCC diagnostic ignored "-Wswitch"
 #endif
-    case 58:  /* Init external random test.  */
-      {
-        void **rctx        = va_arg (arg_ptr, void **);
-        unsigned int flags = va_arg (arg_ptr, unsigned int);
-        const void *key    = va_arg (arg_ptr, const void *);
-        size_t keylen      = va_arg (arg_ptr, size_t);
-        const void *seed   = va_arg (arg_ptr, const void *);
-        size_t seedlen     = va_arg (arg_ptr, size_t);
-        const void *dt     = va_arg (arg_ptr, const void *);
-        size_t dtlen       = va_arg (arg_ptr, size_t);
-        if (!fips_is_operational ())
-          rc = fips_not_operational ();
-        else
-          rc = _gcry_random_init_external_test (rctx, flags, key, keylen,
-                                                seed, seedlen, dt, dtlen);
-      }
+    case PRIV_CTL_INIT_EXTRNG_TEST:  /* Init external random test.  */
+      rc = GPG_ERR_NOT_SUPPORTED;
       break;
-    case 59:  /* Run external random test.  */
+    case PRIV_CTL_RUN_EXTRNG_TEST:  /* Run external DRBG test.  */
       {
-        void *ctx     = va_arg (arg_ptr, void *);
-        void *buffer  = va_arg (arg_ptr, void *);
-        size_t buflen = va_arg (arg_ptr, size_t);
-        if (!fips_is_operational ())
-          rc = fips_not_operational ();
+        struct gcry_drbg_test_vector *test =
+         va_arg (arg_ptr, struct gcry_drbg_test_vector *);
+        unsigned char *buf = va_arg (arg_ptr, unsigned char *);
+
+        if (buf)
+          rc = _gcry_rngdrbg_cavs_test (test, buf);
         else
-          rc = _gcry_random_run_external_test (ctx, buffer, buflen);
+          rc = _gcry_rngdrbg_healthcheck_one (test);
       }
       break;
-    case 60:  /* Deinit external random test.  */
-      {
-        void *ctx = va_arg (arg_ptr, void *);
-        _gcry_random_deinit_external_test (ctx);
-      }
+    case PRIV_CTL_DEINIT_EXTRNG_TEST:  /* Deinit external random test.  */
+      rc = GPG_ERR_NOT_SUPPORTED;
       break;
-    case 61:  /* Run external lock test */
+    case PRIV_CTL_EXTERNAL_LOCK_TEST:  /* Run external lock test */
       rc = external_lock_test (va_arg (arg_ptr, int));
       break;
     case 62:  /* RFU */
@@ -680,6 +659,20 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
       rc = GPG_ERR_NOT_IMPLEMENTED;
       break;
 
+    case GCRYCTL_DRBG_REINIT:
+      {
+        const char *flagstr = va_arg (arg_ptr, const char *);
+        gcry_buffer_t *pers = va_arg (arg_ptr, gcry_buffer_t *);
+        int npers = va_arg (arg_ptr, int);
+        if (va_arg (arg_ptr, void *) || npers < 0)
+          rc = GPG_ERR_INV_ARG;
+        else if (_gcry_get_rng_type (!any_init_done) != GCRY_RNG_TYPE_FIPS)
+          rc = GPG_ERR_NOT_SUPPORTED;
+        else
+          rc = _gcry_rngdrbg_reinit (flagstr, pers, npers);
+      }
+      break;
+
     default:
       _gcry_set_preferred_rng_type (0);
       rc = GPG_ERR_INV_OP;
@@ -876,7 +869,7 @@ _gcry_free (void *p)
     return;
 
   /* In case ERRNO is set we better save it so that the free machinery
-     may not accidently change ERRNO.  We restore it only if it was
+     may not accidentally change ERRNO.  We restore it only if it was
      already set to comply with the usual C semantic for ERRNO.  */
   save_errno = errno;
   if (free_func)
@@ -1142,25 +1135,25 @@ _gcry_set_progress_handler (void (*cb)(void *,const char*,int, int, int),
 static gpg_err_code_t
 external_lock_test (int cmd)
 {
-  static ath_mutex_t testlock;
+  GPGRT_LOCK_DEFINE (testlock);
   gpg_err_code_t rc = 0;
 
   switch (cmd)
     {
     case 30111:  /* Init Lock.  */
-      rc = ath_mutex_init (&testlock);
+      rc = gpgrt_lock_init (&testlock);
       break;
 
     case 30112:  /* Take Lock.  */
-      rc = ath_mutex_lock (&testlock);
+      rc = gpgrt_lock_lock (&testlock);
       break;
 
     case 30113:  /* Release Lock.  */
-      rc = ath_mutex_unlock (&testlock);
+      rc = gpgrt_lock_unlock (&testlock);
       break;
 
     case 30114:  /* Destroy Lock.  */
-      rc = ath_mutex_destroy (&testlock);
+      rc = gpgrt_lock_destroy (&testlock);
       break;
 
     default:
index 94a26da..ca1eb75 100644 (file)
@@ -426,10 +426,8 @@ _gcry_hmac256_finalize (hmac256_context_t hd, size_t *r_dlen)
 
       tmphd = _gcry_hmac256_new (NULL, 0);
       if (!tmphd)
-        {
-          free (hd);
-          return NULL;
-        }
+       return NULL;
+
       _gcry_hmac256_update (tmphd, hd->opad, 64);
       _gcry_hmac256_update (tmphd, hd->buf, 32);
       finalize (tmphd);
@@ -648,6 +646,7 @@ main (int argc, char **argv)
   size_t n, dlen, idx;
   int use_stdin = 0;
   int use_binary = 0;
+  int use_stdkey = 0;
 
   assert (sizeof (u32) == 4);
 #ifdef __WIN32
@@ -691,11 +690,16 @@ main (int argc, char **argv)
           argc--; argv++;
           use_binary = 1;
         }
+      else if (!strcmp (*argv, "--stdkey"))
+        {
+          argc--; argv++;
+          use_stdkey = 1;
+        }
     }
 
   if (argc < 1)
     {
-      fprintf (stderr, "usage: %s [--binary] key [filename]\n", pgm);
+      fprintf (stderr, "usage: %s [--binary] [--stdkey] key [filename]\n", pgm);
       exit (1);
     }
 
@@ -704,7 +708,7 @@ main (int argc, char **argv)
     setmode (fileno (stdout), O_BINARY);
 #endif
 
-  key = *argv;
+  key = use_stdkey? "What am I, a doctor or a moonshuttle conductor?" : *argv;
   argc--, argv++;
   keylen = strlen (key);
   use_stdin = !argc;
index aa4bfd7..3dc050e 100644 (file)
@@ -1,5 +1,5 @@
 /* hwf-arm.c - Detect hardware features - ARM part
- * Copyright © 2013  Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013  Jussi Kivilinna <jussi.kivilinna@iki.fi>
  *
  * This file is part of Libgcrypt.
  *
@@ -98,17 +98,32 @@ detect_arm_at_hwcap(void)
 #define HAS_PROC_CPUINFO 1
 
 static unsigned int
-detect_arm_proc_cpuinfo(void)
+detect_arm_proc_cpuinfo(unsigned int *broken_hwfs)
 {
   char buf[1024]; /* large enough */
   char *str_features, *str_neon;
+  int cpu_implementer, cpu_arch, cpu_variant, cpu_part, cpu_revision;
   FILE *f;
   int readlen, i;
   static int cpuinfo_initialized = 0;
   static unsigned int stored_cpuinfo_features;
+  static unsigned int stored_broken_hwfs;
+  struct {
+    const char *name;
+    int *value;
+  } cpu_entries[5] = {
+    { "CPU implementer", &cpu_implementer },
+    { "CPU architecture", &cpu_arch },
+    { "CPU variant", &cpu_variant },
+    { "CPU part", &cpu_part },
+    { "CPU revision", &cpu_revision },
+  };
 
   if (cpuinfo_initialized)
-    return stored_cpuinfo_features;
+    {
+      *broken_hwfs |= stored_broken_hwfs;
+      return stored_cpuinfo_features;
+    }
 
   f = fopen("/proc/cpuinfo", "r");
   if (!f)
@@ -124,12 +139,32 @@ detect_arm_proc_cpuinfo(void)
 
   cpuinfo_initialized = 1;
   stored_cpuinfo_features = 0;
+  stored_broken_hwfs = 0;
 
   /* Find features line. */
   str_features = strstr(buf, "Features");
   if (!str_features)
     return stored_cpuinfo_features;
 
+  /* Find CPU version information. */
+  for (i = 0; i < DIM(cpu_entries); i++)
+    {
+      char *str;
+
+      *cpu_entries[i].value = -1;
+
+      str = strstr(buf, cpu_entries[i].name);
+      if (!str)
+        continue;
+
+      str = strstr(str, ": ");
+      if (!str)
+        continue;
+
+      str += 2;
+      *cpu_entries[i].value = strtoul(str, NULL, 0);
+    }
+
   /* Lines to strings. */
   for (i = 0; i < sizeof(buf); i++)
     if (buf[i] == '\n')
@@ -140,6 +175,19 @@ detect_arm_proc_cpuinfo(void)
   if (str_neon && (str_neon[5] == ' ' || str_neon[5] == '\0'))
     stored_cpuinfo_features |= HWF_ARM_NEON;
 
+  /* Check for CPUs with broken NEON implementation. See
+   * https://code.google.com/p/chromium/issues/detail?id=341598
+   */
+  if (cpu_implementer == 0x51
+      && cpu_arch == 7
+      && cpu_variant == 1
+      && cpu_part == 0x4d
+      && cpu_revision == 0)
+    {
+      stored_broken_hwfs = HWF_ARM_NEON;
+    }
+
+  *broken_hwfs |= stored_broken_hwfs;
   return stored_cpuinfo_features;
 }
 
@@ -149,18 +197,21 @@ unsigned int
 _gcry_hwf_detect_arm (void)
 {
   unsigned int ret = 0;
+  unsigned int broken_hwfs = 0;
 
 #if defined (HAS_SYS_AT_HWCAP)
   ret |= detect_arm_at_hwcap ();
 #endif
 
 #if defined (HAS_PROC_CPUINFO)
-  ret |= detect_arm_proc_cpuinfo ();
+  ret |= detect_arm_proc_cpuinfo (&broken_hwfs);
 #endif
 
 #if defined(__ARM_NEON__) && defined(ENABLE_NEON_SUPPORT)
   ret |= HWF_ARM_NEON;
 #endif
 
+  ret &= ~broken_hwfs;
+
   return ret;
 }
index 0591b4f..eeacccb 100644 (file)
@@ -81,7 +81,7 @@ get_cpuid(unsigned int in, unsigned int *eax, unsigned int *ebx,
      "cpuid\n\t"
      "movl %%ebx, %1\n\t"
      "popl %%ebx\n\t"            /* Restore GOT register. */
-     : "=a" (regs[0]), "=r" (regs[1]), "=c" (regs[2]), "=d" (regs[3])
+     : "=a" (regs[0]), "=D" (regs[1]), "=c" (regs[2]), "=d" (regs[3])
      : "0" (in), "1" (0), "2" (0), "3" (0)
      : "cc"
      );
@@ -96,19 +96,21 @@ get_cpuid(unsigned int in, unsigned int *eax, unsigned int *ebx,
     *edx = regs[3];
 }
 
+#if defined(ENABLE_AVX_SUPPORT) || defined(ENABLE_AVX2_SUPPORT)
 static unsigned int
 get_xgetbv(void)
 {
-  unsigned int t_eax;
+  unsigned int t_eax, t_edx;
 
   asm volatile
     ("xgetbv\n\t"
-     : "=a" (t_eax)
+     : "=a" (t_eax), "=d" (t_edx)
      : "c" (0)
     );
 
   return t_eax;
 }
+#endif /* ENABLE_AVX_SUPPORT || ENABLE_AVX2_SUPPORT */
 
 #endif /* i386 && GNUC */
 
@@ -145,19 +147,21 @@ get_cpuid(unsigned int in, unsigned int *eax, unsigned int *ebx,
     *edx = regs[3];
 }
 
+#if defined(ENABLE_AVX_SUPPORT) || defined(ENABLE_AVX2_SUPPORT)
 static unsigned int
 get_xgetbv(void)
 {
-  unsigned int t_eax;
+  unsigned int t_eax, t_edx;
 
   asm volatile
     ("xgetbv\n\t"
-     : "=a" (t_eax)
+     : "=a" (t_eax), "=d" (t_edx)
      : "c" (0)
     );
 
   return t_eax;
 }
+#endif /* ENABLE_AVX_SUPPORT || ENABLE_AVX2_SUPPORT */
 
 #endif /* x86-64 && GNUC */
 
@@ -170,6 +174,7 @@ detect_x86_gnuc (void)
   unsigned int features;
   unsigned int os_supports_avx_avx2_registers = 0;
   unsigned int max_cpuid_level;
+  unsigned int fms, family, model;
   unsigned int result = 0;
 
   (void)os_supports_avx_avx2_registers;
@@ -232,8 +237,37 @@ detect_x86_gnuc (void)
   /* Detect Intel features, that might also be supported by other
      vendors.  */
 
-  /* Get CPU info and Intel feature flags (ECX).  */
-  get_cpuid(1, NULL, NULL, &features, NULL);
+  /* Get CPU family/model/stepping (EAX) and Intel feature flags (ECX).  */
+  get_cpuid(1, &fms, NULL, &features, NULL);
+
+  family = ((fms & 0xf00) >> 8) + ((fms & 0xff00000) >> 20);
+  model = ((fms & 0xf0) >> 4) + ((fms & 0xf0000) >> 12);
+
+  if ((result & HWF_INTEL_CPU) && family == 6)
+    {
+      /* These Intel Core processor models have SHLD/SHRD instruction that
+       * can do integer rotation faster actual ROL/ROR instructions. */
+      switch (model)
+       {
+       case 0x2A:
+       case 0x2D:
+       case 0x3A:
+       case 0x3C:
+       case 0x3F:
+       case 0x45:
+       case 0x46:
+       case 0x3D:
+       case 0x4F:
+       case 0x56:
+       case 0x47:
+       case 0x4E:
+       case 0x5E:
+       case 0x55:
+       case 0x66:
+         result |= HWF_INTEL_FAST_SHLD;
+         break;
+       }
+    }
 
 #ifdef ENABLE_PCLMUL_SUPPORT
   /* Test bit 1 for PCLMUL.  */
@@ -243,6 +277,9 @@ detect_x86_gnuc (void)
   /* Test bit 9 for SSSE3.  */
   if (features & 0x00000200)
      result |= HWF_INTEL_SSSE3;
+  /* Test bit 19 for SSE4.1.  */
+  if (features & 0x00080000)
+     result |= HWF_INTEL_SSE4_1;
 #ifdef ENABLE_AESNI_SUPPORT
   /* Test bit 25 for AES-NI.  */
   if (features & 0x02000000)
index 58099c4..4cafae1 100644 (file)
@@ -42,19 +42,21 @@ static struct
   const char *desc;
 } hwflist[] =
   {
-    { HWF_PADLOCK_RNG, "padlock-rng" },
-    { HWF_PADLOCK_AES, "padlock-aes" },
-    { HWF_PADLOCK_SHA, "padlock-sha" },
-    { HWF_PADLOCK_MMUL,"padlock-mmul"},
-    { HWF_INTEL_CPU,   "intel-cpu" },
-    { HWF_INTEL_BMI2,  "intel-bmi2" },
-    { HWF_INTEL_SSSE3, "intel-ssse3" },
-    { HWF_INTEL_PCLMUL,"intel-pclmul" },
-    { HWF_INTEL_AESNI, "intel-aesni" },
-    { HWF_INTEL_RDRAND,"intel-rdrand" },
-    { HWF_INTEL_AVX,   "intel-avx" },
-    { HWF_INTEL_AVX2,  "intel-avx2" },
-    { HWF_ARM_NEON,    "arm-neon" }
+    { HWF_PADLOCK_RNG,     "padlock-rng" },
+    { HWF_PADLOCK_AES,     "padlock-aes" },
+    { HWF_PADLOCK_SHA,     "padlock-sha" },
+    { HWF_PADLOCK_MMUL,    "padlock-mmul"},
+    { HWF_INTEL_CPU,       "intel-cpu" },
+    { HWF_INTEL_FAST_SHLD, "intel-fast-shld" },
+    { HWF_INTEL_BMI2,      "intel-bmi2" },
+    { HWF_INTEL_SSSE3,     "intel-ssse3" },
+    { HWF_INTEL_SSE4_1,    "intel-sse4.1" },
+    { HWF_INTEL_PCLMUL,    "intel-pclmul" },
+    { HWF_INTEL_AESNI,     "intel-aesni" },
+    { HWF_INTEL_RDRAND,    "intel-rdrand" },
+    { HWF_INTEL_AVX,       "intel-avx" },
+    { HWF_INTEL_AVX2,      "intel-avx2" },
+    { HWF_ARM_NEON,        "arm-neon" }
   };
 
 /* A bit vector with the hardware features which shall not be used.
index a90efce..067cb84 100644 (file)
@@ -274,6 +274,12 @@ EXPORTS
       gcry_mac_read             @240
       gcry_mac_verify           @241
       gcry_mac_ctl              @242
+      gcry_mac_get_algo         @243
 
+      gcry_mpi_ec_sub           @244
+
+      gcry_md_extract           @245
+
+      gcry_mpi_ec_decode_point  @246
 
 ;; end of file with public symbols for Windows.
index 6cf482f..c67cfec 100644 (file)
@@ -1,13 +1,15 @@
-dnl Autoconf macros for libgcrypt
-dnl       Copyright (C) 2002, 2004, 2011 Free Software Foundation, Inc.
-dnl
-dnl This file is free software; as a special exception the author gives
-dnl unlimited permission to copy and/or distribute it, with or without
-dnl modifications, as long as this notice is preserved.
-dnl
-dnl This file is distributed in the hope that it will be useful, but
-dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
-dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# libgcrypt.m4 - Autoconf macros to detect libgcrypt
+# Copyright (C) 2002, 2003, 2004, 2011, 2014 g10 Code GmbH
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This file is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Last-changed: 2014-10-02
 
 
 dnl AM_PATH_LIBGCRYPT([MINIMUM-VERSION,
@@ -20,19 +22,37 @@ dnl version of libgcrypt is at least 1.2.5 *and* the API number is 1.  Using
 dnl this features allows to prevent build against newer versions of libgcrypt
 dnl with a changed API.
 dnl
+dnl If a prefix option is not used, the config script is first
+dnl searched in $SYSROOT/bin and then along $PATH.  If the used
+dnl config script does not match the host specification the script
+dnl is added to the gpg_config_script_warn variable.
+dnl
 AC_DEFUN([AM_PATH_LIBGCRYPT],
 [ AC_REQUIRE([AC_CANONICAL_HOST])
   AC_ARG_WITH(libgcrypt-prefix,
             AC_HELP_STRING([--with-libgcrypt-prefix=PFX],
                            [prefix where LIBGCRYPT is installed (optional)]),
      libgcrypt_config_prefix="$withval", libgcrypt_config_prefix="")
-  if test x$libgcrypt_config_prefix != x ; then
-     if test x${LIBGCRYPT_CONFIG+set} != xset ; then
-        LIBGCRYPT_CONFIG=$libgcrypt_config_prefix/bin/libgcrypt-config
+  if test x"${LIBGCRYPT_CONFIG}" = x ; then
+     if test x"${libgcrypt_config_prefix}" != x ; then
+        LIBGCRYPT_CONFIG="${libgcrypt_config_prefix}/bin/libgcrypt-config"
+     else
+       case "${SYSROOT}" in
+         /*)
+           if test -x "${SYSROOT}/bin/libgcrypt-config" ; then
+             LIBGCRYPT_CONFIG="${SYSROOT}/bin/libgcrypt-config"
+           fi
+           ;;
+         '')
+           ;;
+          *)
+           AC_MSG_WARN([Ignoring \$SYSROOT as it is not an absolute path.])
+           ;;
+       esac
      fi
   fi
 
-  AC_PATH_TOOL(LIBGCRYPT_CONFIG, libgcrypt-config, no)
+  AC_PATH_PROG(LIBGCRYPT_CONFIG, libgcrypt-config, no)
   tmp=ifelse([$1], ,1:1.2.0,$1)
   if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then
      req_libgcrypt_api=`echo "$tmp"     | sed 's/\(.*\):\(.*\)/\1/'`
@@ -108,8 +128,9 @@ AC_DEFUN([AM_PATH_LIBGCRYPT],
 *** built for $libgcrypt_config_host and thus may not match the
 *** used host $host.
 *** You may want to use the configure option --with-libgcrypt-prefix
-*** to specify a matching config script.
+*** to specify a matching config script or use \$SYSROOT.
 ***]])
+        gpg_config_script_warn="$gpg_config_script_warn libgcrypt"
       fi
     fi
   else
index 5118c81..785b8ed 100644 (file)
@@ -41,7 +41,7 @@ GCRYPT_1.6 {
     gcry_md_get_algo; gcry_md_get_algo_dlen; gcry_md_hash_buffer;
     gcry_md_hash_buffers;
     gcry_md_info; gcry_md_is_enabled; gcry_md_is_secure;
-    gcry_md_map_name; gcry_md_open; gcry_md_read;
+    gcry_md_map_name; gcry_md_open; gcry_md_read; gcry_md_extract;
     gcry_md_reset; gcry_md_setkey;
     gcry_md_write; gcry_md_debug;
 
@@ -54,7 +54,7 @@ GCRYPT_1.6 {
     gcry_cipher_authenticate; gcry_cipher_gettag; gcry_cipher_checktag;
 
     gcry_mac_algo_info; gcry_mac_algo_name; gcry_mac_map_name;
-    gcry_mac_get_algo_maclen; gcry_mac_get_algo_keylen;
+    gcry_mac_get_algo_maclen; gcry_mac_get_algo_keylen; gcry_mac_get_algo;
     gcry_mac_open; gcry_mac_close; gcry_mac_setkey; gcry_mac_setiv;
     gcry_mac_write; gcry_mac_read; gcry_mac_verify; gcry_mac_ctl;
 
@@ -105,8 +105,8 @@ GCRYPT_1.6 {
     gcry_mpi_ec_get_mpi; gcry_mpi_ec_get_point;
     gcry_mpi_ec_set_mpi; gcry_mpi_ec_set_point;
     gcry_mpi_ec_get_affine;
-    gcry_mpi_ec_dup; gcry_mpi_ec_add; gcry_mpi_ec_mul;
-    gcry_mpi_ec_curve_point;
+    gcry_mpi_ec_dup; gcry_mpi_ec_add; gcry_mpi_ec_sub; gcry_mpi_ec_mul;
+    gcry_mpi_ec_curve_point; gcry_mpi_ec_decode_point;
 
     gcry_log_debug;
     gcry_log_debughex; gcry_log_debugmpi; gcry_log_debugpnt; gcry_log_debugsxp;
index b3c56e2..ac64d70 100644 (file)
@@ -436,6 +436,79 @@ _gcry_log_printsxp (const char *text, gcry_sexp_t sexp)
 }
 
 
+/*
+ * Tokenize STRING using the set of delimiters in DELIM.  Leading
+ * white spaces are removed from all tokens.  The caller must xfree
+ * the result.
+ *
+ * Returns: A malloced and NULL delimited array with the tokens.  On
+ *          memory error NULL is returned and ERRNO is set.
+ */
+char **
+_gcry_strtokenize (const char *string, const char *delim)
+{
+  const char *s;
+  size_t fields;
+  size_t bytes, n;
+  char *buffer;
+  char *p, *px, *pend;
+  char **result;
+  char const ws[] = " \t\v\f\r\n";
+
+  if (!delim)
+    delim = ws;
+
+  /* Count the number of fields.  */
+  for (fields = 1, s = strpbrk (string, delim); s; s = strpbrk (s + 1, delim))
+    fields++;
+  fields++; /* Add one for the terminating NULL.  */
+
+  /* Allocate an array for all fields, a terminating NULL, and space
+     for a copy of the string.  */
+  bytes = fields * sizeof *result;
+  if (bytes / sizeof *result != fields)
+    {
+      gpg_err_set_errno (ENOMEM);
+      return NULL;
+    }
+  n = strlen (string) + 1;
+  bytes += n;
+  if (bytes < n)
+    {
+      gpg_err_set_errno (ENOMEM);
+      return NULL;
+    }
+  result = xtrymalloc (bytes);
+  if (!result)
+    return NULL;
+  buffer = (char*)(result + fields);
+
+  /* Copy and parse the string.  */
+  strcpy (buffer, string);
+  for (n = 0, p = buffer; (pend = strpbrk (p, delim)); p = pend + 1)
+    {
+      *pend = 0;
+      while (strchr (ws, *(byte*)p))
+        p++;
+      for (px = pend - 1; px >= p && strchr (ws, *(byte*)px); px--)
+        *px = 0;
+      result[n++] = p;
+    }
+  while (*p && strchr (ws, *(byte*)p))
+    p++;
+  for (px = p + strlen (p) - 1; px >= p && strchr (ws, *(byte*)px); px--)
+    *px = 0;
+  /* Traling spaces may result in an empty field.  We do not want to
+     store that.  */
+  result[n++] = *p? p : NULL;
+  result[n] = NULL;
+
+  gcry_assert ((char*)(result + n + 1) == buffer);
+
+  return result;
+}
+
+
 void
 __gcry_burn_stack (unsigned int bytes)
 {
index 8446d23..cd539f5 100644 (file)
--- a/src/mpi.h
+++ b/src/mpi.h
@@ -119,12 +119,17 @@ void _gcry_mpi_immutable_failed (void);
 #define mpi_alloc_set_ui(a)   _gcry_mpi_alloc_set_ui ((a))
 #define mpi_m_check(a)        _gcry_mpi_m_check ((a))
 #define mpi_const(n)          _gcry_mpi_const ((n))
+#define mpi_swap_cond(a,b,sw)  _gcry_mpi_swap_cond ((a),(b),(sw))
+#define mpi_set_cond(w,u,set)  _gcry_mpi_set_cond ((w),(u),(set))
 
 void _gcry_mpi_clear( gcry_mpi_t a );
+gcry_mpi_t _gcry_mpi_set_cond (gcry_mpi_t w, const gcry_mpi_t u,
+                               unsigned long swap);
 gcry_mpi_t  _gcry_mpi_alloc_like( gcry_mpi_t a );
 gcry_mpi_t  _gcry_mpi_alloc_set_ui( unsigned long u);
 void _gcry_mpi_m_check( gcry_mpi_t a );
 void _gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b);
+void _gcry_mpi_swap_cond (gcry_mpi_t a, gcry_mpi_t b, unsigned long swap);
 gcry_mpi_t _gcry_mpi_new (unsigned int nbits);
 gcry_mpi_t _gcry_mpi_snew (unsigned int nbits);
 gcry_mpi_t _gcry_mpi_set_opaque_copy (gcry_mpi_t a,
@@ -242,13 +247,18 @@ void _gcry_mpi_snatch_point (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z,
 /* Models describing an elliptic curve.  */
 enum gcry_mpi_ec_models
   {
-
+    /* The Short Weierstrass equation is
+          y^2 = x^3 + ax + b
+     */
     MPI_EC_WEIERSTRASS = 0,
+    /* The Montgomery equation is
+          by^2 = x^3 + ax^2 + x
+     */
     MPI_EC_MONTGOMERY,
-    MPI_EC_TWISTEDEDWARDS
-    /* The equation for Twisted Edwards curves is
+    /* The Twisted Edwards equation is
           ax^2 + y^2 = 1 + bx^2y^2
        Note that we use 'b' instead of the commonly used 'd'.  */
+    MPI_EC_EDWARDS
   };
 
 /* Dialects used with elliptic curves.  It is easier to keep the
@@ -279,6 +289,9 @@ void _gcry_mpi_ec_dup_point (mpi_point_t result,
 void _gcry_mpi_ec_add_points (mpi_point_t result,
                               mpi_point_t p1, mpi_point_t p2,
                               mpi_ec_t ctx);
+void _gcry_mpi_ec_sub_points (mpi_point_t result,
+                              mpi_point_t p1, mpi_point_t p2,
+                              mpi_ec_t ctx);
 void _gcry_mpi_ec_mul_point (mpi_point_t result,
                              gcry_mpi_t scalar, mpi_point_t point,
                              mpi_ec_t ctx);
@@ -294,6 +307,8 @@ gpg_err_code_t _gcry_mpi_ec_set_mpi (const char *name, gcry_mpi_t newvalue,
 gpg_err_code_t _gcry_mpi_ec_set_point (const char *name,
                                        gcry_mpi_point_t newvalue,
                                        gcry_ctx_t ctx);
+gpg_err_code_t _gcry_mpi_ec_decode_point (mpi_point_t result,
+                                          gcry_mpi_t value, mpi_ec_t ec);
 
 /*-- ecc-curves.c --*/
 gpg_err_code_t _gcry_mpi_ec_new (gcry_ctx_t *r_ctx,
index b2b4335..ebd1bbb 100644 (file)
@@ -200,12 +200,14 @@ do_powm (void)
 static void
 do_inv (void)
 {
-  gcry_mpi_t a = mpi_new (0);
+  gcry_mpi_t a;
+
   if (stackidx < 2)
     {
       fputs ("stack underflow\n", stderr);
       return;
     }
+  a = mpi_new (0);
   mpi_invm (a, stack[stackidx - 2], stack[stackidx - 1]);
   mpi_set (stack[stackidx - 2], a);
   mpi_release (a);
@@ -215,12 +217,14 @@ do_inv (void)
 static void
 do_gcd (void)
 {
-  gcry_mpi_t a = mpi_new (0);
+  gcry_mpi_t a;
+
   if (stackidx < 2)
     {
       fputs ("stack underflow\n", stderr);
       return;
     }
+  a = mpi_new (0);
   mpi_gcd (a, stack[stackidx - 2], stack[stackidx - 1]);
   mpi_set (stack[stackidx - 2], a);
   mpi_release (a);
@@ -254,6 +258,23 @@ do_nbits (void)
 }
 
 
+static void
+do_primecheck (void)
+{
+  gpg_error_t err;
+
+  if (stackidx < 1)
+    {
+      fputs ("stack underflow\n", stderr);
+      return;
+    }
+  err = gcry_prime_check (stack[stackidx - 1], 0);
+  mpi_set_ui (stack[stackidx - 1], !err);
+  if (err && gpg_err_code (err) != GPG_ERR_NO_PRIME)
+    fprintf (stderr, "checking prime failed: %s\n", gpg_strerror (err));
+}
+
+
 static int
 my_getc (void)
 {
@@ -295,6 +316,7 @@ print_help (void)
          "d   dup item      [-1] := [0]               {+1}\n"
          "r   reverse       [0] := [1], [1] := [0]    {0}\n"
          "b   # of bits     [0] := nbits([0])         {0}\n"
+         "P   prime check   [0] := is_prime([0])?1:0  {0}\n"
          "c   clear stack\n"
          "p   print top item\n"
          "f   print the stack\n"
@@ -313,7 +335,7 @@ main (int argc, char **argv)
   int print_config = 0;
   int i, c;
   int state = 0;
-  char strbuf[1000];
+  char strbuf[4096];
   int stridx = 0;
 
   if (argc)
@@ -508,6 +530,9 @@ main (int argc, char **argv)
                 case 'b':
                   do_nbits ();
                   break;
+                case 'P':
+                  do_primecheck ();
+                  break;
                case 'c':
                  for (i = 0; i < stackidx; i++)
                     {
index 2bf7d8c..c4e8414 100644 (file)
@@ -37,7 +37,6 @@
 #endif
 #endif
 
-#include "ath.h"
 #include "g10lib.h"
 #include "secmem.h"
 
@@ -86,11 +85,11 @@ static int no_priv_drop;
 static unsigned int cur_alloced, cur_blocks;
 
 /* Lock protecting accesses to the memory pool.  */
-static ath_mutex_t secmem_lock;
+GPGRT_LOCK_DEFINE (secmem_lock);
 
 /* Convenient macros.  */
-#define SECMEM_LOCK   ath_mutex_lock   (&secmem_lock)
-#define SECMEM_UNLOCK ath_mutex_unlock (&secmem_lock)
+#define SECMEM_LOCK   gpgrt_lock_lock   (&secmem_lock)
+#define SECMEM_UNLOCK gpgrt_lock_unlock (&secmem_lock)
 
 /* The size of the memblock structure; this does not include the
    memory that is available to the user.  */
@@ -99,21 +98,20 @@ static ath_mutex_t secmem_lock;
 
 /* Convert an address into the according memory block structure.  */
 #define ADDR_TO_BLOCK(addr) \
-  (memblock_t *) ((char *) addr - BLOCK_HEAD_SIZE)
+  (memblock_t *) (void *) ((char *) addr - BLOCK_HEAD_SIZE)
 
 /* Check whether P points into the pool.  */
 static int
 ptr_into_pool_p (const void *p)
 {
   /* We need to convert pointers to addresses.  This is required by
-     C-99 6.5.8 to avoid undefined behaviour.  Using size_t is at
-     least only implementation defined.  See also
+     C-99 6.5.8 to avoid undefined behaviour.  See also
      http://lists.gnupg.org/pipermail/gcrypt-devel/2007-February/001102.html
   */
-  size_t p_addr = (size_t)p;
-  size_t pool_addr = (size_t)pool;
+  uintptr_t p_addr    = (uintptr_t)p;
+  uintptr_t pool_addr = (uintptr_t)pool;
 
-  return p_addr >= pool_addr && p_addr <  pool_addr+pool_size;
+  return p_addr >= pool_addr && p_addr <  pool_addr + pool_size;
 }
 
 /* Update the stats.  */
@@ -138,7 +136,7 @@ mb_get_next (memblock_t *mb)
 {
   memblock_t *mb_next;
 
-  mb_next = (memblock_t *) ((char *) mb + BLOCK_HEAD_SIZE + mb->size);
+  mb_next = (memblock_t *) (void *) ((char *) mb + BLOCK_HEAD_SIZE + mb->size);
 
   if (! ptr_into_pool_p (mb_next))
     mb_next = NULL;
@@ -206,7 +204,8 @@ mb_get_new (memblock_t *block, size_t size)
          {
            /* Split block.  */
 
-           mb_split = (memblock_t *) (((char *) mb) + BLOCK_HEAD_SIZE + size);
+           mb_split = (memblock_t *) (void *) (((char *) mb) + BLOCK_HEAD_SIZE
+                                               + size);
            mb_split->size = mb->size - size - BLOCK_HEAD_SIZE;
            mb_split->flags = 0;
 
@@ -246,15 +245,21 @@ lock_pool (void *p, size_t n)
   {
     cap_t cap;
 
-    cap = cap_from_text ("cap_ipc_lock+ep");
-    cap_set_proc (cap);
-    cap_free (cap);
+    if (!no_priv_drop)
+      {
+        cap = cap_from_text ("cap_ipc_lock+ep");
+        cap_set_proc (cap);
+        cap_free (cap);
+      }
     err = no_mlock? 0 : mlock (p, n);
     if (err && errno)
       err = errno;
-    cap = cap_from_text ("cap_ipc_lock+p");
-    cap_set_proc (cap);
-    cap_free(cap);
+    if (!no_priv_drop)
+      {
+        cap = cap_from_text ("cap_ipc_lock+p");
+        cap_set_proc (cap);
+        cap_free(cap);
+      }
   }
 
   if (err)
@@ -364,8 +369,6 @@ lock_pool (void *p, size_t n)
 static void
 init_pool (size_t n)
 {
-  size_t pgsize;
-  long int pgsize_val;
   memblock_t *mb;
 
   pool_size = n;
@@ -373,48 +376,54 @@ init_pool (size_t n)
   if (disable_secmem)
     log_bug ("secure memory is disabled");
 
-#if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
-  pgsize_val = sysconf (_SC_PAGESIZE);
-#elif defined(HAVE_GETPAGESIZE)
-  pgsize_val = getpagesize ();
-#else
-  pgsize_val = -1;
-#endif
-  pgsize = (pgsize_val != -1 && pgsize_val > 0)? pgsize_val:DEFAULT_PAGE_SIZE;
-
 
 #if HAVE_MMAP
-  pool_size = (pool_size + pgsize - 1) & ~(pgsize - 1);
-#ifdef MAP_ANONYMOUS
-  pool = mmap (0, pool_size, PROT_READ | PROT_WRITE,
-              MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-#else /* map /dev/zero instead */
   {
-    int fd;
+    size_t pgsize;
+    long int pgsize_val;
+
+# if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
+    pgsize_val = sysconf (_SC_PAGESIZE);
+# elif defined(HAVE_GETPAGESIZE)
+    pgsize_val = getpagesize ();
+# else
+    pgsize_val = -1;
+# endif
+    pgsize = (pgsize_val != -1 && pgsize_val > 0)? pgsize_val:DEFAULT_PAGE_SIZE;
+
+    pool_size = (pool_size + pgsize - 1) & ~(pgsize - 1);
+# ifdef MAP_ANONYMOUS
+    pool = mmap (0, pool_size, PROT_READ | PROT_WRITE,
+                 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+# else /* map /dev/zero instead */
+    {
+      int fd;
 
-    fd = open ("/dev/zero", O_RDWR);
-    if (fd == -1)
-      {
-       log_error ("can't open /dev/zero: %s\n", strerror (errno));
-       pool = (void *) -1;
-      }
+      fd = open ("/dev/zero", O_RDWR);
+      if (fd == -1)
+        {
+          log_error ("can't open /dev/zero: %s\n", strerror (errno));
+          pool = (void *) -1;
+        }
+      else
+        {
+          pool = mmap (0, pool_size,
+                       (PROT_READ | PROT_WRITE), MAP_PRIVATE, fd, 0);
+          close (fd);
+        }
+    }
+# endif
+    if (pool == (void *) -1)
+      log_info ("can't mmap pool of %u bytes: %s - using malloc\n",
+                (unsigned) pool_size, strerror (errno));
     else
       {
-       pool = mmap (0, pool_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
-        close (fd);
+        pool_is_mmapped = 1;
+        pool_okay = 1;
       }
   }
-#endif
-  if (pool == (void *) -1)
-    log_info ("can't mmap pool of %u bytes: %s - using malloc\n",
-             (unsigned) pool_size, strerror (errno));
-  else
-    {
-      pool_is_mmapped = 1;
-      pool_okay = 1;
-    }
+#endif /*HAVE_MMAP*/
 
-#endif
   if (!pool_okay)
     {
       pool = malloc (pool_size);
@@ -482,13 +491,14 @@ secmem_init (size_t n)
     {
 #ifdef USE_CAPABILITIES
       /* drop all capabilities */
-      {
-        cap_t cap;
+      if (!no_priv_drop)
+        {
+          cap_t cap;
 
-        cap = cap_from_text ("all-eip");
-        cap_set_proc (cap);
-        cap_free (cap);
-      }
+          cap = cap_from_text ("all-eip");
+          cap_set_proc (cap);
+          cap_free (cap);
+        }
 
 #elif !defined(HAVE_DOSISH_SYSTEM)
       uid_t uid;
@@ -536,12 +546,7 @@ _gcry_secmem_init (size_t n)
 gcry_err_code_t
 _gcry_secmem_module_init ()
 {
-  int err;
-
-  err = ath_mutex_init (&secmem_lock);
-  if (err)
-    log_fatal ("could not allocate secmem lock\n");
-
+  /* Not anymore needed.  */
   return 0;
 }
 
@@ -612,7 +617,7 @@ _gcry_secmem_free_internal (void *a)
   /* This does not make much sense: probably this memory is held in the
    * cache. We do it anyway: */
 #define MB_WIPE_OUT(byte) \
-  wipememory2 ((memblock_t *) ((char *) mb + BLOCK_HEAD_SIZE), (byte), size);
+  wipememory2 (((char *) mb + BLOCK_HEAD_SIZE), (byte), size);
 
   MB_WIPE_OUT (0xff);
   MB_WIPE_OUT (0xaa);
@@ -647,7 +652,8 @@ _gcry_secmem_realloc (void *p, size_t newsize)
 
   SECMEM_LOCK;
 
-  mb = (memblock_t *) ((char *) p - ((size_t) &((memblock_t *) 0)->aligned.c));
+  mb = (memblock_t *) (void *) ((char *) p
+                               - ((size_t) &((memblock_t *) 0)->aligned.c));
   size = mb->size;
   if (newsize < size)
     {
index 9bc13ca..6077bab 100644 (file)
@@ -53,7 +53,7 @@
    data) is required as well.  The close_tag finishes the list and
    would actually be sufficient.  For fail-safe reasons a final stop
    tag is always the last byte in a buffer; it has a value of 0 so
-   that string function accidently applied to an S-expression will
+   that string function accidentally applied to an S-expression will
    never access unallocated data.  We do not support display hints and
    thus don't need to represent them.  A list may have more an
    arbitrary number of data elements but at least one is required.
@@ -1592,6 +1592,13 @@ do_vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
              err = GPG_ERR_SEXP_UNMATCHED_DH;
               goto leave;
            }
+
+         if (level == 0)
+           {
+             *erroff = p - buffer;
+             err = GPG_ERR_SEXP_UNMATCHED_PAREN;
+             goto leave;
+           }
          MAKE_SPACE (0);
          *c.pos++ = ST_CLOSE;
          level--;
@@ -2183,8 +2190,8 @@ _gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
  * a parameter name, enclose the name in single quotes.
  *
  * Unless in gcry_buffer_t mode for each parameter name a pointer to
- * an MPI variable is expected and finally a NULL is expected.
- * Example:
+ * an MPI variable is expected that must be set to NULL prior to
+ * invoking this function, and finally a NULL is expected.  Example:
  *
  *   _gcry_sexp_extract_param (key, NULL, "n/x+ed",
  *                             &mpi_n, &mpi_x, &mpi_e, NULL)
@@ -2208,8 +2215,11 @@ _gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
  * mark separated tokens are used to via gcry_sexp_find_token to find
  * a start point inside SEXP.
  *
- * The function returns NULL on success.  On error an error code is
- * returned and the passed MPIs are either unchanged or set to NULL.
+ * The function returns 0 on success.  On error an error code is
+ * returned, all passed MPIs that might have been allocated up to this
+ * point are deallocated and set to NULL, and all passed buffers are
+ * either truncated if the caller supplied the buffer, or deallocated
+ * if the function allocated the buffer.
  */
 gpg_err_code_t
 _gcry_sexp_vextract_param (gcry_sexp_t sexp, const char *path,
@@ -2405,7 +2415,7 @@ _gcry_sexp_vextract_param (gcry_sexp_t sexp, const char *path,
           _gcry_mpi_release (*array[idx]);
           *array[idx] = NULL;
         }
-      else if (!arrayisdesc[idx] == 1)
+      else if (arrayisdesc[idx] == 1)
         {
           /* Caller provided buffer.  */
           gcry_buffer_t *spec = (gcry_buffer_t*)array[idx];
@@ -2423,7 +2433,7 @@ _gcry_sexp_vextract_param (gcry_sexp_t sexp, const char *path,
   return rc;
 }
 
-gpg_error_t
+gpg_err_code_t
 _gcry_sexp_extract_param (gcry_sexp_t sexp, const char *path,
                           const char *list, ...)
 {
@@ -2433,5 +2443,5 @@ _gcry_sexp_extract_param (gcry_sexp_t sexp, const char *path,
   va_start (arg_ptr, list);
   rc = _gcry_sexp_vextract_param (sexp, path, list, arg_ptr);
   va_end (arg_ptr);
-  return gpg_error (rc);
+  return rc;
 }
index ee0a62b..645ddd6 100644 (file)
 #ifndef GCRYPT_TYPES_H
 #define GCRYPT_TYPES_H
 
+#ifndef _GCRYPT_CONFIG_H_INCLUDED
+# error config.h must be included before types.h
+#endif
 
 /* The AC_CHECK_SIZEOF() in configure fails for some machines.
  * we provide some fallback values here */
 #if !SIZEOF_UNSIGNED_SHORT
-#undef SIZEOF_UNSIGNED_SHORT
-#define SIZEOF_UNSIGNED_SHORT 2
+# undef SIZEOF_UNSIGNED_SHORT
+# define SIZEOF_UNSIGNED_SHORT 2
 #endif
 #if !SIZEOF_UNSIGNED_INT
-#undef SIZEOF_UNSIGNED_INT
-#define SIZEOF_UNSIGNED_INT 4
+# undef SIZEOF_UNSIGNED_INT
+# define SIZEOF_UNSIGNED_INT 4
 #endif
 #if !SIZEOF_UNSIGNED_LONG
-#undef SIZEOF_UNSIGNED_LONG
-#define SIZEOF_UNSIGNED_LONG 4
+# undef SIZEOF_UNSIGNED_LONG
+# define SIZEOF_UNSIGNED_LONG 4
 #endif
 
 
 #include <sys/types.h>
 
+/* Provide uintptr_t */
+#ifdef HAVE_STDINT_H
+# include <stdint.h> /* uintptr_t */
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#else
+/* In this case, uintptr_t is provided by config.h. */
+#endif
+
+
 
 #ifndef HAVE_BYTE_TYPEDEF
-#undef byte        /* maybe there is a macro with this name */
-/* Windows typedefs byte in the rpc headers.  Avoid warning about
-   double definition.  */
-#if !(defined(_WIN32) && defined(cbNDRContext))
-  typedef unsigned char byte;
-#endif
-#define HAVE_BYTE_TYPEDEF
+# undef byte   /* In case there is a macro with that name.  */
+# if !(defined(_WIN32) && defined(cbNDRContext))
+   /* Windows typedefs byte in the rpc headers.  Avoid warning about
+      double definition.  */
+   typedef unsigned char byte;
+# endif
+# define HAVE_BYTE_TYPEDEF
 #endif
 
 #ifndef HAVE_USHORT_TYPEDEF
-#undef ushort     /* maybe there is a macro with this name */
+# undef ushort  /* In case there is a macro with that name.  */
   typedef unsigned short ushort;
-#define HAVE_USHORT_TYPEDEF
+# define HAVE_USHORT_TYPEDEF
 #endif
 
 #ifndef HAVE_ULONG_TYPEDEF
-#undef ulong       /* maybe there is a macro with this name */
+# undef ulong   /* In case there is a macro with that name.  */
   typedef unsigned long ulong;
-#define HAVE_ULONG_TYPEDEF
+# define HAVE_ULONG_TYPEDEF
 #endif
 
 #ifndef HAVE_U16_TYPEDEF
-#undef u16         /* maybe there is a macro with this name */
-#if SIZEOF_UNSIGNED_INT == 2
-    typedef unsigned int   u16;
-#elif SIZEOF_UNSIGNED_SHORT == 2
-    typedef unsigned short u16;
-#else
-#error no typedef for u16
-#endif
-#define HAVE_U16_TYPEDEF
+# undef u16    /* In case there is a macro with that name.  */
+# if SIZEOF_UNSIGNED_INT == 2
+   typedef unsigned int   u16;
+# elif SIZEOF_UNSIGNED_SHORT == 2
+   typedef unsigned short u16;
+# else
+#  error no typedef for u16
+# endif
+# define HAVE_U16_TYPEDEF
 #endif
 
 #ifndef HAVE_U32_TYPEDEF
-#undef u32         /* maybe there is a macro with this name */
-#if SIZEOF_UNSIGNED_INT == 4
-    typedef unsigned int u32;
-#elif SIZEOF_UNSIGNED_LONG == 4
-    typedef unsigned long u32;
-#else
-#error no typedef for u32
-#endif
-#define HAVE_U32_TYPEDEF
+# undef u32    /* In case there is a macro with that name.  */
+# if SIZEOF_UNSIGNED_INT == 4
+   typedef unsigned int  u32;
+# elif SIZEOF_UNSIGNED_LONG == 4
+   typedef unsigned long u32;
+# else
+#  error no typedef for u32
+# endif
+# define HAVE_U32_TYPEDEF
 #endif
 
-/****************
+/*
  * Warning: Some systems segfault when this u64 typedef and
  * the dummy code in cipher/md.c is not available.  Examples are
  * Solaris and IRIX.
  */
 #ifndef HAVE_U64_TYPEDEF
-#undef u64         /* maybe there is a macro with this name */
-#if SIZEOF_UNSIGNED_INT == 8
-    typedef unsigned int u64;
-#define U64_C(c) (c ## U)
-#define HAVE_U64_TYPEDEF
-#elif SIZEOF_UNSIGNED_LONG == 8
-    typedef unsigned long u64;
-#define U64_C(c) (c ## UL)
-#define HAVE_U64_TYPEDEF
-#elif SIZEOF_UNSIGNED_LONG_LONG == 8
-    typedef unsigned long long u64;
-#define U64_C(c) (c ## ULL)
-#define HAVE_U64_TYPEDEF
-#elif SIZEOF_UINT64_T == 8
-    typedef uint64_t u64;
-#define U64_C(c) (UINT64_C(c))
-#define HAVE_U64_TYPEDEF
-#endif
+# undef u64    /* In case there is a macro with that name.  */
+# if SIZEOF_UNSIGNED_INT == 8
+   typedef unsigned int u64;
+#  define U64_C(c) (c ## U)
+#  define HAVE_U64_TYPEDEF
+# elif SIZEOF_UNSIGNED_LONG == 8
+   typedef unsigned long u64;
+#  define U64_C(c) (c ## UL)
+#  define HAVE_U64_TYPEDEF
+# elif SIZEOF_UNSIGNED_LONG_LONG == 8
+   typedef unsigned long long u64;
+#  define U64_C(c) (c ## ULL)
+#  define HAVE_U64_TYPEDEF
+# elif SIZEOF_UINT64_T == 8
+   typedef uint64_t u64;
+#  define U64_C(c) (UINT64_C(c))
+#  define HAVE_U64_TYPEDEF
+# else
+#  error No way to declare a 64 bit integer type
+# endif
 #endif
 
-typedef union {
-    int a;
-    short b;
-    char c[1];
-    long d;
-#ifdef HAVE_U64_TYPEDEF
-    u64 e;
-#endif
-    float f;
-    double g;
+typedef union
+{
+  int a;
+  short b;
+  char c[1];
+  long d;
+  u64 e;
+  float f;
+  double g;
 } PROPERLY_ALIGNED_TYPE;
 
 #endif /*GCRYPT_TYPES_H*/
index 3199521..1adb4e9 100644 (file)
@@ -39,7 +39,7 @@ BEGIN
             VALUE "FileDescription", "Libgcrypt - The GNU Crypto Library\0"
             VALUE "FileVersion", "@LIBGCRYPT_LT_CURRENT@.@LIBGCRYPT_LT_AGE@.@LIBGCRYPT_LT_REVISION@.@BUILD_REVISION@\0"
             VALUE "InternalName", "libgcrypt\0"
-            VALUE "LegalCopyright", "Copyright © 2012 Free Software Foundation, Inc.\0"
+            VALUE "LegalCopyright", "Copyright © 2016 Free Software Foundation, Inc.\0"
             VALUE "LegalTrademarks", "\0"
             VALUE "OriginalFilename", "libgcrypt.dll\0"
             VALUE "PrivateBuild", "\0"
index 2989498..3abbd37 100644 (file)
@@ -57,7 +57,7 @@ gcry_err_make_from_errno (gcry_err_source_t source, int err)
   return _gcry_err_make_from_errno (source, err);
 }
 
-gcry_err_code_t
+gcry_error_t
 gcry_error_from_errno (int err)
 {
   return _gcry_error_from_errno (err);
@@ -292,7 +292,7 @@ gcry_mpi_copy (const gcry_mpi_t a)
 void
 gcry_mpi_snatch (gcry_mpi_t w, const gcry_mpi_t u)
 {
-  return _gcry_mpi_snatch (w, u);
+  _gcry_mpi_snatch (w, u);
 }
 
 gcry_mpi_t
@@ -544,6 +544,15 @@ gcry_mpi_ec_set_point (const char *name, gcry_mpi_point_t newvalue,
   return gpg_error (_gcry_mpi_ec_set_point (name, newvalue, ctx));
 }
 
+gpg_error_t
+gcry_mpi_ec_decode_point (gcry_mpi_point_t result, gcry_mpi_t value,
+                          gcry_ctx_t ctx)
+{
+  return gpg_error (_gcry_mpi_ec_decode_point
+                    (result, value,
+                     ctx? _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC) : NULL));
+}
+
 int
 gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_point_t point,
                         gcry_ctx_t ctx)
@@ -567,6 +576,14 @@ gcry_mpi_ec_add (gcry_mpi_point_t w,
 }
 
 void
+gcry_mpi_ec_sub (gcry_mpi_point_t w,
+                 gcry_mpi_point_t u, gcry_mpi_point_t v, gcry_ctx_t ctx)
+{
+  _gcry_mpi_ec_sub_points (w, u, v,
+                           _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC));
+}
+
+void
 gcry_mpi_ec_mul (gcry_mpi_point_t w, gcry_mpi_t n, gcry_mpi_point_t u,
                  gcry_ctx_t ctx)
 {
@@ -855,6 +872,12 @@ gcry_mac_map_name (const char *string)
   return _gcry_mac_map_name (string);
 }
 
+int
+gcry_mac_get_algo (gcry_mac_hd_t hd)
+{
+  return _gcry_mac_get_algo (hd);
+}
+
 unsigned int
 gcry_mac_get_algo_maclen (int algo)
 {
@@ -1151,6 +1174,12 @@ gcry_md_read (gcry_md_hd_t hd, int algo)
   return _gcry_md_read (hd, algo);
 }
 
+gcry_err_code_t
+gcry_md_extract (gcry_md_hd_t hd, int algo, void *buffer, size_t length)
+{
+  return _gcry_md_extract(hd, algo, buffer, length);
+}
+
 void
 gcry_md_hash_buffer (int algo, void *digest,
                      const void *buffer, size_t length)
index 4127a43..7ecd75e 100644 (file)
@@ -110,6 +110,7 @@ MARK_VISIBLEX (gcry_md_is_secure)
 MARK_VISIBLEX (gcry_md_map_name)
 MARK_VISIBLEX (gcry_md_open)
 MARK_VISIBLEX (gcry_md_read)
+MARK_VISIBLEX (gcry_md_extract)
 MARK_VISIBLEX (gcry_md_reset)
 MARK_VISIBLEX (gcry_md_setkey)
 MARK_VISIBLEX (gcry_md_write)
@@ -137,6 +138,7 @@ MARK_VISIBLEX (gcry_cipher_open)
 MARK_VISIBLEX (gcry_mac_algo_info)
 MARK_VISIBLEX (gcry_mac_algo_name)
 MARK_VISIBLEX (gcry_mac_map_name)
+MARK_VISIBLEX (gcry_mac_get_algo)
 MARK_VISIBLEX (gcry_mac_get_algo_maclen)
 MARK_VISIBLEX (gcry_mac_get_algo_keylen)
 MARK_VISIBLEX (gcry_mac_open)
@@ -217,8 +219,10 @@ MARK_VISIBLEX (gcry_mpi_copy)
 MARK_VISIBLEX (gcry_mpi_div)
 MARK_VISIBLEX (gcry_mpi_dump)
 MARK_VISIBLEX (gcry_mpi_ec_add)
+MARK_VISIBLEX (gcry_mpi_ec_sub)
 MARK_VISIBLEX (gcry_mpi_ec_curve_point)
 MARK_VISIBLEX (gcry_mpi_ec_dup)
+MARK_VISIBLEX (gcry_mpi_ec_decode_point)
 MARK_VISIBLEX (gcry_mpi_ec_get_affine)
 MARK_VISIBLEX (gcry_mpi_ec_mul)
 MARK_VISIBLEX (gcry_mpi_ec_new)
@@ -372,6 +376,7 @@ MARK_VISIBLEX (_gcry_mpi_get_const)
 #define gcry_md_map_name            _gcry_USE_THE_UNDERSCORED_FUNCTION
 #define gcry_md_open                _gcry_USE_THE_UNDERSCORED_FUNCTION
 #define gcry_md_read                _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_extract             _gcry_USE_THE_UNDERSCORED_FUNCTION
 #define gcry_md_reset               _gcry_USE_THE_UNDERSCORED_FUNCTION
 #define gcry_md_setkey              _gcry_USE_THE_UNDERSCORED_FUNCTION
 #define gcry_md_write               _gcry_USE_THE_UNDERSCORED_FUNCTION
@@ -380,6 +385,7 @@ MARK_VISIBLEX (_gcry_mpi_get_const)
 #define gcry_mac_algo_info          _gcry_USE_THE_UNDERSCORED_FUNCTION
 #define gcry_mac_algo_name          _gcry_USE_THE_UNDERSCORED_FUNCTION
 #define gcry_mac_map_name           _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mac_get_algo           _gcry_USE_THE_UNDERSCORED_FUNCTION
 #define gcry_mac_get_algo_maclen    _gcry_USE_THE_UNDERSCORED_FUNCTION
 #define gcry_mac_get_algo_keylen    _gcry_USE_THE_UNDERSCORED_FUNCTION
 #define gcry_mac_open               _gcry_USE_THE_UNDERSCORED_FUNCTION
@@ -484,8 +490,10 @@ MARK_VISIBLEX (_gcry_mpi_get_const)
 
 #define gcry_mpi_abs                _gcry_USE_THE_UNDERSCORED_FUNCTION
 #define gcry_mpi_ec_add             _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_ec_sub             _gcry_USE_THE_UNDERSCORED_FUNCTION
 #define gcry_mpi_ec_curve_point     _gcry_USE_THE_UNDERSCORED_FUNCTION
 #define gcry_mpi_ec_dup             _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_ec_decode_point    _gcry_USE_THE_UNDERSCORED_FUNCTION
 #define gcry_mpi_ec_get_affine      _gcry_USE_THE_UNDERSCORED_FUNCTION
 #define gcry_mpi_ec_get_mpi         _gcry_USE_THE_UNDERSCORED_FUNCTION
 #define gcry_mpi_ec_get_point       _gcry_USE_THE_UNDERSCORED_FUNCTION
index 9645471..d462f30 100644 (file)
 ## Process this file with automake to produce Makefile.in
 
 tests_bin = \
-        version mpitests tsexp t-convert \
+        version mpitests t-sexp t-convert \
        t-mpi-bit t-mpi-point curves t-lock \
        prime basic keygen pubkey hmac hashtest t-kdf keygrip \
-       fips186-dsa aeswrap pkcs1v2 random dsa-rfc6979 t-ed25519
+       fips186-dsa aeswrap pkcs1v2 random dsa-rfc6979 t-ed25519 t-cv25519
 
 tests_bin_last = benchmark bench-slope
 
@@ -46,17 +46,20 @@ AM_CPPFLAGS = -I../src -I$(top_srcdir)/src
 AM_CFLAGS = $(GPG_ERROR_CFLAGS)
 AM_LDFLAGS = -no-install
 
-default_ldadd = \
+standard_ldadd = \
        ../src/libgcrypt.la $(DL_LIBS) \
-        ../compat/libcompat.la $(GPG_ERROR_LIBS)
+        ../compat/libcompat.la
 
 EXTRA_PROGRAMS = testapi pkbench
-noinst_PROGRAMS = $(tests_bin) $(tests_bin_last) fipsdrv rsacvt genhashdata
+noinst_PROGRAMS = $(tests_bin) $(tests_bin_last) fipsdrv rsacvt genhashdata \
+                 gchash
 noinst_HEADERS = t-common.h
 
 EXTRA_DIST = README rsa-16k.key cavs_tests.sh cavs_driver.pl \
             pkcs1v2-oaep.h pkcs1v2-pss.h pkcs1v2-v15c.h pkcs1v2-v15s.h \
-            t-ed25519.inp stopwatch.h hashtest-256g.in
+            t-ed25519.inp stopwatch.h hashtest-256g.in \
+            sha3-224.h sha3-256.h sha3-384.h sha3-512.h
 
-LDADD = $(default_ldadd) $(LIBTHREAD)
-t_lock_LDADD = $(default_ldadd) $(LIBMULTITHREAD)
+LDADD = $(standard_ldadd) $(GPG_ERROR_LIBS)
+t_lock_LDADD = $(standard_ldadd) $(GPG_ERROR_MT_LIBS)
+t_lock_CFLAGS = $(GPG_ERROR_MT_CFLAGS)
index 66fdfe1..000ec67 100644 (file)
@@ -1,9 +1,8 @@
-# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
-# Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
 
 VPATH = @srcdir@
-am__make_dryrun = \
-  { \
-    am__dry=no; \
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
     case $$MAKEFLAGS in \
       *\\[\ \  ]*) \
-        echo 'am--echo: ; @echo "AM"  OK' | $(MAKE) -f - 2>/dev/null \
-          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
-      *) \
-        for am__flg in $$MAKEFLAGS; do \
-          case $$am__flg in \
-            *=*|--*) ;; \
-            *n*) am__dry=yes; break;; \
-          esac; \
-        done;; \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs  ]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
     esac; \
-    test $$am__dry = yes; \
-  }
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -74,32 +101,33 @@ TESTS = $(am__EXEEXT_1) $(am__EXEEXT_3) $(am__EXEEXT_2) \
        $(tests_sh_last)
 EXTRA_PROGRAMS = testapi$(EXEEXT) pkbench$(EXEEXT)
 noinst_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) fipsdrv$(EXEEXT) \
-       rsacvt$(EXEEXT) genhashdata$(EXEEXT)
+       rsacvt$(EXEEXT) genhashdata$(EXEEXT) gchash$(EXEEXT)
 subdir = tests
-DIST_COMMON = README $(noinst_HEADERS) $(srcdir)/Makefile.am \
-       $(srcdir)/Makefile.in $(srcdir)/hashtest-256g.in
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+       $(srcdir)/hashtest-256g.in $(top_srcdir)/build-aux/depcomp \
+       $(noinst_HEADERS) README
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/gpg-error.m4 \
-       $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/lock.m4 \
-       $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
-       $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+       $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+       $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+       $(top_srcdir)/m4/lt~obsolete.m4 \
        $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \
        $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
-       $(top_srcdir)/m4/threadlib.m4 $(top_srcdir)/acinclude.m4 \
-       $(top_srcdir)/configure.ac
+       $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES = hashtest-256g
 CONFIG_CLEAN_VPATH_FILES =
-am__EXEEXT_1 = version$(EXEEXT) mpitests$(EXEEXT) tsexp$(EXEEXT) \
+am__EXEEXT_1 = version$(EXEEXT) mpitests$(EXEEXT) t-sexp$(EXEEXT) \
        t-convert$(EXEEXT) t-mpi-bit$(EXEEXT) t-mpi-point$(EXEEXT) \
        curves$(EXEEXT) t-lock$(EXEEXT) prime$(EXEEXT) basic$(EXEEXT) \
        keygen$(EXEEXT) pubkey$(EXEEXT) hmac$(EXEEXT) \
        hashtest$(EXEEXT) t-kdf$(EXEEXT) keygrip$(EXEEXT) \
        fips186-dsa$(EXEEXT) aeswrap$(EXEEXT) pkcs1v2$(EXEEXT) \
-       random$(EXEEXT) dsa-rfc6979$(EXEEXT) t-ed25519$(EXEEXT)
+       random$(EXEEXT) dsa-rfc6979$(EXEEXT) t-ed25519$(EXEEXT) \
+       t-cv25519$(EXEEXT)
 am__EXEEXT_2 = benchmark$(EXEEXT) bench-slope$(EXEEXT)
 PROGRAMS = $(noinst_PROGRAMS)
 aeswrap_SOURCES = aeswrap.c
@@ -107,11 +135,12 @@ aeswrap_OBJECTS = aeswrap.$(OBJEXT)
 aeswrap_LDADD = $(LDADD)
 am__DEPENDENCIES_1 =
 am__DEPENDENCIES_2 = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
-       ../compat/libcompat.la $(am__DEPENDENCIES_1)
+       ../compat/libcompat.la
 aeswrap_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
 AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
 am__v_lt_0 = --silent
+am__v_lt_1 = 
 basic_SOURCES = basic.c
 basic_OBJECTS = basic.$(OBJEXT)
 basic_LDADD = $(LDADD)
@@ -140,6 +169,10 @@ fipsdrv_SOURCES = fipsdrv.c
 fipsdrv_OBJECTS = fipsdrv.$(OBJEXT)
 fipsdrv_LDADD = $(LDADD)
 fipsdrv_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
+gchash_SOURCES = gchash.c
+gchash_OBJECTS = gchash.$(OBJEXT)
+gchash_LDADD = $(LDADD)
+gchash_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
 genhashdata_SOURCES = genhashdata.c
 genhashdata_OBJECTS = genhashdata.$(OBJEXT)
 genhashdata_LDADD = $(LDADD)
@@ -192,6 +225,10 @@ t_convert_SOURCES = t-convert.c
 t_convert_OBJECTS = t-convert.$(OBJEXT)
 t_convert_LDADD = $(LDADD)
 t_convert_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
+t_cv25519_SOURCES = t-cv25519.c
+t_cv25519_OBJECTS = t-cv25519.$(OBJEXT)
+t_cv25519_LDADD = $(LDADD)
+t_cv25519_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
 t_ed25519_SOURCES = t-ed25519.c
 t_ed25519_OBJECTS = t-ed25519.$(OBJEXT)
 t_ed25519_LDADD = $(LDADD)
@@ -201,8 +238,11 @@ t_kdf_OBJECTS = t-kdf.$(OBJEXT)
 t_kdf_LDADD = $(LDADD)
 t_kdf_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
 t_lock_SOURCES = t-lock.c
-t_lock_OBJECTS = t-lock.$(OBJEXT)
+t_lock_OBJECTS = t_lock-t-lock.$(OBJEXT)
 t_lock_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
+t_lock_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+       $(LIBTOOLFLAGS) --mode=link $(CCLD) $(t_lock_CFLAGS) $(CFLAGS) \
+       $(AM_LDFLAGS) $(LDFLAGS) -o $@
 t_mpi_bit_SOURCES = t-mpi-bit.c
 t_mpi_bit_OBJECTS = t-mpi-bit.$(OBJEXT)
 t_mpi_bit_LDADD = $(LDADD)
@@ -211,18 +251,30 @@ t_mpi_point_SOURCES = t-mpi-point.c
 t_mpi_point_OBJECTS = t-mpi-point.$(OBJEXT)
 t_mpi_point_LDADD = $(LDADD)
 t_mpi_point_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
+t_sexp_SOURCES = t-sexp.c
+t_sexp_OBJECTS = t-sexp.$(OBJEXT)
+t_sexp_LDADD = $(LDADD)
+t_sexp_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
 testapi_SOURCES = testapi.c
 testapi_OBJECTS = testapi.$(OBJEXT)
 testapi_LDADD = $(LDADD)
 testapi_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
-tsexp_SOURCES = tsexp.c
-tsexp_OBJECTS = tsexp.$(OBJEXT)
-tsexp_LDADD = $(LDADD)
-tsexp_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
 version_SOURCES = version.c
 version_OBJECTS = version.$(OBJEXT)
 version_LDADD = $(LDADD)
 version_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
 depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
 am__depfiles_maybe = depfiles
@@ -235,42 +287,75 @@ LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(AM_CFLAGS) $(CFLAGS)
 AM_V_CC = $(am__v_CC_@AM_V@)
 am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
-am__v_CC_0 = @echo "  CC    " $@;
-AM_V_at = $(am__v_at_@AM_V@)
-am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
-am__v_at_0 = @
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
 CCLD = $(CC)
 LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
        $(AM_LDFLAGS) $(LDFLAGS) -o $@
 AM_V_CCLD = $(am__v_CCLD_@AM_V@)
 am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
-am__v_CCLD_0 = @echo "  CCLD  " $@;
-AM_V_GEN = $(am__v_GEN_@AM_V@)
-am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
-am__v_GEN_0 = @echo "  GEN   " $@;
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
 SOURCES = aeswrap.c basic.c bench-slope.c benchmark.c curves.c \
-       dsa-rfc6979.c fips186-dsa.c fipsdrv.c genhashdata.c hashtest.c \
-       hmac.c keygen.c keygrip.c mpitests.c pkbench.c pkcs1v2.c \
-       prime.c pubkey.c random.c rsacvt.c t-convert.c t-ed25519.c \
-       t-kdf.c t-lock.c t-mpi-bit.c t-mpi-point.c testapi.c tsexp.c \
-       version.c
+       dsa-rfc6979.c fips186-dsa.c fipsdrv.c gchash.c genhashdata.c \
+       hashtest.c hmac.c keygen.c keygrip.c mpitests.c pkbench.c \
+       pkcs1v2.c prime.c pubkey.c random.c rsacvt.c t-convert.c \
+       t-cv25519.c t-ed25519.c t-kdf.c t-lock.c t-mpi-bit.c \
+       t-mpi-point.c t-sexp.c testapi.c version.c
 DIST_SOURCES = aeswrap.c basic.c bench-slope.c benchmark.c curves.c \
-       dsa-rfc6979.c fips186-dsa.c fipsdrv.c genhashdata.c hashtest.c \
-       hmac.c keygen.c keygrip.c mpitests.c pkbench.c pkcs1v2.c \
-       prime.c pubkey.c random.c rsacvt.c t-convert.c t-ed25519.c \
-       t-kdf.c t-lock.c t-mpi-bit.c t-mpi-point.c testapi.c tsexp.c \
-       version.c
+       dsa-rfc6979.c fips186-dsa.c fipsdrv.c gchash.c genhashdata.c \
+       hashtest.c hmac.c keygen.c keygrip.c mpitests.c pkbench.c \
+       pkcs1v2.c prime.c pubkey.c random.c rsacvt.c t-convert.c \
+       t-cv25519.c t-ed25519.c t-kdf.c t-lock.c t-mpi-bit.c \
+       t-mpi-point.c t-sexp.c testapi.c version.c
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
 HEADERS = $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
 ETAGS = etags
 CTAGS = ctags
-am__tty_colors = \
-red=; grn=; lgn=; blu=; std=
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red='\e[0;31m'; \
+    grn='\e[0;32m'; \
+    lgn='\e[1;32m'; \
+    blu='\e[1;34m'; \
+    mgn='\e[0;35m'; \
+    brg='\e[1m'; \
+    std='\e[m'; \
+  fi; \
+}
 am__EXEEXT_3 =
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
@@ -317,6 +402,8 @@ GCRYPT_RANDOM = @GCRYPT_RANDOM@
 GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
 GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
 GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GPG_ERROR_MT_CFLAGS = @GPG_ERROR_MT_CFLAGS@
+GPG_ERROR_MT_LIBS = @GPG_ERROR_MT_LIBS@
 GREP = @GREP@
 INSERT_SYS_SELECT_H = @INSERT_SYS_SELECT_H@
 INSTALL = @INSTALL@
@@ -337,16 +424,12 @@ LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@
 LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@
 LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@
 LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@
-LIBMULTITHREAD = @LIBMULTITHREAD@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
-LIBTHREAD = @LIBTHREAD@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
-LTLIBMULTITHREAD = @LTLIBMULTITHREAD@
 LTLIBOBJS = @LTLIBOBJS@
-LTLIBTHREAD = @LTLIBTHREAD@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
@@ -377,6 +460,7 @@ SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
+SYSROOT = @SYSROOT@
 SYS_SOCKET_H = @SYS_SOCKET_H@
 VERSION = @VERSION@
 VERSION_NUMBER = @VERSION_NUMBER@
@@ -436,10 +520,10 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tests_bin = \
-        version mpitests tsexp t-convert \
+        version mpitests t-sexp t-convert \
        t-mpi-bit t-mpi-point curves t-lock \
        prime basic keygen pubkey hmac hashtest t-kdf keygrip \
-       fips186-dsa aeswrap pkcs1v2 random dsa-rfc6979 t-ed25519
+       fips186-dsa aeswrap pkcs1v2 random dsa-rfc6979 t-ed25519 t-cv25519
 
 tests_bin_last = benchmark bench-slope
 tests_sh = 
@@ -451,17 +535,19 @@ TESTS_ENVIRONMENT = GCRYPT_IN_REGRESSION_TEST=1
 AM_CPPFLAGS = -I../src -I$(top_srcdir)/src
 AM_CFLAGS = $(GPG_ERROR_CFLAGS)
 AM_LDFLAGS = -no-install
-default_ldadd = \
+standard_ldadd = \
        ../src/libgcrypt.la $(DL_LIBS) \
-        ../compat/libcompat.la $(GPG_ERROR_LIBS)
+        ../compat/libcompat.la
 
 noinst_HEADERS = t-common.h
 EXTRA_DIST = README rsa-16k.key cavs_tests.sh cavs_driver.pl \
             pkcs1v2-oaep.h pkcs1v2-pss.h pkcs1v2-v15c.h pkcs1v2-v15s.h \
-            t-ed25519.inp stopwatch.h hashtest-256g.in
+            t-ed25519.inp stopwatch.h hashtest-256g.in \
+            sha3-224.h sha3-256.h sha3-384.h sha3-512.h
 
-LDADD = $(default_ldadd) $(LIBTHREAD)
-t_lock_LDADD = $(default_ldadd) $(LIBMULTITHREAD)
+LDADD = $(standard_ldadd) $(GPG_ERROR_LIBS)
+t_lock_LDADD = $(standard_ldadd) $(GPG_ERROR_MT_LIBS)
+t_lock_CFLAGS = $(GPG_ERROR_MT_CFLAGS)
 all: all-am
 
 .SUFFIXES:
@@ -507,90 +593,127 @@ clean-noinstPROGRAMS:
        list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
        echo " rm -f" $$list; \
        rm -f $$list
+
 aeswrap$(EXEEXT): $(aeswrap_OBJECTS) $(aeswrap_DEPENDENCIES) $(EXTRA_aeswrap_DEPENDENCIES) 
        @rm -f aeswrap$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(aeswrap_OBJECTS) $(aeswrap_LDADD) $(LIBS)
+
 basic$(EXEEXT): $(basic_OBJECTS) $(basic_DEPENDENCIES) $(EXTRA_basic_DEPENDENCIES) 
        @rm -f basic$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(basic_OBJECTS) $(basic_LDADD) $(LIBS)
+
 bench-slope$(EXEEXT): $(bench_slope_OBJECTS) $(bench_slope_DEPENDENCIES) $(EXTRA_bench_slope_DEPENDENCIES) 
        @rm -f bench-slope$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(bench_slope_OBJECTS) $(bench_slope_LDADD) $(LIBS)
+
 benchmark$(EXEEXT): $(benchmark_OBJECTS) $(benchmark_DEPENDENCIES) $(EXTRA_benchmark_DEPENDENCIES) 
        @rm -f benchmark$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(benchmark_OBJECTS) $(benchmark_LDADD) $(LIBS)
+
 curves$(EXEEXT): $(curves_OBJECTS) $(curves_DEPENDENCIES) $(EXTRA_curves_DEPENDENCIES) 
        @rm -f curves$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(curves_OBJECTS) $(curves_LDADD) $(LIBS)
+
 dsa-rfc6979$(EXEEXT): $(dsa_rfc6979_OBJECTS) $(dsa_rfc6979_DEPENDENCIES) $(EXTRA_dsa_rfc6979_DEPENDENCIES) 
        @rm -f dsa-rfc6979$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(dsa_rfc6979_OBJECTS) $(dsa_rfc6979_LDADD) $(LIBS)
+
 fips186-dsa$(EXEEXT): $(fips186_dsa_OBJECTS) $(fips186_dsa_DEPENDENCIES) $(EXTRA_fips186_dsa_DEPENDENCIES) 
        @rm -f fips186-dsa$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(fips186_dsa_OBJECTS) $(fips186_dsa_LDADD) $(LIBS)
+
 fipsdrv$(EXEEXT): $(fipsdrv_OBJECTS) $(fipsdrv_DEPENDENCIES) $(EXTRA_fipsdrv_DEPENDENCIES) 
        @rm -f fipsdrv$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(fipsdrv_OBJECTS) $(fipsdrv_LDADD) $(LIBS)
+
+gchash$(EXEEXT): $(gchash_OBJECTS) $(gchash_DEPENDENCIES) $(EXTRA_gchash_DEPENDENCIES) 
+       @rm -f gchash$(EXEEXT)
+       $(AM_V_CCLD)$(LINK) $(gchash_OBJECTS) $(gchash_LDADD) $(LIBS)
+
 genhashdata$(EXEEXT): $(genhashdata_OBJECTS) $(genhashdata_DEPENDENCIES) $(EXTRA_genhashdata_DEPENDENCIES) 
        @rm -f genhashdata$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(genhashdata_OBJECTS) $(genhashdata_LDADD) $(LIBS)
+
 hashtest$(EXEEXT): $(hashtest_OBJECTS) $(hashtest_DEPENDENCIES) $(EXTRA_hashtest_DEPENDENCIES) 
        @rm -f hashtest$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(hashtest_OBJECTS) $(hashtest_LDADD) $(LIBS)
+
 hmac$(EXEEXT): $(hmac_OBJECTS) $(hmac_DEPENDENCIES) $(EXTRA_hmac_DEPENDENCIES) 
        @rm -f hmac$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(hmac_OBJECTS) $(hmac_LDADD) $(LIBS)
+
 keygen$(EXEEXT): $(keygen_OBJECTS) $(keygen_DEPENDENCIES) $(EXTRA_keygen_DEPENDENCIES) 
        @rm -f keygen$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(keygen_OBJECTS) $(keygen_LDADD) $(LIBS)
+
 keygrip$(EXEEXT): $(keygrip_OBJECTS) $(keygrip_DEPENDENCIES) $(EXTRA_keygrip_DEPENDENCIES) 
        @rm -f keygrip$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(keygrip_OBJECTS) $(keygrip_LDADD) $(LIBS)
+
 mpitests$(EXEEXT): $(mpitests_OBJECTS) $(mpitests_DEPENDENCIES) $(EXTRA_mpitests_DEPENDENCIES) 
        @rm -f mpitests$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(mpitests_OBJECTS) $(mpitests_LDADD) $(LIBS)
+
 pkbench$(EXEEXT): $(pkbench_OBJECTS) $(pkbench_DEPENDENCIES) $(EXTRA_pkbench_DEPENDENCIES) 
        @rm -f pkbench$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(pkbench_OBJECTS) $(pkbench_LDADD) $(LIBS)
+
 pkcs1v2$(EXEEXT): $(pkcs1v2_OBJECTS) $(pkcs1v2_DEPENDENCIES) $(EXTRA_pkcs1v2_DEPENDENCIES) 
        @rm -f pkcs1v2$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(pkcs1v2_OBJECTS) $(pkcs1v2_LDADD) $(LIBS)
+
 prime$(EXEEXT): $(prime_OBJECTS) $(prime_DEPENDENCIES) $(EXTRA_prime_DEPENDENCIES) 
        @rm -f prime$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(prime_OBJECTS) $(prime_LDADD) $(LIBS)
+
 pubkey$(EXEEXT): $(pubkey_OBJECTS) $(pubkey_DEPENDENCIES) $(EXTRA_pubkey_DEPENDENCIES) 
        @rm -f pubkey$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(pubkey_OBJECTS) $(pubkey_LDADD) $(LIBS)
+
 random$(EXEEXT): $(random_OBJECTS) $(random_DEPENDENCIES) $(EXTRA_random_DEPENDENCIES) 
        @rm -f random$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(random_OBJECTS) $(random_LDADD) $(LIBS)
+
 rsacvt$(EXEEXT): $(rsacvt_OBJECTS) $(rsacvt_DEPENDENCIES) $(EXTRA_rsacvt_DEPENDENCIES) 
        @rm -f rsacvt$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(rsacvt_OBJECTS) $(rsacvt_LDADD) $(LIBS)
+
 t-convert$(EXEEXT): $(t_convert_OBJECTS) $(t_convert_DEPENDENCIES) $(EXTRA_t_convert_DEPENDENCIES) 
        @rm -f t-convert$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(t_convert_OBJECTS) $(t_convert_LDADD) $(LIBS)
+
+t-cv25519$(EXEEXT): $(t_cv25519_OBJECTS) $(t_cv25519_DEPENDENCIES) $(EXTRA_t_cv25519_DEPENDENCIES) 
+       @rm -f t-cv25519$(EXEEXT)
+       $(AM_V_CCLD)$(LINK) $(t_cv25519_OBJECTS) $(t_cv25519_LDADD) $(LIBS)
+
 t-ed25519$(EXEEXT): $(t_ed25519_OBJECTS) $(t_ed25519_DEPENDENCIES) $(EXTRA_t_ed25519_DEPENDENCIES) 
        @rm -f t-ed25519$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(t_ed25519_OBJECTS) $(t_ed25519_LDADD) $(LIBS)
+
 t-kdf$(EXEEXT): $(t_kdf_OBJECTS) $(t_kdf_DEPENDENCIES) $(EXTRA_t_kdf_DEPENDENCIES) 
        @rm -f t-kdf$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(t_kdf_OBJECTS) $(t_kdf_LDADD) $(LIBS)
+
 t-lock$(EXEEXT): $(t_lock_OBJECTS) $(t_lock_DEPENDENCIES) $(EXTRA_t_lock_DEPENDENCIES) 
        @rm -f t-lock$(EXEEXT)
-       $(AM_V_CCLD)$(LINK) $(t_lock_OBJECTS) $(t_lock_LDADD) $(LIBS)
+       $(AM_V_CCLD)$(t_lock_LINK) $(t_lock_OBJECTS) $(t_lock_LDADD) $(LIBS)
+
 t-mpi-bit$(EXEEXT): $(t_mpi_bit_OBJECTS) $(t_mpi_bit_DEPENDENCIES) $(EXTRA_t_mpi_bit_DEPENDENCIES) 
        @rm -f t-mpi-bit$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(t_mpi_bit_OBJECTS) $(t_mpi_bit_LDADD) $(LIBS)
+
 t-mpi-point$(EXEEXT): $(t_mpi_point_OBJECTS) $(t_mpi_point_DEPENDENCIES) $(EXTRA_t_mpi_point_DEPENDENCIES) 
        @rm -f t-mpi-point$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(t_mpi_point_OBJECTS) $(t_mpi_point_LDADD) $(LIBS)
+
+t-sexp$(EXEEXT): $(t_sexp_OBJECTS) $(t_sexp_DEPENDENCIES) $(EXTRA_t_sexp_DEPENDENCIES) 
+       @rm -f t-sexp$(EXEEXT)
+       $(AM_V_CCLD)$(LINK) $(t_sexp_OBJECTS) $(t_sexp_LDADD) $(LIBS)
+
 testapi$(EXEEXT): $(testapi_OBJECTS) $(testapi_DEPENDENCIES) $(EXTRA_testapi_DEPENDENCIES) 
        @rm -f testapi$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(testapi_OBJECTS) $(testapi_LDADD) $(LIBS)
-tsexp$(EXEEXT): $(tsexp_OBJECTS) $(tsexp_DEPENDENCIES) $(EXTRA_tsexp_DEPENDENCIES) 
-       @rm -f tsexp$(EXEEXT)
-       $(AM_V_CCLD)$(LINK) $(tsexp_OBJECTS) $(tsexp_LDADD) $(LIBS)
+
 version$(EXEEXT): $(version_OBJECTS) $(version_DEPENDENCIES) $(EXTRA_version_DEPENDENCIES) 
        @rm -f version$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(version_OBJECTS) $(version_LDADD) $(LIBS)
@@ -609,6 +732,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dsa-rfc6979.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fips186-dsa.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fipsdrv.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gchash.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/genhashdata.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hashtest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmac.Po@am__quote@
@@ -622,13 +746,14 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsacvt.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-convert.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-cv25519.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-ed25519.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-kdf.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-lock.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-mpi-bit.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-mpi-point.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-sexp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_lock-t-lock.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testapi.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsexp.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@
 
 .c.o:
@@ -636,14 +761,14 @@ distclean-compile:
 @am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
 
 .c.obj:
 @am__fastdepCC_TRUE@   $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
 @am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
 
 .c.lo:
 @am__fastdepCC_TRUE@   $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -652,32 +777,35 @@ distclean-compile:
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
 
+t_lock-t-lock.o: t-lock.c
+@am__fastdepCC_TRUE@   $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(t_lock_CFLAGS) $(CFLAGS) -MT t_lock-t-lock.o -MD -MP -MF $(DEPDIR)/t_lock-t-lock.Tpo -c -o t_lock-t-lock.o `test -f 't-lock.c' || echo '$(srcdir)/'`t-lock.c
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/t_lock-t-lock.Tpo $(DEPDIR)/t_lock-t-lock.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='t-lock.c' object='t_lock-t-lock.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(t_lock_CFLAGS) $(CFLAGS) -c -o t_lock-t-lock.o `test -f 't-lock.c' || echo '$(srcdir)/'`t-lock.c
+
+t_lock-t-lock.obj: t-lock.c
+@am__fastdepCC_TRUE@   $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(t_lock_CFLAGS) $(CFLAGS) -MT t_lock-t-lock.obj -MD -MP -MF $(DEPDIR)/t_lock-t-lock.Tpo -c -o t_lock-t-lock.obj `if test -f 't-lock.c'; then $(CYGPATH_W) 't-lock.c'; else $(CYGPATH_W) '$(srcdir)/t-lock.c'; fi`
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/t_lock-t-lock.Tpo $(DEPDIR)/t_lock-t-lock.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='t-lock.c' object='t_lock-t-lock.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(t_lock_CFLAGS) $(CFLAGS) -c -o t_lock-t-lock.obj `if test -f 't-lock.c'; then $(CYGPATH_W) 't-lock.c'; else $(CYGPATH_W) '$(srcdir)/t-lock.c'; fi`
+
 mostlyclean-libtool:
        -rm -f *.lo
 
 clean-libtool:
        -rm -rf .libs _libs
 
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
-       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
-       unique=`for i in $$list; do \
-           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-         done | \
-         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-             END { if (nonempty) { for (i in files) print i; }; }'`; \
-       mkid -fID $$unique
-tags: TAGS
-
-TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-               $(TAGS_FILES) $(LISP)
+ID: $(am__tagged_files)
+       $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
        set x; \
        here=`pwd`; \
-       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-       unique=`for i in $$list; do \
-           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-         done | \
-         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-             END { if (nonempty) { for (i in files) print i; }; }'`; \
+       $(am__define_uniq_tagged_files); \
        shift; \
        if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
@@ -689,15 +817,11 @@ TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
              $$unique; \
          fi; \
        fi
-ctags: CTAGS
-CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-               $(TAGS_FILES) $(LISP)
-       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-       unique=`for i in $$list; do \
-           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-         done | \
-         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-             END { if (nonempty) { for (i in files) print i; }; }'`; \
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+       $(am__define_uniq_tagged_files); \
        test -z "$(CTAGS_ARGS)$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$unique
@@ -706,6 +830,21 @@ GTAGS:
        here=`$(am__cd) $(top_builddir) && pwd` \
          && $(am__cd) $(top_srcdir) \
          && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+       list='$(am__tagged_files)'; \
+       case "$(srcdir)" in \
+         [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+         *) sdir=$(subdir)/$(srcdir) ;; \
+       esac; \
+       for i in $$list; do \
+         if test -f "$$i"; then \
+           echo "$(subdir)/$$i"; \
+         else \
+           echo "$$sdir/$$i"; \
+         fi; \
+       done >> $(top_builddir)/cscope.files
 
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
@@ -720,7 +859,7 @@ check-TESTS: $(TESTS)
            if test -f ./$$tst; then dir=./; \
            elif test -f $$tst; then dir=; \
            else dir="$(srcdir)/"; fi; \
-           if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+           if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \
              all=`expr $$all + 1`; \
              case " $(XFAIL_TESTS) " in \
              *[\ \     ]$$tst[\ \      ]*) \
@@ -941,9 +1080,9 @@ uninstall-am:
 
 .MAKE: check-am install-am install-strip
 
-.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \
-       clean-generic clean-libtool clean-noinstPROGRAMS ctags \
-       distclean distclean-compile distclean-generic \
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+       clean-generic clean-libtool clean-noinstPROGRAMS cscopelist-am \
+       ctags ctags-am distclean distclean-compile distclean-generic \
        distclean-libtool distclean-tags distdir dvi dvi-am html \
        html-am info info-am install install-am install-data \
        install-data-am install-dvi install-dvi-am install-exec \
@@ -953,7 +1092,7 @@ uninstall-am:
        installcheck-am installdirs maintainer-clean \
        maintainer-clean-generic mostlyclean mostlyclean-compile \
        mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-       tags uninstall uninstall-am
+       tags tags-am uninstall uninstall-am
 
 
 # Force sequential run of some tests.
index 86be89d..96fb4cb 100644 (file)
@@ -34,6 +34,7 @@
 # define DIM(v)                     (sizeof(v)/sizeof((v)[0]))
 #endif
 
+#define PGM "basic"
 
 typedef struct test_spec_pubkey_key
 {
@@ -60,6 +61,22 @@ static int error_count;
 static int in_fips_mode;
 static int die_on_error;
 
+#define MAX_DATA_LEN 128
+
+#define digitp(p)   (*(p) >= '0' && *(p) <= '9')
+#define hexdigitp(a) (digitp (a)                     \
+                      || (*(a) >= 'A' && *(a) <= 'F')  \
+                      || (*(a) >= 'a' && *(a) <= 'f'))
+#define xtoi_1(p)   (*(p) <= '9'? (*(p)- '0'): \
+                     *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
+#define xtoi_2(p)   ((xtoi_1(p) * 16) + xtoi_1((p)+1))
+#define xmalloc(a)    gcry_xmalloc ((a))
+#define xcalloc(a,b)  gcry_xcalloc ((a),(b))
+#define xstrdup(a)    gcry_xstrdup ((a))
+#define xfree(a)      gcry_free ((a))
+
+
+
 static void
 fail (const char *format, ...)
 {
@@ -73,6 +90,7 @@ fail (const char *format, ...)
     exit (1);
 }
 
+
 static void
 mismatch (const void *expected, size_t expectedlen,
           const void *computed, size_t computedlen)
@@ -101,6 +119,30 @@ die (const char *format, ...)
 }
 
 
+/* Convert STRING consisting of hex characters into its binary
+   representation and return it as an allocated buffer. The valid
+   length of the buffer is returned at R_LENGTH.  The string is
+   delimited by end of string.  The function terminates on error.  */
+static void *
+hex2buffer (const char *string, size_t *r_length)
+{
+  const char *s;
+  unsigned char *buffer;
+  size_t length;
+
+  buffer = xmalloc (strlen(string)/2+1);
+  length = 0;
+  for (s=string; *s; s +=2 )
+    {
+      if (!hexdigitp (s) || !hexdigitp (s+1))
+        die ("invalid hex digits in \"%s\"\n", string);
+      ((unsigned char*)buffer)[length++] = xtoi_2 (s);
+    }
+  *r_length = length;
+  return buffer;
+}
+
+
 static void
 show_sexp (const char *prefix, gcry_sexp_t a)
 {
@@ -118,7 +160,81 @@ show_sexp (const char *prefix, gcry_sexp_t a)
 }
 
 
-#define MAX_DATA_LEN 100
+static void
+show_note (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  if (!verbose && getenv ("srcdir"))
+    fputs ("      ", stderr);  /* To align above "PASS: ".  */
+  else
+    fprintf (stderr, "%s: ", PGM);
+  va_start (arg_ptr, format);
+  vfprintf (stderr, format, arg_ptr);
+  if (*format && format[strlen(format)-1] != '\n')
+    putc ('\n', stderr);
+  va_end (arg_ptr);
+}
+
+
+static void
+show_md_not_available (int algo)
+{
+  static int list[100];
+  static int listlen;
+  int i;
+
+  if (!verbose && algo == GCRY_MD_MD2)
+    return;  /* Do not print the diagnostic for that one.  */
+
+  for (i=0; i < listlen; i++)
+    if (algo == list[i])
+      return; /* Note already printed.  */
+  if (listlen < DIM (list))
+    list[listlen++] = algo;
+  show_note ("hash algorithm %d not available - skipping tests", algo);
+}
+
+
+static void
+show_old_hmac_not_available (int algo)
+{
+  static int list[100];
+  static int listlen;
+  int i;
+
+  if (!verbose && algo == GCRY_MD_MD2)
+    return;  /* Do not print the diagnostic for that one.  */
+
+  for (i=0; i < listlen; i++)
+    if (algo == list[i])
+      return; /* Note already printed.  */
+  if (listlen < DIM (list))
+    list[listlen++] = algo;
+  show_note ("hash algorithm %d for old HMAC API not available "
+             "- skipping tests", algo);
+}
+
+
+static void
+show_mac_not_available (int algo)
+{
+  static int list[100];
+  static int listlen;
+  int i;
+
+  if (!verbose && algo == GCRY_MD_MD2)
+    return;  /* Do not print the diagnostic for that one.  */
+
+  for (i=0; i < listlen; i++)
+    if (algo == list[i])
+      return; /* Note already printed.  */
+  if (listlen < DIM (list))
+    list[listlen++] = algo;
+  show_note ("MAC algorithm %d not available - skipping tests", algo);
+}
+
+
 
 void
 progress_handler (void *cb_data, const char *what, int printchar,
@@ -574,6 +690,7 @@ check_ctr_cipher (void)
   unsigned char out[MAX_DATA_LEN];
   int i, j, keylen, blklen;
   gcry_error_t err = 0;
+  size_t taglen2;
 
   if (verbose)
     fprintf (stderr, "  Starting CTR cipher checks.\n");
@@ -582,6 +699,14 @@ check_ctr_cipher (void)
       if (!tv[i].algo)
         continue;
 
+      if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode)
+        {
+          if (verbose)
+            fprintf (stderr, "  algorithm %d not available in fips mode\n",
+                    tv[i].algo);
+          continue;
+        }
+
       err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0);
       if (!err)
        err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0);
@@ -629,6 +754,17 @@ check_ctr_cipher (void)
          return;
        }
 
+
+      err = gcry_cipher_info (hde, GCRYCTL_GET_TAGLEN, NULL, &taglen2);
+      if (gpg_err_code (err) != GPG_ERR_INV_CIPHER_MODE)
+        {
+          fail ("aes-ctr, gcryctl_get_taglen failed to fail (tv %d): %s\n",
+                i, gpg_strerror (err));
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
+
       if (verbose)
        fprintf (stderr, "    checking CTR mode for %s [%i]\n",
                 gcry_cipher_algo_name (tv[i].algo),
@@ -737,6 +873,7 @@ check_cfb_cipher (void)
   static const struct tv
   {
     int algo;
+    int cfb8;
     char key[MAX_DATA_LEN];
     char iv[MAX_DATA_LEN];
     struct data
@@ -749,7 +886,7 @@ check_cfb_cipher (void)
   } tv[] =
     {
       /* http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf */
-      { GCRY_CIPHER_AES,
+      { GCRY_CIPHER_AES, 0,
         "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
         "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
         { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
@@ -766,7 +903,7 @@ check_cfb_cipher (void)
             "\xc0\x4b\x05\x35\x7c\x5d\x1c\x0e\xea\xc4\xc6\x6f\x9f\xf7\xf2\xe6" },
         }
       },
-      { GCRY_CIPHER_AES192,
+      { GCRY_CIPHER_AES192, 0,
         "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b"
         "\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
         "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
@@ -784,7 +921,7 @@ check_cfb_cipher (void)
             "\xc0\x5f\x9f\x9c\xa9\x83\x4f\xa0\x42\xae\x8f\xba\x58\x4b\x09\xff" },
         }
       },
-      { GCRY_CIPHER_AES256,
+      { GCRY_CIPHER_AES256, 0,
         "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81"
         "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
         "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
@@ -805,7 +942,7 @@ check_cfb_cipher (void)
     };
   gcry_cipher_hd_t hde, hdd;
   unsigned char out[MAX_DATA_LEN];
-  int i, j, keylen, blklen;
+  int i, j, keylen, blklen, mode;
   gcry_error_t err = 0;
 
   if (verbose)
@@ -813,13 +950,23 @@ check_cfb_cipher (void)
 
   for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
     {
+      if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode)
+        {
+          if (verbose)
+            fprintf (stderr, "  algorithm %d not available in fips mode\n",
+                    tv[i].algo);
+          continue;
+        }
+
+      mode = tv[i].cfb8? GCRY_CIPHER_MODE_CFB8 : GCRY_CIPHER_MODE_CFB;
+
       if (verbose)
         fprintf (stderr, "    checking CFB mode for %s [%i]\n",
                 gcry_cipher_algo_name (tv[i].algo),
                 tv[i].algo);
-      err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_CFB, 0);
+      err = gcry_cipher_open (&hde, tv[i].algo, mode, 0);
       if (!err)
-        err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_CFB, 0);
+        err = gcry_cipher_open (&hdd, tv[i].algo, mode, 0);
       if (err)
         {
           fail ("aes-cfb, gcry_cipher_open failed: %s\n", gpg_strerror (err));
@@ -984,6 +1131,14 @@ check_ofb_cipher (void)
 
   for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
     {
+      if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode)
+        {
+          if (verbose)
+            fprintf (stderr, "  algorithm %d not available in fips mode\n",
+                    tv[i].algo);
+          continue;
+        }
+
       if (verbose)
         fprintf (stderr, "    checking OFB mode for %s [%i]\n",
                 gcry_cipher_algo_name (tv[i].algo),
@@ -1152,6 +1307,8 @@ _check_gcm_cipher (unsigned int step)
     int inlen;
     char out[MAX_DATA_LEN];
     char tag[MAX_DATA_LEN];
+    int taglen;
+    int should_fail;
   } tv[] =
     {
       /* http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf */
@@ -1167,6 +1324,78 @@ _check_gcm_cipher (unsigned int step)
         "\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", 12,
         "", 0,
+        "",
+        0,
+        "",
+        "\x58\xe2\xfc\xce\xfa\x7e\x30\x61\x36\x7f\x1d\x57\xa4\xe7\x45",
+        15 },
+      { GCRY_CIPHER_AES,
+        "\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", 12,
+        "", 0,
+        "",
+        0,
+        "",
+        "\x58\xe2\xfc\xce\xfa\x7e\x30\x61\x36\x7f\x1d\x57\xa4\xe7",
+        14 },
+      { GCRY_CIPHER_AES,
+        "\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", 12,
+        "", 0,
+        "",
+        0,
+        "",
+        "\x58\xe2\xfc\xce\xfa\x7e\x30\x61\x36\x7f\x1d\x57\xa4",
+        13 },
+      { GCRY_CIPHER_AES,
+        "\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", 12,
+        "", 0,
+        "",
+        0,
+        "",
+        "\x58\xe2\xfc\xce\xfa\x7e\x30\x61\x36\x7f\x1d\x57",
+        12 },
+      { GCRY_CIPHER_AES,
+        "\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", 12,
+        "", 0,
+        "",
+        0,
+        "",
+        "\x58\xe2\xfc\xce\xfa\x7e\x30\x61\x36\x7f\x1d",
+        11, 1 },
+      { GCRY_CIPHER_AES,
+        "\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", 12,
+        "", 0,
+        "",
+        0,
+        "",
+        "\x58\xe2\xfc\xce\xfa\x7e\x30\x61",
+        8 },
+      { GCRY_CIPHER_AES,
+        "\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", 12,
+        "", 0,
+        "",
+        0,
+        "",
+        "\x58\xe2\xfc\xce",
+        4 },
+      { GCRY_CIPHER_AES,
+        "\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", 12,
+        "", 0,
+        "",
+        0,
+        "",
+        "\x58",
+        1, 1 },
+      { GCRY_CIPHER_AES,
+        "\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", 12,
+        "", 0,
         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
         16,
         "\x03\x88\xda\xce\x60\xb6\xa3\x92\xf3\x28\xc2\xb9\x71\xb2\xfe\x78",
@@ -1278,7 +1507,7 @@ _check_gcm_cipher (unsigned int step)
   unsigned char tag[GCRY_GCM_BLOCK_LEN];
   int i, keylen;
   gcry_error_t err = 0;
-  size_t pos, poslen;
+  size_t pos, poslen, taglen2;
   int byteNum;
 
   if (verbose)
@@ -1286,6 +1515,14 @@ _check_gcm_cipher (unsigned int step)
 
   for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
     {
+      if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode)
+        {
+          if (verbose)
+            fprintf (stderr, "  algorithm %d not available in fips mode\n",
+                    tv[i].algo);
+          continue;
+        }
+
       if (verbose)
         fprintf (stderr, "    checking GCM mode for %s [%i]\n",
                  gcry_cipher_algo_name (tv[i].algo),
@@ -1330,6 +1567,25 @@ _check_gcm_cipher (unsigned int step)
           return;
         }
 
+      err = gcry_cipher_info (hde, GCRYCTL_GET_TAGLEN, NULL, &taglen2);
+      if (err)
+        {
+          fail ("cipher-gcm, gcryctl_get_taglen failed (tv %d): %s\n",
+                i, gpg_strerror (err));
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
+      if (taglen2 != GCRY_GCM_BLOCK_LEN)
+        {
+          fail ("cipher-gcm, gcryctl_get_taglen returned bad length"
+                " (tv %d): got=%zu want=%d\n",
+                i, taglen2, GCRY_GCM_BLOCK_LEN);
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
+
       for (pos = 0; pos < tv[i].aadlen; pos += step)
         {
           poslen = (pos + step < tv[i].aadlen) ? step : tv[i].aadlen - pos;
@@ -1391,9 +1647,14 @@ _check_gcm_cipher (unsigned int step)
       if (memcmp (tv[i].plaintext, out, tv[i].inlen))
         fail ("aes-gcm, decrypt mismatch entry %d (step %d)\n", i, step);
 
-      err = gcry_cipher_gettag (hde, out, GCRY_GCM_BLOCK_LEN);
+      taglen2 = tv[i].taglen ? tv[i].taglen : GCRY_GCM_BLOCK_LEN;
+
+      err = gcry_cipher_gettag (hde, out, taglen2);
       if (err)
         {
+          if (tv[i].should_fail)
+            goto next_tv;
+
           fail ("aes-gcm, gcry_cipher_gettag(%d) failed: %s\n",
                 i, gpg_strerror (err));
           gcry_cipher_close (hde);
@@ -1401,11 +1662,10 @@ _check_gcm_cipher (unsigned int step)
           return;
         }
 
-      if (memcmp (tv[i].tag, out, GCRY_GCM_BLOCK_LEN))
+      if (memcmp (tv[i].tag, out, taglen2))
         fail ("aes-gcm, encrypt tag mismatch entry %d\n", i);
 
-
-      err = gcry_cipher_checktag (hdd, out, GCRY_GCM_BLOCK_LEN);
+      err = gcry_cipher_checktag (hdd, out, taglen2);
       if (err)
         {
           fail ("aes-gcm, gcry_cipher_checktag(%d) failed: %s\n",
@@ -1481,17 +1741,25 @@ _check_gcm_cipher (unsigned int step)
       if (memcmp (tv[i].out, out, tv[i].inlen))
         fail ("aes-gcm, encrypt mismatch entry %d, (byte-buf)\n", i);
 
-      err = gcry_cipher_gettag (hde, tag, GCRY_GCM_BLOCK_LEN);
+      /* Test output to larger than 16-byte buffer. */
+      taglen2 = tv[i].taglen ? tv[i].taglen : GCRY_GCM_BLOCK_LEN + 1;
+
+      err = gcry_cipher_gettag (hde, tag, taglen2);
       if (err)
         {
-          fail ("aes-gcm, gcry_cipher_gettag(%d) (byte-buf) failed: %s\n",
-                i, gpg_strerror (err));
+          if (tv[i].should_fail)
+            goto next_tv;
+
+          fail ("aes-gcm, gcry_cipher_gettag(%d, %d) (byte-buf) failed: %s\n",
+                i, taglen2, gpg_strerror (err));
           gcry_cipher_close (hde);
           gcry_cipher_close (hdd);
           return;
         }
 
-      if (memcmp (tv[i].tag, tag, GCRY_GCM_BLOCK_LEN))
+      taglen2 = tv[i].taglen ? tv[i].taglen : GCRY_GCM_BLOCK_LEN;
+
+      if (memcmp (tv[i].tag, tag, taglen2))
         fail ("aes-gcm, encrypt tag mismatch entry %d, (byte-buf)\n", i);
 
       for (byteNum = 0; byteNum < tv[i].inlen; ++byteNum)
@@ -1510,7 +1778,7 @@ _check_gcm_cipher (unsigned int step)
       if (memcmp (tv[i].plaintext, out, tv[i].inlen))
         fail ("aes-gcm, decrypt mismatch entry %d\n", i);
 
-      err = gcry_cipher_checktag (hdd, tag, GCRY_GCM_BLOCK_LEN);
+      err = gcry_cipher_checktag (hdd, tag, taglen2);
       if (err)
         {
           fail ("aes-gcm, gcry_cipher_checktag(%d) (byte-buf) failed: %s\n",
@@ -1520,6 +1788,34 @@ _check_gcm_cipher (unsigned int step)
           return;
         }
 
+      err = gcry_cipher_checktag (hdd, tag, 1);
+      if (!err)
+        {
+          fail ("aes-gcm, gcry_cipher_checktag(%d) did not fail for invalid "
+               " tag length of '%d'\n", i, 1);
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
+      err = gcry_cipher_checktag (hdd, tag, 17);
+      if (!err)
+        {
+          fail ("aes-gcm, gcry_cipher_checktag(%d) did not fail for invalid "
+               " tag length of '%d'\n", i, 17);
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
+
+      if (tv[i].should_fail)
+        {
+          fail ("aes-gcm, negative test succeeded %d\n", i);
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
+
+    next_tv:
       gcry_cipher_close (hde);
       gcry_cipher_close (hdd);
     }
@@ -1543,82 +1839,446 @@ check_gcm_cipher (void)
 
 
 static void
-check_ccm_cipher (void)
+_check_poly1305_cipher (unsigned int step)
 {
-#ifdef HAVE_U64_TYPEDEF
-  static const struct tv
+  struct tv
   {
     int algo;
-    int keylen;
     const char *key;
-    int noncelen;
-    const char *nonce;
-    int aadlen;
+    const char *iv;
+    int ivlen;
     const char *aad;
-    int plainlen;
+    int aadlen;
     const char *plaintext;
-    int cipherlen;
-    const char *ciphertext;
+    int inlen;
+    const char *out;
+    const char *tag;
   } tv[] =
     {
-      /* RFC 3610 */
-      { GCRY_CIPHER_AES, /* Packet Vector #1 */
-          16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
-          13, "\x00\x00\x00\x03\x02\x01\x00\xA0\xA1\xA2\xA3\xA4\xA5",
-          8, "\x00\x01\x02\x03\x04\x05\x06\x07",
-          23,
-          "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E",
-          31,
-          "\x58\x8C\x97\x9A\x61\xC6\x63\xD2\xF0\x66\xD0\xC2\xC0\xF9\x89\x80\x6D\x5F\x6B\x61\xDA\xC3\x84\x17\xE8\xD1\x2C\xFD\xF9\x26\xE0"},
-      { GCRY_CIPHER_AES, /* Packet Vector #2 */
-          16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
-          13, "\x00\x00\x00\x04\x03\x02\x01\xA0\xA1\xA2\xA3\xA4\xA5",
-          8, "\x00\x01\x02\x03\x04\x05\x06\x07",
-          24,
-          "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F",
-          32,
-          "\x72\xC9\x1A\x36\xE1\x35\xF8\xCF\x29\x1C\xA8\x94\x08\x5C\x87\xE3\xCC\x15\xC4\x39\xC9\xE4\x3A\x3B\xA0\x91\xD5\x6E\x10\x40\x09\x16"},
-      { GCRY_CIPHER_AES, /* Packet Vector #3 */
-          16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
-          13, "\x00\x00\x00\x05\x04\x03\x02\xA0\xA1\xA2\xA3\xA4\xA5",
-          8, "\x00\x01\x02\x03\x04\x05\x06\x07",
-          25,
-          "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20",
-          33,
-          "\x51\xB1\xE5\xF4\x4A\x19\x7D\x1D\xA4\x6B\x0F\x8E\x2D\x28\x2A\xE8\x71\xE8\x38\xBB\x64\xDA\x85\x96\x57\x4A\xDA\xA7\x6F\xBD\x9F\xB0\xC5"},
-      { GCRY_CIPHER_AES, /* Packet Vector #4 */
-          16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
-          13, "\x00\x00\x00\x06\x05\x04\x03\xA0\xA1\xA2\xA3\xA4\xA5",
-          12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B",
-          19,
-          "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E",
-          27,
-          "\xA2\x8C\x68\x65\x93\x9A\x9A\x79\xFA\xAA\x5C\x4C\x2A\x9D\x4A\x91\xCD\xAC\x8C\x96\xC8\x61\xB9\xC9\xE6\x1E\xF1"},
-      { GCRY_CIPHER_AES, /* Packet Vector #5 */
-          16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
-          13, "\x00\x00\x00\x07\x06\x05\x04\xA0\xA1\xA2\xA3\xA4\xA5",
-          12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B",
-          20,
-          "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F",
-          28,
-          "\xDC\xF1\xFB\x7B\x5D\x9E\x23\xFB\x9D\x4E\x13\x12\x53\x65\x8A\xD8\x6E\xBD\xCA\x3E\x51\xE8\x3F\x07\x7D\x9C\x2D\x93"},
-      { GCRY_CIPHER_AES, /* Packet Vector #6 */
-          16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
-          13, "\x00\x00\x00\x08\x07\x06\x05\xA0\xA1\xA2\xA3\xA4\xA5",
-          12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B",
-          21,
-          "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20",
-          29,
-          "\x6F\xC1\xB0\x11\xF0\x06\x56\x8B\x51\x71\xA4\x2D\x95\x3D\x46\x9B\x25\x70\xA4\xBD\x87\x40\x5A\x04\x43\xAC\x91\xCB\x94"},
-      { GCRY_CIPHER_AES, /* Packet Vector #7 */
-          16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
-          13, "\x00\x00\x00\x09\x08\x07\x06\xA0\xA1\xA2\xA3\xA4\xA5",
-          8, "\x00\x01\x02\x03\x04\x05\x06\x07",
-          23,
-          "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E",
-          33,
-          "\x01\x35\xD1\xB2\xC9\x5F\x41\xD5\xD1\xD4\xFE\xC1\x85\xD1\x66\xB8\x09\x4E\x99\x9D\xFE\xD9\x6C\x04\x8C\x56\x60\x2C\x97\xAC\xBB\x74\x90"},
-      { GCRY_CIPHER_AES, /* Packet Vector #8 */
+      /* draft-irtf-cfrg-chacha20-poly1305-03 */
+      { GCRY_CIPHER_CHACHA20,
+       "\x1c\x92\x40\xa5\xeb\x55\xd3\x8a\xf3\x33\x88\x86\x04\xf6\xb5\xf0"
+       "\x47\x39\x17\xc1\x40\x2b\x80\x09\x9d\xca\x5c\xbc\x20\x70\x75\xc0",
+       "\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08", 12,
+       "\xf3\x33\x88\x86\x00\x00\x00\x00\x00\x00\x4e\x91", 12,
+       "\x49\x6e\x74\x65\x72\x6e\x65\x74\x2d\x44\x72\x61\x66\x74\x73\x20"
+       "\x61\x72\x65\x20\x64\x72\x61\x66\x74\x20\x64\x6f\x63\x75\x6d\x65"
+       "\x6e\x74\x73\x20\x76\x61\x6c\x69\x64\x20\x66\x6f\x72\x20\x61\x20"
+       "\x6d\x61\x78\x69\x6d\x75\x6d\x20\x6f\x66\x20\x73\x69\x78\x20\x6d"
+       "\x6f\x6e\x74\x68\x73\x20\x61\x6e\x64\x20\x6d\x61\x79\x20\x62\x65"
+       "\x20\x75\x70\x64\x61\x74\x65\x64\x2c\x20\x72\x65\x70\x6c\x61\x63"
+       "\x65\x64\x2c\x20\x6f\x72\x20\x6f\x62\x73\x6f\x6c\x65\x74\x65\x64"
+       "\x20\x62\x79\x20\x6f\x74\x68\x65\x72\x20\x64\x6f\x63\x75\x6d\x65"
+       "\x6e\x74\x73\x20\x61\x74\x20\x61\x6e\x79\x20\x74\x69\x6d\x65\x2e"
+       "\x20\x49\x74\x20\x69\x73\x20\x69\x6e\x61\x70\x70\x72\x6f\x70\x72"
+       "\x69\x61\x74\x65\x20\x74\x6f\x20\x75\x73\x65\x20\x49\x6e\x74\x65"
+       "\x72\x6e\x65\x74\x2d\x44\x72\x61\x66\x74\x73\x20\x61\x73\x20\x72"
+       "\x65\x66\x65\x72\x65\x6e\x63\x65\x20\x6d\x61\x74\x65\x72\x69\x61"
+       "\x6c\x20\x6f\x72\x20\x74\x6f\x20\x63\x69\x74\x65\x20\x74\x68\x65"
+       "\x6d\x20\x6f\x74\x68\x65\x72\x20\x74\x68\x61\x6e\x20\x61\x73\x20"
+       "\x2f\xe2\x80\x9c\x77\x6f\x72\x6b\x20\x69\x6e\x20\x70\x72\x6f\x67"
+       "\x72\x65\x73\x73\x2e\x2f\xe2\x80\x9d", 265,
+       "\x64\xa0\x86\x15\x75\x86\x1a\xf4\x60\xf0\x62\xc7\x9b\xe6\x43\xbd"
+       "\x5e\x80\x5c\xfd\x34\x5c\xf3\x89\xf1\x08\x67\x0a\xc7\x6c\x8c\xb2"
+       "\x4c\x6c\xfc\x18\x75\x5d\x43\xee\xa0\x9e\xe9\x4e\x38\x2d\x26\xb0"
+       "\xbd\xb7\xb7\x3c\x32\x1b\x01\x00\xd4\xf0\x3b\x7f\x35\x58\x94\xcf"
+       "\x33\x2f\x83\x0e\x71\x0b\x97\xce\x98\xc8\xa8\x4a\xbd\x0b\x94\x81"
+       "\x14\xad\x17\x6e\x00\x8d\x33\xbd\x60\xf9\x82\xb1\xff\x37\xc8\x55"
+       "\x97\x97\xa0\x6e\xf4\xf0\xef\x61\xc1\x86\x32\x4e\x2b\x35\x06\x38"
+       "\x36\x06\x90\x7b\x6a\x7c\x02\xb0\xf9\xf6\x15\x7b\x53\xc8\x67\xe4"
+       "\xb9\x16\x6c\x76\x7b\x80\x4d\x46\xa5\x9b\x52\x16\xcd\xe7\xa4\xe9"
+       "\x90\x40\xc5\xa4\x04\x33\x22\x5e\xe2\x82\xa1\xb0\xa0\x6c\x52\x3e"
+       "\xaf\x45\x34\xd7\xf8\x3f\xa1\x15\x5b\x00\x47\x71\x8c\xbc\x54\x6a"
+       "\x0d\x07\x2b\x04\xb3\x56\x4e\xea\x1b\x42\x22\x73\xf5\x48\x27\x1a"
+       "\x0b\xb2\x31\x60\x53\xfa\x76\x99\x19\x55\xeb\xd6\x31\x59\x43\x4e"
+       "\xce\xbb\x4e\x46\x6d\xae\x5a\x10\x73\xa6\x72\x76\x27\x09\x7a\x10"
+       "\x49\xe6\x17\xd9\x1d\x36\x10\x94\xfa\x68\xf0\xff\x77\x98\x71\x30"
+       "\x30\x5b\xea\xba\x2e\xda\x04\xdf\x99\x7b\x71\x4d\x6c\x6f\x2c\x29"
+       "\xa6\xad\x5c\xb4\x02\x2b\x02\x70\x9b",
+       "\xee\xad\x9d\x67\x89\x0c\xbb\x22\x39\x23\x36\xfe\xa1\x85\x1f\x38" },
+      /* draft-irtf-cfrg-chacha20-poly1305-03 */
+      { GCRY_CIPHER_CHACHA20,
+       "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+       "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f",
+       "\x07\x00\x00\x00\x40\x41\x42\x43\x44\x45\x46\x47", 12,
+       "\x50\x51\x52\x53\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7", 12,
+       "Ladies and Gentlemen of the class of '99: If I could offer you "
+       "only one tip for the future, sunscreen would be it.", 114,
+       "\xd3\x1a\x8d\x34\x64\x8e\x60\xdb\x7b\x86\xaf\xbc\x53\xef\x7e\xc2"
+       "\xa4\xad\xed\x51\x29\x6e\x08\xfe\xa9\xe2\xb5\xa7\x36\xee\x62\xd6"
+       "\x3d\xbe\xa4\x5e\x8c\xa9\x67\x12\x82\xfa\xfb\x69\xda\x92\x72\x8b"
+       "\x1a\x71\xde\x0a\x9e\x06\x0b\x29\x05\xd6\xa5\xb6\x7e\xcd\x3b\x36"
+       "\x92\xdd\xbd\x7f\x2d\x77\x8b\x8c\x98\x03\xae\xe3\x28\x09\x1b\x58"
+       "\xfa\xb3\x24\xe4\xfa\xd6\x75\x94\x55\x85\x80\x8b\x48\x31\xd7\xbc"
+       "\x3f\xf4\xde\xf0\x8e\x4b\x7a\x9d\xe5\x76\xd2\x65\x86\xce\xc6\x4b"
+       "\x61\x16",
+       "\x1a\xe1\x0b\x59\x4f\x09\xe2\x6a\x7e\x90\x2e\xcb\xd0\x60\x06\x91" },
+    };
+
+  gcry_cipher_hd_t hde, hdd;
+  unsigned char out[1024];
+  unsigned char tag[16];
+  int i, keylen;
+  gcry_error_t err = 0;
+  size_t pos, poslen, taglen2;
+  int byteNum;
+
+  if (verbose)
+    fprintf (stderr, "  Starting POLY1305 checks.\n");
+
+  for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
+    {
+      if (verbose)
+        fprintf (stderr, "    checking POLY1305 mode for %s [%i]\n",
+                 gcry_cipher_algo_name (tv[i].algo),
+                 tv[i].algo);
+      err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_POLY1305, 0);
+      if (!err)
+        err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_POLY1305, 0);
+      if (err)
+        {
+          fail ("poly1305, gcry_cipher_open failed: %s\n", gpg_strerror (err));
+          return;
+        }
+
+      keylen = gcry_cipher_get_algo_keylen(tv[i].algo);
+      if (!keylen)
+        {
+          fail ("poly1305, gcry_cipher_get_algo_keylen failed\n");
+          return;
+        }
+
+      err = gcry_cipher_setkey (hde, tv[i].key, keylen);
+      if (!err)
+        err = gcry_cipher_setkey (hdd, tv[i].key, keylen);
+      if (err)
+        {
+          fail ("poly1305, gcry_cipher_setkey failed: %s\n",
+                gpg_strerror (err));
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
+
+      err = gcry_cipher_setiv (hde, tv[i].iv, tv[i].ivlen);
+      if (!err)
+        err = gcry_cipher_setiv (hdd, tv[i].iv, tv[i].ivlen);
+      if (err)
+        {
+          fail ("poly1305, gcry_cipher_setiv failed: %s\n",
+                gpg_strerror (err));
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
+
+      err = gcry_cipher_info (hde, GCRYCTL_GET_TAGLEN, NULL, &taglen2);
+      if (err)
+        {
+          fail ("cipher-poly1305, gcryctl_get_taglen failed (tv %d): %s\n",
+                i, gpg_strerror (err));
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
+      if (taglen2 != 16)
+        {
+          fail ("cipher-poly1305, gcryctl_get_taglen returned bad length"
+                " (tv %d): got=%zu want=%d\n",
+                i, taglen2, 16);
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
+
+      for (pos = 0; pos < tv[i].aadlen; pos += step)
+        {
+          poslen = (pos + step < tv[i].aadlen) ? step : tv[i].aadlen - pos;
+
+          err = gcry_cipher_authenticate(hde, tv[i].aad + pos, poslen);
+          if (err)
+            {
+              fail ("poly1305, gcry_cipher_authenticate (%d) (%d:%d) failed: "
+                    "%s\n", i, pos, step, gpg_strerror (err));
+              gcry_cipher_close (hde);
+              gcry_cipher_close (hdd);
+              return;
+            }
+          err = gcry_cipher_authenticate(hdd, tv[i].aad + pos, poslen);
+          if (err)
+            {
+              fail ("poly1305, de gcry_cipher_authenticate (%d) (%d:%d) failed: "
+                   "%s\n", i, pos, step, gpg_strerror (err));
+              gcry_cipher_close (hde);
+              gcry_cipher_close (hdd);
+              return;
+            }
+        }
+
+      for (pos = 0; pos < tv[i].inlen; pos += step)
+        {
+          poslen = (pos + step < tv[i].inlen) ? step : tv[i].inlen - pos;
+
+          err = gcry_cipher_encrypt (hde, out + pos, poslen,
+                                     tv[i].plaintext + pos, poslen);
+          if (err)
+            {
+              fail ("poly1305, gcry_cipher_encrypt (%d) (%d:%d) failed: %s\n",
+                    i, pos, step, gpg_strerror (err));
+              gcry_cipher_close (hde);
+              gcry_cipher_close (hdd);
+              return;
+            }
+        }
+
+      if (memcmp (tv[i].out, out, tv[i].inlen))
+        fail ("poly1305, encrypt mismatch entry %d (step %d)\n", i, step);
+
+      for (pos = 0; pos < tv[i].inlen; pos += step)
+        {
+          poslen = (pos + step < tv[i].inlen) ? step : tv[i].inlen - pos;
+
+          err = gcry_cipher_decrypt (hdd, out + pos, poslen, NULL, 0);
+          if (err)
+            {
+              fail ("poly1305, gcry_cipher_decrypt (%d) (%d:%d) failed: %s\n",
+                    i, pos, step, gpg_strerror (err));
+              gcry_cipher_close (hde);
+              gcry_cipher_close (hdd);
+              return;
+            }
+        }
+
+      if (memcmp (tv[i].plaintext, out, tv[i].inlen))
+        fail ("poly1305, decrypt mismatch entry %d (step %d)\n", i, step);
+
+      err = gcry_cipher_gettag (hde, out, 16);
+      if (err)
+        {
+          fail ("poly1305, gcry_cipher_gettag(%d) failed: %s\n",
+                i, gpg_strerror (err));
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
+
+      if (memcmp (tv[i].tag, out, 16))
+        fail ("poly1305, encrypt tag mismatch entry %d\n", i);
+
+
+      err = gcry_cipher_checktag (hdd, out, 16);
+      if (err)
+        {
+          fail ("poly1305, gcry_cipher_checktag(%d) failed: %s\n",
+                i, gpg_strerror (err));
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
+
+      err = gcry_cipher_reset(hde);
+      if (!err)
+        err = gcry_cipher_reset(hdd);
+      if (err)
+        {
+          fail ("poly1305, gcry_cipher_reset (%d) failed: %s\n",
+                i, gpg_strerror (err));
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
+
+      /* gcry_cipher_reset clears the IV */
+      err = gcry_cipher_setiv (hde, tv[i].iv, tv[i].ivlen);
+      if (!err)
+        err = gcry_cipher_setiv (hdd, tv[i].iv, tv[i].ivlen);
+      if (err)
+        {
+          fail ("poly1305, gcry_cipher_setiv failed: %s\n",
+                gpg_strerror (err));
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
+
+      /* this time we authenticate, encrypt and decrypt one byte at a time */
+      for (byteNum = 0; byteNum < tv[i].aadlen; ++byteNum)
+        {
+          err = gcry_cipher_authenticate(hde, tv[i].aad + byteNum, 1);
+          if (err)
+            {
+              fail ("poly1305, gcry_cipher_authenticate (%d) (byte-buf) failed: "
+                    "%s\n", i, gpg_strerror (err));
+              gcry_cipher_close (hde);
+              gcry_cipher_close (hdd);
+              return;
+            }
+          err = gcry_cipher_authenticate(hdd, tv[i].aad + byteNum, 1);
+          if (err)
+            {
+              fail ("poly1305, de gcry_cipher_authenticate (%d) (byte-buf) "
+                   "failed: %s\n", i, gpg_strerror (err));
+              gcry_cipher_close (hde);
+              gcry_cipher_close (hdd);
+              return;
+            }
+        }
+
+      for (byteNum = 0; byteNum < tv[i].inlen; ++byteNum)
+        {
+          err = gcry_cipher_encrypt (hde, out+byteNum, 1,
+                                     (tv[i].plaintext) + byteNum,
+                                     1);
+          if (err)
+            {
+              fail ("poly1305, gcry_cipher_encrypt (%d) (byte-buf) failed: %s\n",
+                    i,  gpg_strerror (err));
+              gcry_cipher_close (hde);
+              gcry_cipher_close (hdd);
+              return;
+            }
+        }
+
+      if (memcmp (tv[i].out, out, tv[i].inlen))
+        fail ("poly1305, encrypt mismatch entry %d, (byte-buf)\n", i);
+
+      err = gcry_cipher_gettag (hde, tag, 16);
+      if (err)
+        {
+          fail ("poly1305, gcry_cipher_gettag(%d) (byte-buf) failed: %s\n",
+                i, gpg_strerror (err));
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
+
+      if (memcmp (tv[i].tag, tag, 16))
+        fail ("poly1305, encrypt tag mismatch entry %d, (byte-buf)\n", i);
+
+      for (byteNum = 0; byteNum < tv[i].inlen; ++byteNum)
+        {
+          err = gcry_cipher_decrypt (hdd, out+byteNum, 1, NULL, 0);
+          if (err)
+            {
+              fail ("poly1305, gcry_cipher_decrypt (%d) (byte-buf) failed: %s\n",
+                    i, gpg_strerror (err));
+              gcry_cipher_close (hde);
+              gcry_cipher_close (hdd);
+              return;
+            }
+        }
+
+      if (memcmp (tv[i].plaintext, out, tv[i].inlen))
+        fail ("poly1305, decrypt mismatch entry %d\n", i);
+
+      err = gcry_cipher_checktag (hdd, tag, 16);
+      if (err)
+        {
+          fail ("poly1305, gcry_cipher_checktag(%d) (byte-buf) failed: %s\n",
+                i, gpg_strerror (err));
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
+
+      gcry_cipher_close (hde);
+      gcry_cipher_close (hdd);
+    }
+  if (verbose)
+    fprintf (stderr, "  Completed POLY1305 checks.\n");
+}
+
+
+static void
+check_poly1305_cipher (void)
+{
+  /* Large buffers, no splitting. */
+  _check_poly1305_cipher(0xffffffff);
+  /* Split input to one byte buffers. */
+  _check_poly1305_cipher(1);
+  /* Split input to 7 byte buffers. */
+  _check_poly1305_cipher(7);
+  /* Split input to 16 byte buffers. */
+  _check_poly1305_cipher(16);
+}
+
+
+static void
+check_ccm_cipher (void)
+{
+  static const struct tv
+  {
+    int algo;
+    int keylen;
+    const char *key;
+    int noncelen;
+    const char *nonce;
+    int aadlen;
+    const char *aad;
+    int plainlen;
+    const char *plaintext;
+    int cipherlen;
+    const char *ciphertext;
+  } tv[] =
+    {
+      /* RFC 3610 */
+      { GCRY_CIPHER_AES, /* Packet Vector #1 */
+          16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+          13, "\x00\x00\x00\x03\x02\x01\x00\xA0\xA1\xA2\xA3\xA4\xA5",
+          8, "\x00\x01\x02\x03\x04\x05\x06\x07",
+          23,
+          "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E",
+          31,
+          "\x58\x8C\x97\x9A\x61\xC6\x63\xD2\xF0\x66\xD0\xC2\xC0\xF9\x89\x80\x6D\x5F\x6B\x61\xDA\xC3\x84\x17\xE8\xD1\x2C\xFD\xF9\x26\xE0"},
+      { GCRY_CIPHER_AES, /* Packet Vector #2 */
+          16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+          13, "\x00\x00\x00\x04\x03\x02\x01\xA0\xA1\xA2\xA3\xA4\xA5",
+          8, "\x00\x01\x02\x03\x04\x05\x06\x07",
+          24,
+          "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F",
+          32,
+          "\x72\xC9\x1A\x36\xE1\x35\xF8\xCF\x29\x1C\xA8\x94\x08\x5C\x87\xE3\xCC\x15\xC4\x39\xC9\xE4\x3A\x3B\xA0\x91\xD5\x6E\x10\x40\x09\x16"},
+      { GCRY_CIPHER_AES, /* Packet Vector #3 */
+          16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+          13, "\x00\x00\x00\x05\x04\x03\x02\xA0\xA1\xA2\xA3\xA4\xA5",
+          8, "\x00\x01\x02\x03\x04\x05\x06\x07",
+          25,
+          "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20",
+          33,
+          "\x51\xB1\xE5\xF4\x4A\x19\x7D\x1D\xA4\x6B\x0F\x8E\x2D\x28\x2A\xE8\x71\xE8\x38\xBB\x64\xDA\x85\x96\x57\x4A\xDA\xA7\x6F\xBD\x9F\xB0\xC5"},
+      { GCRY_CIPHER_AES, /* Packet Vector #4 */
+          16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+          13, "\x00\x00\x00\x06\x05\x04\x03\xA0\xA1\xA2\xA3\xA4\xA5",
+          12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B",
+          19,
+          "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E",
+          27,
+          "\xA2\x8C\x68\x65\x93\x9A\x9A\x79\xFA\xAA\x5C\x4C\x2A\x9D\x4A\x91\xCD\xAC\x8C\x96\xC8\x61\xB9\xC9\xE6\x1E\xF1"},
+      { GCRY_CIPHER_AES, /* Packet Vector #5 */
+          16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+          13, "\x00\x00\x00\x07\x06\x05\x04\xA0\xA1\xA2\xA3\xA4\xA5",
+          12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B",
+          20,
+          "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F",
+          28,
+          "\xDC\xF1\xFB\x7B\x5D\x9E\x23\xFB\x9D\x4E\x13\x12\x53\x65\x8A\xD8\x6E\xBD\xCA\x3E\x51\xE8\x3F\x07\x7D\x9C\x2D\x93"},
+      { GCRY_CIPHER_AES, /* Packet Vector #6 */
+          16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+          13, "\x00\x00\x00\x08\x07\x06\x05\xA0\xA1\xA2\xA3\xA4\xA5",
+          12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B",
+          21,
+          "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20",
+          29,
+          "\x6F\xC1\xB0\x11\xF0\x06\x56\x8B\x51\x71\xA4\x2D\x95\x3D\x46\x9B\x25\x70\xA4\xBD\x87\x40\x5A\x04\x43\xAC\x91\xCB\x94"},
+      { GCRY_CIPHER_AES, /* Packet Vector #7 */
+          16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+          13, "\x00\x00\x00\x09\x08\x07\x06\xA0\xA1\xA2\xA3\xA4\xA5",
+          8, "\x00\x01\x02\x03\x04\x05\x06\x07",
+          23,
+          "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E",
+          33,
+          "\x01\x35\xD1\xB2\xC9\x5F\x41\xD5\xD1\xD4\xFE\xC1\x85\xD1\x66\xB8\x09\x4E\x99\x9D\xFE\xD9\x6C\x04\x8C\x56\x60\x2C\x97\xAC\xBB\x74\x90"},
+      { GCRY_CIPHER_AES, /* Packet Vector #8 */
           16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
           13, "\x00\x00\x00\x0A\x09\x08\x07\xA0\xA1\xA2\xA3\xA4\xA5",
           8, "\x00\x01\x02\x03\x04\x05\x06\x07",
@@ -1951,370 +2611,1267 @@ check_ccm_cipher (void)
   static const int cut[] = { 0, 1, 8, 10, 16, 19, -1 };
   gcry_cipher_hd_t hde, hdd;
   unsigned char out[MAX_DATA_LEN];
-  u64 ctl_params[3];
-  int split, aadsplit;
-  size_t j, i, keylen, blklen, authlen;
-  gcry_error_t err = 0;
+  u64 ctl_params[3];
+  int split, aadsplit;
+  size_t j, i, keylen, blklen, authlen, taglen2;
+  gcry_error_t err = 0;
+
+  if (verbose)
+    fprintf (stderr, "  Starting CCM checks.\n");
+
+  for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
+    {
+      if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode)
+        {
+          if (verbose)
+            fprintf (stderr, "  algorithm %d not available in fips mode\n",
+                    tv[i].algo);
+          continue;
+        }
+
+      if (verbose)
+        fprintf (stderr, "    checking CCM mode for %s [%i]\n",
+                 gcry_cipher_algo_name (tv[i].algo),
+                 tv[i].algo);
+
+      for (j = 0; j < sizeof (cut) / sizeof (cut[0]); j++)
+        {
+          split = cut[j] < 0 ? tv[i].plainlen : cut[j];
+          if (tv[i].plainlen < split)
+            continue;
+
+          err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_CCM, 0);
+          if (!err)
+            err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_CCM, 0);
+          if (err)
+            {
+              fail ("cipher-ccm, gcry_cipher_open failed: %s\n",
+                    gpg_strerror (err));
+              return;
+            }
+
+          keylen = gcry_cipher_get_algo_keylen(tv[i].algo);
+          if (!keylen)
+            {
+              fail ("cipher-ccm, gcry_cipher_get_algo_keylen failed\n");
+              return;
+            }
+
+          err = gcry_cipher_setkey (hde, tv[i].key, keylen);
+          if (!err)
+            err = gcry_cipher_setkey (hdd, tv[i].key, keylen);
+          if (err)
+            {
+              fail ("cipher-ccm, gcry_cipher_setkey failed: %s\n",
+                    gpg_strerror (err));
+              gcry_cipher_close (hde);
+              gcry_cipher_close (hdd);
+              return;
+            }
+
+          blklen = gcry_cipher_get_algo_blklen(tv[i].algo);
+          if (!blklen)
+            {
+              fail ("cipher-ccm, gcry_cipher_get_algo_blklen failed\n");
+              return;
+            }
+
+          err = gcry_cipher_setiv (hde, tv[i].nonce, tv[i].noncelen);
+          if (!err)
+            err = gcry_cipher_setiv (hdd, tv[i].nonce, tv[i].noncelen);
+          if (err)
+            {
+              fail ("cipher-ccm, gcry_cipher_setiv failed: %s\n",
+                    gpg_strerror (err));
+              gcry_cipher_close (hde);
+              gcry_cipher_close (hdd);
+              return;
+            }
+
+          authlen = tv[i].cipherlen - tv[i].plainlen;
+          ctl_params[0] = tv[i].plainlen; /* encryptedlen */
+          ctl_params[1] = tv[i].aadlen; /* aadlen */
+          ctl_params[2] = authlen; /* authtaglen */
+          err = gcry_cipher_ctl (hde, GCRYCTL_SET_CCM_LENGTHS, ctl_params,
+                                 sizeof(ctl_params));
+          if (!err)
+            err = gcry_cipher_ctl (hdd, GCRYCTL_SET_CCM_LENGTHS, ctl_params,
+                                   sizeof(ctl_params));
+          if (err)
+            {
+              fail ("cipher-ccm, gcry_cipher_ctl GCRYCTL_SET_CCM_LENGTHS "
+                    "failed: %s\n", gpg_strerror (err));
+              gcry_cipher_close (hde);
+              gcry_cipher_close (hdd);
+              return;
+            }
+
+          err = gcry_cipher_info (hde, GCRYCTL_GET_TAGLEN, NULL, &taglen2);
+          if (err)
+            {
+              fail ("cipher-ccm, gcryctl_get_taglen failed (tv %d): %s\n",
+                    i, gpg_strerror (err));
+              gcry_cipher_close (hde);
+              gcry_cipher_close (hdd);
+              return;
+            }
+          if (taglen2 != authlen)
+            {
+              fail ("cipher-ccm, gcryctl_get_taglen returned bad length"
+                    " (tv %d): got=%zu want=%zu\n",
+                    i, taglen2, authlen);
+              gcry_cipher_close (hde);
+              gcry_cipher_close (hdd);
+              return;
+            }
+
+          aadsplit = split > tv[i].aadlen ? 0 : split;
+
+          err = gcry_cipher_authenticate (hde, tv[i].aad,
+                                          tv[i].aadlen - aadsplit);
+          if (!err)
+            err = gcry_cipher_authenticate (hde,
+                                            &tv[i].aad[tv[i].aadlen - aadsplit],
+                                            aadsplit);
+          if (!err)
+            err = gcry_cipher_authenticate (hdd, tv[i].aad,
+                                            tv[i].aadlen - aadsplit);
+          if (!err)
+            err = gcry_cipher_authenticate (hdd,
+                                            &tv[i].aad[tv[i].aadlen - aadsplit],
+                                            aadsplit);
+          if (err)
+            {
+              fail ("cipher-ccm, gcry_cipher_authenticate failed: %s\n",
+                   gpg_strerror (err));
+              gcry_cipher_close (hde);
+              gcry_cipher_close (hdd);
+              return;
+            }
+
+          err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, tv[i].plaintext,
+                                     tv[i].plainlen - split);
+          if (!err)
+            err = gcry_cipher_encrypt (hde, &out[tv[i].plainlen - split],
+                                       MAX_DATA_LEN - (tv[i].plainlen - split),
+                                       &tv[i].plaintext[tv[i].plainlen - split],
+                                       split);
+          if (err)
+            {
+              fail ("cipher-ccm, gcry_cipher_encrypt (%d:%d) failed: %s\n",
+                    i, j, gpg_strerror (err));
+              gcry_cipher_close (hde);
+              gcry_cipher_close (hdd);
+              return;
+            }
+
+          err = gcry_cipher_gettag (hde, &out[tv[i].plainlen], authlen);
+          if (err)
+            {
+              fail ("cipher-ccm, gcry_cipher_gettag (%d:%d) failed: %s\n",
+                    i, j, gpg_strerror (err));
+              gcry_cipher_close (hde);
+              gcry_cipher_close (hdd);
+              return;
+            }
+
+          if (memcmp (tv[i].ciphertext, out, tv[i].cipherlen))
+            fail ("cipher-ccm, encrypt mismatch entry %d:%d\n", i, j);
+
+          err = gcry_cipher_decrypt (hdd, out, tv[i].plainlen - split, NULL, 0);
+          if (!err)
+            err = gcry_cipher_decrypt (hdd, &out[tv[i].plainlen - split], split,
+                                       NULL, 0);
+          if (err)
+            {
+              fail ("cipher-ccm, gcry_cipher_decrypt (%d:%d) failed: %s\n",
+                    i, j, gpg_strerror (err));
+              gcry_cipher_close (hde);
+              gcry_cipher_close (hdd);
+              return;
+            }
+
+          if (memcmp (tv[i].plaintext, out, tv[i].plainlen))
+            fail ("cipher-ccm, decrypt mismatch entry %d:%d\n", i, j);
+
+          err = gcry_cipher_checktag (hdd, &out[tv[i].plainlen], authlen);
+          if (err)
+            {
+              fail ("cipher-ccm, gcry_cipher_checktag (%d:%d) failed: %s\n",
+                    i, j, gpg_strerror (err));
+              gcry_cipher_close (hde);
+              gcry_cipher_close (hdd);
+              return;
+            }
+
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+        }
+    }
+
+  /* Large buffer tests.  */
+
+  /* Test encoding of aadlen > 0xfeff.  */
+  {
+    static const char key[]={0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
+                             0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f};
+    static const char iv[]={0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19};
+    static const char tag[]={0x9C,0x76,0xE7,0x33,0xD5,0x15,0xB3,0x6C,
+                             0xBA,0x76,0x95,0xF7,0xFB,0x91};
+    char buf[1024];
+    size_t enclen = 0x20000;
+    size_t aadlen = 0x20000;
+    size_t taglen = sizeof(tag);
+
+    err = gcry_cipher_open (&hde, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CCM, 0);
+    if (err)
+      {
+        fail ("cipher-ccm-large, gcry_cipher_open failed: %s\n",
+              gpg_strerror (err));
+        return;
+      }
+
+    err = gcry_cipher_setkey (hde, key, sizeof (key));
+    if (err)
+      {
+         fail ("cipher-ccm-large, gcry_cipher_setkey failed: %s\n",
+               gpg_strerror (err));
+         gcry_cipher_close (hde);
+         return;
+      }
+
+    err = gcry_cipher_setiv (hde, iv, sizeof (iv));
+    if (err)
+      {
+        fail ("cipher-ccm-large, gcry_cipher_setiv failed: %s\n",
+              gpg_strerror (err));
+        gcry_cipher_close (hde);
+        return;
+      }
+
+    ctl_params[0] = enclen; /* encryptedlen */
+    ctl_params[1] = aadlen; /* aadlen */
+    ctl_params[2] = taglen; /* authtaglen */
+    err = gcry_cipher_ctl (hde, GCRYCTL_SET_CCM_LENGTHS, ctl_params,
+                           sizeof(ctl_params));
+    if (err)
+      {
+        fail ("cipher-ccm-large, gcry_cipher_ctl GCRYCTL_SET_CCM_LENGTHS "
+              "failed: %s\n", gpg_strerror (err));
+        gcry_cipher_close (hde);
+        return;
+      }
+
+    memset (buf, 0xaa, sizeof(buf));
+
+    for (i = 0; i < aadlen; i += sizeof(buf))
+      {
+        err = gcry_cipher_authenticate (hde, buf, sizeof (buf));
+        if (err)
+          {
+            fail ("cipher-ccm-large, gcry_cipher_authenticate failed: %s\n",
+                 gpg_strerror (err));
+            gcry_cipher_close (hde);
+            return;
+          }
+      }
+
+    for (i = 0; i < enclen; i += sizeof(buf))
+      {
+        memset (buf, 0xee, sizeof(buf));
+        err = gcry_cipher_encrypt (hde, buf, sizeof (buf), NULL, 0);
+        if (err)
+          {
+            fail ("cipher-ccm-large, gcry_cipher_encrypt failed: %s\n",
+                 gpg_strerror (err));
+            gcry_cipher_close (hde);
+            return;
+          }
+      }
+
+    err = gcry_cipher_gettag (hde, buf, taglen);
+    if (err)
+      {
+        fail ("cipher-ccm-large, gcry_cipher_gettag failed: %s\n",
+              gpg_strerror (err));
+        gcry_cipher_close (hde);
+        return;
+      }
+
+    if (memcmp (buf, tag, taglen) != 0)
+      fail ("cipher-ccm-large, encrypt mismatch entry\n");
+
+    gcry_cipher_close (hde);
+  }
+
+#if 0
+  /* Test encoding of aadlen > 0xffffffff.  */
+  {
+    static const char key[]={0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
+                             0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f};
+    static const char iv[]={0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19};
+    static const char tag[]={0x01,0xB2,0xC3,0x4A,0xA6,0x6A,0x07,0x6D,
+                             0xBC,0xBD,0xEA,0x17,0xD3,0x73,0xD7,0xD4};
+    char buf[1024];
+    size_t enclen = (size_t)0xffffffff + 1 + 1024;
+    size_t aadlen = (size_t)0xffffffff + 1 + 1024;
+    size_t taglen = sizeof(tag);
+
+    err = gcry_cipher_open (&hde, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CCM, 0);
+    if (err)
+      {
+        fail ("cipher-ccm-huge, gcry_cipher_open failed: %s\n",
+              gpg_strerror (err));
+        return;
+      }
+
+    err = gcry_cipher_setkey (hde, key, sizeof (key));
+    if (err)
+      {
+         fail ("cipher-ccm-huge, gcry_cipher_setkey failed: %s\n",
+               gpg_strerror (err));
+         gcry_cipher_close (hde);
+         return;
+      }
+
+    err = gcry_cipher_setiv (hde, iv, sizeof (iv));
+    if (err)
+      {
+        fail ("cipher-ccm-huge, gcry_cipher_setiv failed: %s\n",
+              gpg_strerror (err));
+        gcry_cipher_close (hde);
+        return;
+      }
+
+    ctl_params[0] = enclen; /* encryptedlen */
+    ctl_params[1] = aadlen; /* aadlen */
+    ctl_params[2] = taglen; /* authtaglen */
+    err = gcry_cipher_ctl (hde, GCRYCTL_SET_CCM_LENGTHS, ctl_params,
+                           sizeof(ctl_params));
+    if (err)
+      {
+        fail ("cipher-ccm-huge, gcry_cipher_ctl GCRYCTL_SET_CCM_LENGTHS failed:"
+              "%s\n", gpg_strerror (err));
+        gcry_cipher_close (hde);
+        return;
+      }
+
+    memset (buf, 0xaa, sizeof(buf));
+
+    for (i = 0; i < aadlen; i += sizeof(buf))
+      {
+        err = gcry_cipher_authenticate (hde, buf, sizeof (buf));
+        if (err)
+          {
+            fail ("cipher-ccm-huge, gcry_cipher_authenticate failed: %s\n",
+                 gpg_strerror (err));
+            gcry_cipher_close (hde);
+            return;
+          }
+      }
+
+    for (i = 0; i < enclen; i += sizeof(buf))
+      {
+        memset (buf, 0xee, sizeof(buf));
+        err = gcry_cipher_encrypt (hde, buf, sizeof (buf), NULL, 0);
+        if (err)
+          {
+            fail ("cipher-ccm-huge, gcry_cipher_encrypt failed: %s\n",
+                 gpg_strerror (err));
+            gcry_cipher_close (hde);
+            return;
+          }
+      }
+
+    err = gcry_cipher_gettag (hde, buf, taglen);
+    if (err)
+      {
+        fail ("cipher-ccm-huge, gcry_cipher_gettag failed: %s\n",
+              gpg_strerror (err));
+        gcry_cipher_close (hde);
+        return;
+      }
+
+    if (memcmp (buf, tag, taglen) != 0)
+      fail ("cipher-ccm-huge, encrypt mismatch entry\n");
+
+    gcry_cipher_close (hde);
+  }
+
+  if (verbose)
+    fprintf (stderr, "  Completed CCM checks.\n");
+#endif
+}
+
+
+static void
+do_check_ocb_cipher (int inplace)
+{
+  /* Note that we use hex strings and not binary strings in TV.  That
+     makes it easier to maintain the test vectors.  */
+  static const struct
+  {
+    int algo;
+    int taglen;         /* 16, 12, or 8 bytes  */
+    const char *key;    /* NULL means "000102030405060708090A0B0C0D0E0F" */
+    const char *nonce;
+    const char *aad;
+    const char *plain;
+    const char *ciph;
+  } tv[] = {
+    /* The RFC-7253 test vectos*/
+    { GCRY_CIPHER_AES, 16, NULL,
+      "BBAA99887766554433221100",
+      "",
+      "",
+      "785407BFFFC8AD9EDCC5520AC9111EE6"
+    },
+    { GCRY_CIPHER_AES, 16, NULL,
+      "BBAA99887766554433221101",
+      "0001020304050607",
+      "0001020304050607",
+      "6820B3657B6F615A5725BDA0D3B4EB3A257C9AF1F8F03009"
+    },
+    { GCRY_CIPHER_AES, 16, NULL,
+      "BBAA99887766554433221102",
+      "0001020304050607",
+      "",
+      "81017F8203F081277152FADE694A0A00"
+    },
+    { GCRY_CIPHER_AES, 16, NULL,
+      "BBAA99887766554433221103",
+      "",
+      "0001020304050607",
+      "45DD69F8F5AAE72414054CD1F35D82760B2CD00D2F99BFA9"
+    },
+    { GCRY_CIPHER_AES, 16, NULL,
+      "BBAA99887766554433221104",
+      "000102030405060708090A0B0C0D0E0F",
+      "000102030405060708090A0B0C0D0E0F",
+      "571D535B60B277188BE5147170A9A22C3AD7A4FF3835B8C5"
+      "701C1CCEC8FC3358"
+    },
+    { GCRY_CIPHER_AES, 16, NULL,
+      "BBAA99887766554433221105",
+      "000102030405060708090A0B0C0D0E0F",
+      "",
+      "8CF761B6902EF764462AD86498CA6B97"
+    },
+    { GCRY_CIPHER_AES, 16, NULL,
+      "BBAA99887766554433221106",
+      "",
+      "000102030405060708090A0B0C0D0E0F",
+      "5CE88EC2E0692706A915C00AEB8B2396F40E1C743F52436B"
+      "DF06D8FA1ECA343D"
+    },
+    { GCRY_CIPHER_AES, 16, NULL,
+      "BBAA99887766554433221107",
+      "000102030405060708090A0B0C0D0E0F1011121314151617",
+      "000102030405060708090A0B0C0D0E0F1011121314151617",
+      "1CA2207308C87C010756104D8840CE1952F09673A448A122"
+      "C92C62241051F57356D7F3C90BB0E07F"
+    },
+    { GCRY_CIPHER_AES, 16, NULL,
+      "BBAA99887766554433221108",
+      "000102030405060708090A0B0C0D0E0F1011121314151617",
+      "",
+      "6DC225A071FC1B9F7C69F93B0F1E10DE"
+    },
+    { GCRY_CIPHER_AES, 16, NULL,
+      "BBAA99887766554433221109",
+      "",
+      "000102030405060708090A0B0C0D0E0F1011121314151617",
+      "221BD0DE7FA6FE993ECCD769460A0AF2D6CDED0C395B1C3C"
+      "E725F32494B9F914D85C0B1EB38357FF"
+    },
+    { GCRY_CIPHER_AES, 16, NULL,
+      "BBAA9988776655443322110A",
+      "000102030405060708090A0B0C0D0E0F1011121314151617"
+      "18191A1B1C1D1E1F",
+      "000102030405060708090A0B0C0D0E0F1011121314151617"
+      "18191A1B1C1D1E1F",
+      "BD6F6C496201C69296C11EFD138A467ABD3C707924B964DE"
+      "AFFC40319AF5A48540FBBA186C5553C68AD9F592A79A4240"
+    },
+    { GCRY_CIPHER_AES, 16, NULL,
+      "BBAA9988776655443322110B",
+      "000102030405060708090A0B0C0D0E0F1011121314151617"
+      "18191A1B1C1D1E1F",
+      "",
+      "FE80690BEE8A485D11F32965BC9D2A32"
+    },
+    { GCRY_CIPHER_AES, 16, NULL,
+      "BBAA9988776655443322110C",
+      "",
+      "000102030405060708090A0B0C0D0E0F1011121314151617"
+      "18191A1B1C1D1E1F",
+      "2942BFC773BDA23CABC6ACFD9BFD5835BD300F0973792EF4"
+      "6040C53F1432BCDFB5E1DDE3BC18A5F840B52E653444D5DF"
+    },
+    { GCRY_CIPHER_AES, 16, NULL,
+      "BBAA9988776655443322110D",
+      "000102030405060708090A0B0C0D0E0F1011121314151617"
+      "18191A1B1C1D1E1F2021222324252627",
+      "000102030405060708090A0B0C0D0E0F1011121314151617"
+      "18191A1B1C1D1E1F2021222324252627",
+      "D5CA91748410C1751FF8A2F618255B68A0A12E093FF45460"
+      "6E59F9C1D0DDC54B65E8628E568BAD7AED07BA06A4A69483"
+      "A7035490C5769E60"
+    },
+    { GCRY_CIPHER_AES, 16, NULL,
+      "BBAA9988776655443322110E",
+      "000102030405060708090A0B0C0D0E0F1011121314151617"
+      "18191A1B1C1D1E1F2021222324252627",
+      "",
+      "C5CD9D1850C141E358649994EE701B68"
+    },
+    { GCRY_CIPHER_AES, 16, NULL,
+      "BBAA9988776655443322110F",
+      "",
+      "000102030405060708090A0B0C0D0E0F1011121314151617"
+      "18191A1B1C1D1E1F2021222324252627",
+      "4412923493C57D5DE0D700F753CCE0D1D2D95060122E9F15"
+      "A5DDBFC5787E50B5CC55EE507BCB084E479AD363AC366B95"
+      "A98CA5F3000B1479"
+    },
+    { GCRY_CIPHER_AES, 12, "0F0E0D0C0B0A09080706050403020100",
+      "BBAA9988776655443322110D",
+      "000102030405060708090A0B0C0D0E0F1011121314151617"
+      "18191A1B1C1D1E1F2021222324252627",
+      "000102030405060708090A0B0C0D0E0F1011121314151617"
+      "18191A1B1C1D1E1F2021222324252627",
+      "1792A4E31E0755FB03E31B22116E6C2DDF9EFD6E33D536F1"
+      "A0124B0A55BAE884ED93481529C76B6AD0C515F4D1CDD4FD"
+      "AC4F02AA"
+    }
+  };
+  gpg_error_t err = 0;
+  gcry_cipher_hd_t hde, hdd;
+  unsigned char out[MAX_DATA_LEN];
+  unsigned char tag[16];
+  int tidx;
 
   if (verbose)
-    fprintf (stderr, "  Starting CCM checks.\n");
+    fprintf (stderr, "  Starting OCB checks.\n");
 
-  for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
+  for (tidx = 0; tidx < DIM (tv); tidx++)
     {
-      if (verbose)
-        fprintf (stderr, "    checking CCM mode for %s [%i]\n",
-                 gcry_cipher_algo_name (tv[i].algo),
-                 tv[i].algo);
+      char *key, *nonce, *aad, *ciph, *plain;
+      size_t keylen, noncelen, aadlen, ciphlen, plainlen;
+      int taglen;
+      size_t taglen2;
 
-      for (j = 0; j < sizeof (cut) / sizeof (cut[0]); j++)
+      if (verbose)
+        fprintf (stderr, "    checking OCB mode for %s [%i] (tv %d)\n",
+                 gcry_cipher_algo_name (tv[tidx].algo), tv[tidx].algo, tidx);
+
+      /* Convert to hex strings to binary.  */
+      key   = hex2buffer (tv[tidx].key? tv[tidx].key
+                          /*        */: "000102030405060708090A0B0C0D0E0F",
+                          &keylen);
+      nonce = hex2buffer (tv[tidx].nonce, &noncelen);
+      aad   = hex2buffer (tv[tidx].aad, &aadlen);
+      plain = hex2buffer (tv[tidx].plain, &plainlen);
+      ciph  = hex2buffer (tv[tidx].ciph, &ciphlen);
+
+      /* Check that our test vectors are sane.  */
+      assert (plainlen <= sizeof out);
+      assert (tv[tidx].taglen <= ciphlen);
+      assert (tv[tidx].taglen <= sizeof tag);
+
+      err = gcry_cipher_open (&hde, tv[tidx].algo, GCRY_CIPHER_MODE_OCB, 0);
+      if (!err)
+        err = gcry_cipher_open (&hdd, tv[tidx].algo, GCRY_CIPHER_MODE_OCB, 0);
+      if (err)
         {
-          split = cut[j] < 0 ? tv[i].plainlen : cut[j];
-          if (tv[i].plainlen < split)
-            continue;
-
-          err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_CCM, 0);
-          if (!err)
-            err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_CCM, 0);
-          if (err)
-            {
-              fail ("cipher-ccm, gcry_cipher_open failed: %s\n",
-                    gpg_strerror (err));
-              return;
-            }
-
-          keylen = gcry_cipher_get_algo_keylen(tv[i].algo);
-          if (!keylen)
-            {
-              fail ("cipher-ccm, gcry_cipher_get_algo_keylen failed\n");
-              return;
-            }
+          fail ("cipher-ocb, gcry_cipher_open failed (tv %d): %s\n",
+                tidx, gpg_strerror (err));
+          return;
+        }
 
-          err = gcry_cipher_setkey (hde, tv[i].key, keylen);
-          if (!err)
-            err = gcry_cipher_setkey (hdd, tv[i].key, keylen);
+      /* Set the taglen.  For the first handle we do this only for a
+         non-default taglen.  For the second handle we check that we
+         can also set to the default taglen.  */
+      taglen = tv[tidx].taglen;
+      if (taglen != 16)
+        {
+          err = gcry_cipher_ctl (hde, GCRYCTL_SET_TAGLEN,
+                                 &taglen, sizeof taglen);
           if (err)
             {
-              fail ("cipher-ccm, gcry_cipher_setkey failed: %s\n",
-                    gpg_strerror (err));
+              fail ("cipher-ocb, gcryctl_set_taglen failed (tv %d): %s\n",
+                    tidx, gpg_strerror (err));
               gcry_cipher_close (hde);
               gcry_cipher_close (hdd);
               return;
             }
+        }
+      err = gcry_cipher_ctl (hdd, GCRYCTL_SET_TAGLEN,
+                             &taglen, sizeof taglen);
+      if (err)
+        {
+          fail ("cipher-ocb, gcryctl_set_taglen failed (tv %d): %s\n",
+                tidx, gpg_strerror (err));
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
 
-          blklen = gcry_cipher_get_algo_blklen(tv[i].algo);
-          if (!blklen)
-            {
-              fail ("cipher-ccm, gcry_cipher_get_algo_blklen failed\n");
-              return;
-            }
+      err = gcry_cipher_info (hde, GCRYCTL_GET_TAGLEN, NULL, &taglen2);
+      if (err)
+        {
+          fail ("cipher-ocb, gcryctl_get_taglen failed (tv %d): %s\n",
+                tidx, gpg_strerror (err));
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
+      if (taglen2 != tv[tidx].taglen)
+        {
+          fail ("cipher-ocb, gcryctl_get_taglen returned bad length (tv %d): "
+                "got=%zu want=%d\n",
+                tidx, taglen2, tv[tidx].taglen);
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
 
-          err = gcry_cipher_setiv (hde, tv[i].nonce, tv[i].noncelen);
-          if (!err)
-            err = gcry_cipher_setiv (hdd, tv[i].nonce, tv[i].noncelen);
-          if (err)
+      err = gcry_cipher_setkey (hde, key, keylen);
+      if (!err)
+        err = gcry_cipher_setkey (hdd, key, keylen);
+      if (err)
+        {
+          fail ("cipher-ocb, gcry_cipher_setkey failed (tv %d): %s\n",
+                tidx, gpg_strerror (err));
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
+
+      err = gcry_cipher_setiv (hde, nonce, noncelen);
+      if (!err)
+        err = gcry_cipher_setiv (hdd, nonce, noncelen);
+      if (err)
+        {
+          fail ("cipher-ocb, gcry_cipher_setiv failed (tv %d): %s\n",
+                tidx, gpg_strerror (err));
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
+
+      err = gcry_cipher_authenticate (hde, aad, aadlen);
+      if (err)
+        {
+          fail ("cipher-ocb, gcry_cipher_authenticate failed (tv %d): %s\n",
+                tidx, gpg_strerror (err));
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
+
+      err = gcry_cipher_final (hde);
+      if (!err)
+        {
+          if (inplace)
             {
-              fail ("cipher-ccm, gcry_cipher_setiv failed: %s\n",
-                    gpg_strerror (err));
-              gcry_cipher_close (hde);
-              gcry_cipher_close (hdd);
-              return;
+              memcpy(out, plain, plainlen);
+              err = gcry_cipher_encrypt (hde, out, plainlen, NULL, 0);
             }
-
-          authlen = tv[i].cipherlen - tv[i].plainlen;
-          ctl_params[0] = tv[i].plainlen; /* encryptedlen */
-          ctl_params[1] = tv[i].aadlen; /* aadlen */
-          ctl_params[2] = authlen; /* authtaglen */
-          err = gcry_cipher_ctl (hde, GCRYCTL_SET_CCM_LENGTHS, ctl_params,
-                                 sizeof(ctl_params));
-          if (!err)
-            err = gcry_cipher_ctl (hdd, GCRYCTL_SET_CCM_LENGTHS, ctl_params,
-                                   sizeof(ctl_params));
-          if (err)
+          else
             {
-              fail ("cipher-ccm, gcry_cipher_ctl GCRYCTL_SET_CCM_LENGTHS "
-                    "failed: %s\n", gpg_strerror (err));
-              gcry_cipher_close (hde);
-              gcry_cipher_close (hdd);
-              return;
+              err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN,
+                                         plain, plainlen);
             }
+        }
+      if (err)
+        {
+          fail ("cipher-ocb, gcry_cipher_encrypt failed (tv %d): %s\n",
+                tidx, gpg_strerror (err));
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
 
-          aadsplit = split > tv[i].aadlen ? 0 : split;
+      /* Check that the encrypt output matches the expected cipher
+         text without the tag (i.e. at the length of plaintext).  */
+      if (memcmp (ciph, out, plainlen))
+        {
+          mismatch (ciph, plainlen, out, plainlen);
+          fail ("cipher-ocb, encrypt data mismatch (tv %d)\n", tidx);
+        }
 
-          err = gcry_cipher_authenticate (hde, tv[i].aad,
-                                          tv[i].aadlen - aadsplit);
-          if (!err)
-            err = gcry_cipher_authenticate (hde,
-                                            &tv[i].aad[tv[i].aadlen - aadsplit],
-                                            aadsplit);
-          if (!err)
-            err = gcry_cipher_authenticate (hdd, tv[i].aad,
-                                            tv[i].aadlen - aadsplit);
-          if (!err)
-            err = gcry_cipher_authenticate (hdd,
-                                            &tv[i].aad[tv[i].aadlen - aadsplit],
-                                            aadsplit);
-          if (err)
+      /* Check that the tag matches TAGLEN bytes from the end of the
+         expected ciphertext.  */
+      err = gcry_cipher_gettag (hde, tag, tv[tidx].taglen);
+      if (err)
+        {
+          fail ("cipher_ocb, gcry_cipher_gettag failed (tv %d): %s\n",
+                tidx, gpg_strerror (err));
+        }
+      if (memcmp (ciph + ciphlen - tv[tidx].taglen, tag, tv[tidx].taglen))
+        {
+          mismatch (ciph + ciphlen - tv[tidx].taglen, tv[tidx].taglen,
+                    tag, tv[tidx].taglen);
+          fail ("cipher-ocb, encrypt tag mismatch (tv %d)\n", tidx);
+        }
+
+
+      err = gcry_cipher_authenticate (hdd, aad, aadlen);
+      if (err)
+        {
+          fail ("cipher-ocb, gcry_cipher_authenticate failed (tv %d): %s\n",
+                tidx, gpg_strerror (err));
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
+
+      /* Now for the decryption.  */
+      err = gcry_cipher_final (hdd);
+      if (!err)
+        {
+          if (inplace)
             {
-              fail ("cipher-ccm, gcry_cipher_authenticate failed: %s\n",
-                   gpg_strerror (err));
-              gcry_cipher_close (hde);
-              gcry_cipher_close (hdd);
-              return;
+              err = gcry_cipher_decrypt (hdd, out, plainlen, NULL, 0);
             }
-
-          err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, tv[i].plaintext,
-                                     tv[i].plainlen - split);
-          if (!err)
-            err = gcry_cipher_encrypt (hde, &out[tv[i].plainlen - split],
-                                       MAX_DATA_LEN - (tv[i].plainlen - split),
-                                       &tv[i].plaintext[tv[i].plainlen - split],
-                                       split);
-          if (err)
+          else
             {
-              fail ("cipher-ccm, gcry_cipher_encrypt (%d:%d) failed: %s\n",
-                    i, j, gpg_strerror (err));
-              gcry_cipher_close (hde);
-              gcry_cipher_close (hdd);
-              return;
+              unsigned char tmp[MAX_DATA_LEN];
+
+              memcpy(tmp, out, plainlen);
+              err = gcry_cipher_decrypt (hdd, out, plainlen, tmp, plainlen);
             }
+        }
+      if (err)
+        {
+          fail ("cipher-ocb, gcry_cipher_decrypt (tv %d) failed: %s\n",
+                tidx, gpg_strerror (err));
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
+
+      /* We still have TAG from the encryption.  */
+      err = gcry_cipher_checktag (hdd, tag, tv[tidx].taglen);
+      if (err)
+        {
+          fail ("cipher-ocb, gcry_cipher_checktag failed (tv %d): %s\n",
+                tidx, gpg_strerror (err));
+        }
+
+      /* Check that the decrypt output matches the original plaintext.  */
+      if (memcmp (plain, out, plainlen))
+        {
+          mismatch (plain, plainlen, out, plainlen);
+          fail ("cipher-ocb, decrypt data mismatch (tv %d)\n", tidx);
+        }
+
+      /* Check that gettag also works for decryption.  */
+      err = gcry_cipher_gettag (hdd, tag, tv[tidx].taglen);
+      if (err)
+        {
+          fail ("cipher_ocb, decrypt gettag failed (tv %d): %s\n",
+                tidx, gpg_strerror (err));
+        }
+      if (memcmp (ciph + ciphlen - tv[tidx].taglen, tag, tv[tidx].taglen))
+        {
+          mismatch (ciph + ciphlen - tv[tidx].taglen, tv[tidx].taglen,
+                    tag, tv[tidx].taglen);
+          fail ("cipher-ocb, decrypt tag mismatch (tv %d)\n", tidx);
+        }
+
+      gcry_cipher_close (hde);
+      gcry_cipher_close (hdd);
+
+      xfree (nonce);
+      xfree (aad);
+      xfree (ciph);
+      xfree (plain);
+      xfree (key);
+    }
+
+  if (verbose)
+    fprintf (stderr, "  Completed OCB checks.\n");
+}
+
+
+static void
+check_ocb_cipher_largebuf_split (int algo, int keylen, const char *tagexpect,
+                                unsigned int splitpos)
+{
+  static const unsigned char key[32] =
+        "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+        "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
+  static const unsigned char nonce[12] =
+        "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x00\x01\x02\x03";
+  const size_t buflen = 1024 * 1024 * 2 + 32;
+  unsigned char *inbuf;
+  unsigned char *outbuf;
+  gpg_error_t err = 0;
+  gcry_cipher_hd_t hde, hdd;
+  unsigned char tag[16];
+  int i;
+
+  inbuf = xmalloc(buflen);
+  if (!inbuf)
+    {
+      fail ("out-of-memory\n");
+      return;
+    }
+  outbuf = xmalloc(buflen);
+  if (!outbuf)
+    {
+      fail ("out-of-memory\n");
+      xfree(inbuf);
+      return;
+    }
+
+  for (i = 0; i < buflen; i++)
+    inbuf[i] = 'a';
+
+  err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0);
+  if (!err)
+    err = gcry_cipher_open (&hdd, algo, GCRY_CIPHER_MODE_OCB, 0);
+  if (err)
+    {
+      fail ("cipher-ocb, gcry_cipher_open failed (large, algo %d): %s\n",
+            algo, gpg_strerror (err));
+      goto out_free;
+    }
+
+  err = gcry_cipher_setkey (hde, key, keylen);
+  if (!err)
+    err = gcry_cipher_setkey (hdd, key, keylen);
+  if (err)
+    {
+      fail ("cipher-ocb, gcry_cipher_setkey failed (large, algo %d): %s\n",
+            algo, gpg_strerror (err));
+      gcry_cipher_close (hde);
+      gcry_cipher_close (hdd);
+      goto out_free;
+    }
+
+  err = gcry_cipher_setiv (hde, nonce, 12);
+  if (!err)
+    err = gcry_cipher_setiv (hdd, nonce, 12);
+  if (err)
+    {
+      fail ("cipher-ocb, gcry_cipher_setiv failed (large, algo %d): %s\n",
+            algo, gpg_strerror (err));
+      gcry_cipher_close (hde);
+      gcry_cipher_close (hdd);
+      goto out_free;
+    }
+
+  if (splitpos)
+    {
+      err = gcry_cipher_authenticate (hde, inbuf, splitpos);
+    }
+  if (!err)
+    {
+      err = gcry_cipher_authenticate (hde, inbuf + splitpos, buflen - splitpos);
+    }
+  if (err)
+    {
+      fail ("cipher-ocb, gcry_cipher_authenticate failed (large, algo %d): %s\n",
+            algo, gpg_strerror (err));
+      gcry_cipher_close (hde);
+      gcry_cipher_close (hdd);
+      goto out_free;
+    }
 
-          err = gcry_cipher_gettag (hde, &out[tv[i].plainlen], authlen);
-          if (err)
-            {
-              fail ("cipher-ccm, gcry_cipher_gettag (%d:%d) failed: %s\n",
-                    i, j, gpg_strerror (err));
-              gcry_cipher_close (hde);
-              gcry_cipher_close (hdd);
-              return;
-            }
+  if (splitpos)
+    {
+      err = gcry_cipher_encrypt (hde, outbuf, splitpos, inbuf, splitpos);
+    }
+  if (!err)
+    {
+      err = gcry_cipher_final (hde);
+      if (!err)
+       {
+         err = gcry_cipher_encrypt (hde, outbuf + splitpos, buflen - splitpos,
+                                   inbuf + splitpos, buflen - splitpos);
+       }
+    }
+  if (err)
+    {
+      fail ("cipher-ocb, gcry_cipher_encrypt failed (large, algo %d): %s\n",
+            algo, gpg_strerror (err));
+      gcry_cipher_close (hde);
+      gcry_cipher_close (hdd);
+      goto out_free;
+    }
 
-          if (memcmp (tv[i].ciphertext, out, tv[i].cipherlen))
-            fail ("cipher-ccm, encrypt mismatch entry %d:%d\n", i, j);
+  /* Check that the tag matches. */
+  err = gcry_cipher_gettag (hde, tag, 16);
+  if (err)
+    {
+      fail ("cipher_ocb, gcry_cipher_gettag failed (large, algo %d): %s\n",
+            algo, gpg_strerror (err));
+    }
+  if (memcmp (tagexpect, tag, 16))
+    {
+      mismatch (tagexpect, 16, tag, 16);
+      fail ("cipher-ocb, encrypt tag mismatch (large, algo %d)\n", algo);
+    }
 
-          err = gcry_cipher_decrypt (hdd, out, tv[i].plainlen - split, NULL, 0);
-          if (!err)
-            err = gcry_cipher_decrypt (hdd, &out[tv[i].plainlen - split], split,
-                                       NULL, 0);
-          if (err)
-            {
-              fail ("cipher-ccm, gcry_cipher_decrypt (%d:%d) failed: %s\n",
-                    i, j, gpg_strerror (err));
-              gcry_cipher_close (hde);
-              gcry_cipher_close (hdd);
-              return;
-            }
+  err = gcry_cipher_authenticate (hdd, inbuf, buflen);
+  if (err)
+    {
+      fail ("cipher-ocb, gcry_cipher_authenticate failed (large, algo %d): %s\n",
+            algo, gpg_strerror (err));
+      gcry_cipher_close (hde);
+      gcry_cipher_close (hdd);
+      goto out_free;
+    }
 
-          if (memcmp (tv[i].plaintext, out, tv[i].plainlen))
-            fail ("cipher-ccm, decrypt mismatch entry %d:%d\n", i, j);
+  /* Now for the decryption.  */
+  if (splitpos)
+    {
+      err = gcry_cipher_decrypt (hdd, outbuf, splitpos, NULL, 0);
+    }
+  if (!err)
+    {
+      err = gcry_cipher_final (hdd);
+      if (!err)
+       {
+         err = gcry_cipher_decrypt (hdd, outbuf + splitpos, buflen - splitpos,
+                                    NULL, 0);
+       }
+    }
+  if (err)
+    {
+      fail ("cipher-ocb, gcry_cipher_decrypt (large, algo %d) failed: %s\n",
+            algo, gpg_strerror (err));
+      gcry_cipher_close (hde);
+      gcry_cipher_close (hdd);
+      goto out_free;
+    }
 
-          err = gcry_cipher_checktag (hdd, &out[tv[i].plainlen], authlen);
-          if (err)
-            {
-              fail ("cipher-ccm, gcry_cipher_checktag (%d:%d) failed: %s\n",
-                    i, j, gpg_strerror (err));
-              gcry_cipher_close (hde);
-              gcry_cipher_close (hdd);
-              return;
-            }
+  /* We still have TAG from the encryption.  */
+  err = gcry_cipher_checktag (hdd, tag, 16);
+  if (err)
+    {
+      fail ("cipher-ocb, gcry_cipher_checktag failed (large, algo %d): %s\n",
+            algo, gpg_strerror (err));
+    }
 
-          gcry_cipher_close (hde);
-          gcry_cipher_close (hdd);
-        }
+  /* Check that the decrypt output matches the original plaintext.  */
+  if (memcmp (inbuf, outbuf, buflen))
+    {
+      /*mismatch (inbuf, buflen, outbuf, buflen);*/
+      fail ("cipher-ocb, decrypt data mismatch (large, algo %d)\n", algo);
     }
 
-  /* Large buffer tests.  */
+  /* Check that gettag also works for decryption.  */
+  err = gcry_cipher_gettag (hdd, tag, 16);
+  if (err)
+    {
+      fail ("cipher_ocb, decrypt gettag failed (large, algo %d): %s\n",
+            algo, gpg_strerror (err));
+    }
+  if (memcmp (tagexpect, tag, 16))
+    {
+      mismatch (tagexpect, 16, tag, 16);
+      fail ("cipher-ocb, decrypt tag mismatch (large, algo %d)\n", algo);
+    }
 
-  /* Test encoding of aadlen > 0xfeff.  */
-  {
-    static const char key[]={0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
-                             0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f};
-    static const char iv[]={0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19};
-    static const char tag[]={0x9C,0x76,0xE7,0x33,0xD5,0x15,0xB3,0x6C,
-                             0xBA,0x76,0x95,0xF7,0xFB,0x91};
-    char buf[1024];
-    size_t enclen = 0x20000;
-    size_t aadlen = 0x20000;
-    size_t taglen = sizeof(tag);
+  gcry_cipher_close (hde);
+  gcry_cipher_close (hdd);
 
-    err = gcry_cipher_open (&hde, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CCM, 0);
-    if (err)
-      {
-        fail ("cipher-ccm-large, gcry_cipher_open failed: %s\n",
-              gpg_strerror (err));
-        return;
-      }
+out_free:
+  xfree(outbuf);
+  xfree(inbuf);
+}
 
-    err = gcry_cipher_setkey (hde, key, sizeof (key));
-    if (err)
-      {
-         fail ("cipher-ccm-large, gcry_cipher_setkey failed: %s\n",
-               gpg_strerror (err));
-         gcry_cipher_close (hde);
-         return;
-      }
 
-    err = gcry_cipher_setiv (hde, iv, sizeof (iv));
-    if (err)
-      {
-        fail ("cipher-ccm-large, gcry_cipher_setiv failed: %s\n",
-              gpg_strerror (err));
-        gcry_cipher_close (hde);
-        return;
-      }
+static void
+check_ocb_cipher_largebuf (int algo, int keylen, const char *tagexpect)
+{
+  unsigned int split;
 
-    ctl_params[0] = enclen; /* encryptedlen */
-    ctl_params[1] = aadlen; /* aadlen */
-    ctl_params[2] = taglen; /* authtaglen */
-    err = gcry_cipher_ctl (hde, GCRYCTL_SET_CCM_LENGTHS, ctl_params,
-                           sizeof(ctl_params));
-    if (err)
-      {
-        fail ("cipher-ccm-large, gcry_cipher_ctl GCRYCTL_SET_CCM_LENGTHS "
-              "failed: %s\n", gpg_strerror (err));
-        gcry_cipher_close (hde);
-        return;
-      }
+  for (split = 0; split < 32 * 16; split = split * 2 + 16)
+    {
+      check_ocb_cipher_largebuf_split(algo, keylen, tagexpect, split);
+    }
+}
 
-    memset (buf, 0xaa, sizeof(buf));
 
-    for (i = 0; i < aadlen; i += sizeof(buf))
-      {
-        err = gcry_cipher_authenticate (hde, buf, sizeof (buf));
-        if (err)
-          {
-            fail ("cipher-ccm-large, gcry_cipher_authenticate failed: %s\n",
-                 gpg_strerror (err));
-            gcry_cipher_close (hde);
-            return;
-          }
-      }
+static void
+check_ocb_cipher_splitaad (void)
+{
+  const char t_nonce[] = ("BBAA9988776655443322110D");
+  const char t_plain[] = ("000102030405060708090A0B0C0D0E0F1011121314151617"
+                          "18191A1B1C1D1E1F2021222324252627");
+  const char t_ciph[]  = ("D5CA91748410C1751FF8A2F618255B68A0A12E093FF45460"
+                          "6E59F9C1D0DDC54B65E8628E568BAD7AED07BA06A4A69483"
+                          "A7035490C5769E60");
+  struct {
+    const char *aad0;
+    const char *aad1;
+    const char *aad2;
+    const char *aad3;
+  } tv[] = {
+    {
+      "000102030405060708090A0B0C0D0E0F"
+      "101112131415161718191A1B1C1D1E1F2021222324252627"
+    },
+    {
+      "000102030405060708090A0B0C0D0E0F",
+      "101112131415161718191A1B1C1D1E1F",
+      "2021222324252627"
+    },
+    {
+      "000102030405060708090A0B0C0D0E0F",
+      "1011121314151617",
+      "18191A1B1C1D1E1F",
+      "2021222324252627"
+    },
+    {
+      "000102030405060708090A0B0C0D0E0F",
+      "101112131415161718191A1B1C1D1E1F",
+      "20",
+      "21222324252627"
+    },
+    {
+      "000102030405060708090A0B0C0D0E0F",
+      "101112131415161718191A1B1C1D1E1F",
+      "2021",
+      "222324252627"
+    },
+    {
+      "000102030405060708090A0B0C0D0E0F",
+      "101112131415161718191A1B1C1D1E1F",
+      "202122",
+      "2324252627"
+    },
+    {
+      "000102030405060708090A0B0C0D0E0F",
+      "101112131415161718191A1B1C1D1E1F",
+      "20212223",
+      "24252627"
+    },
+    {
+      "000102030405060708090A0B0C0D0E0F",
+      "101112131415161718191A1B1C1D1E1F",
+      "2021222324",
+      "252627"
+    },
+    {
+      "000102030405060708090A0B0C0D0E0F",
+      "101112131415161718191A1B1C1D1E1F",
+      "202122232425",
+      "2627"
+    },
+    {
+      "000102030405060708090A0B0C0D0E0F",
+      "101112131415161718191A1B1C1D1E1F",
+      "20212223242526"
+      "27"
+    },
+    {
+      "000102030405060708090A0B0C0D0E0F",
+      "1011121314151617",
+      "18191A1B1C1D1E1F2021222324252627"
+    },
+    {
+      "00",
+      "0102030405060708090A0B0C0D0E0F",
+      "1011121314151617",
+      "18191A1B1C1D1E1F2021222324252627"
+    },
+    {
+      "0001",
+      "02030405060708090A0B0C0D0E0F",
+      "1011121314151617",
+      "18191A1B1C1D1E1F2021222324252627"
+    },
+    {
+      "000102030405060708090A0B0C0D",
+      "0E0F",
+      "1011121314151617",
+      "18191A1B1C1D1E1F2021222324252627"
+    },
+    {
+      "000102030405060708090A0B0C0D0E",
+      "0F",
+      "1011121314151617",
+      "18191A1B1C1D1E1F2021222324252627"
+    },
+    {
+      "000102030405060708090A0B0C0D0E",
+      "0F101112131415161718191A1B1C1D1E1F20212223242526",
+      "27"
+    }
+  };
 
-    for (i = 0; i < enclen; i += sizeof(buf))
-      {
-        memset (buf, 0xee, sizeof(buf));
-        err = gcry_cipher_encrypt (hde, buf, sizeof (buf), NULL, 0);
-        if (err)
-          {
-            fail ("cipher-ccm-large, gcry_cipher_encrypt failed: %s\n",
-                 gpg_strerror (err));
-            gcry_cipher_close (hde);
-            return;
-          }
-      }
+  gpg_error_t err = 0;
+  gcry_cipher_hd_t hde;
+  unsigned char out[MAX_DATA_LEN];
+  unsigned char tag[16];
+  int tidx;
+  char *key, *nonce, *ciph, *plain;
+  size_t keylen, noncelen, ciphlen, plainlen;
+  int i;
 
-    err = gcry_cipher_gettag (hde, buf, taglen);
-    if (err)
-      {
-        fail ("cipher-ccm-large, gcry_cipher_gettag failed: %s\n",
-              gpg_strerror (err));
-        gcry_cipher_close (hde);
-        return;
-      }
+  /* Convert to hex strings to binary.  */
+  key   = hex2buffer ("000102030405060708090A0B0C0D0E0F", &keylen);
+  nonce = hex2buffer (t_nonce, &noncelen);
+  plain = hex2buffer (t_plain, &plainlen);
+  ciph  = hex2buffer (t_ciph, &ciphlen);
 
-    if (memcmp (buf, tag, taglen) != 0)
-      fail ("cipher-ccm-large, encrypt mismatch entry\n");
+  /* Check that our test vectors are sane.  */
+  assert (plainlen <= sizeof out);
+  assert (16 <= ciphlen);
+  assert (16 <= sizeof tag);
 
-    gcry_cipher_close (hde);
-  }
+  for (tidx = 0; tidx < DIM (tv); tidx++)
+    {
+      char *aad[4];
+      size_t aadlen[4];
 
-#if 0
-  /* Test encoding of aadlen > 0xffffffff.  */
-  {
-    static const char key[]={0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
-                             0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f};
-    static const char iv[]={0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19};
-    static const char tag[]={0x01,0xB2,0xC3,0x4A,0xA6,0x6A,0x07,0x6D,
-                             0xBC,0xBD,0xEA,0x17,0xD3,0x73,0xD7,0xD4};
-    char buf[1024];
-    size_t enclen = (size_t)0xffffffff + 1 + 1024;
-    size_t aadlen = (size_t)0xffffffff + 1 + 1024;
-    size_t taglen = sizeof(tag);
+      if (verbose)
+        fprintf (stderr, "    checking OCB aad split (tv %d)\n", tidx);
 
-    err = gcry_cipher_open (&hde, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CCM, 0);
-    if (err)
-      {
-        fail ("cipher-ccm-huge, gcry_cipher_open failed: %s\n",
-              gpg_strerror (err));
-        return;
-      }
+      aad[0] = tv[tidx].aad0? hex2buffer (tv[tidx].aad0, aadlen+0) : NULL;
+      aad[1] = tv[tidx].aad1? hex2buffer (tv[tidx].aad1, aadlen+1) : NULL;
+      aad[2] = tv[tidx].aad2? hex2buffer (tv[tidx].aad2, aadlen+2) : NULL;
+      aad[3] = tv[tidx].aad3? hex2buffer (tv[tidx].aad3, aadlen+3) : NULL;
 
-    err = gcry_cipher_setkey (hde, key, sizeof (key));
-    if (err)
-      {
-         fail ("cipher-ccm-huge, gcry_cipher_setkey failed: %s\n",
-               gpg_strerror (err));
-         gcry_cipher_close (hde);
-         return;
-      }
+      err = gcry_cipher_open (&hde, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_OCB, 0);
+      if (err)
+        {
+          fail ("cipher-ocb-splitadd, gcry_cipher_open failed: %s\n",
+                gpg_strerror (err));
+          return;
+        }
+
+      err = gcry_cipher_setkey (hde, key, keylen);
+      if (err)
+        {
+          fail ("cipher-ocb-splitaad, gcry_cipher_setkey failed: %s\n",
+                gpg_strerror (err));
+          gcry_cipher_close (hde);
+          return;
+        }
 
-    err = gcry_cipher_setiv (hde, iv, sizeof (iv));
-    if (err)
-      {
-        fail ("cipher-ccm-huge, gcry_cipher_setiv failed: %s\n",
-              gpg_strerror (err));
-        gcry_cipher_close (hde);
-        return;
-      }
+      err = gcry_cipher_setiv (hde, nonce, noncelen);
+      if (err)
+        {
+          fail ("cipher-ocb-splitaad, gcry_cipher_setiv failed: %s\n",
+                gpg_strerror (err));
+          gcry_cipher_close (hde);
+          return;
+        }
 
-    ctl_params[0] = enclen; /* encryptedlen */
-    ctl_params[1] = aadlen; /* aadlen */
-    ctl_params[2] = taglen; /* authtaglen */
-    err = gcry_cipher_ctl (hde, GCRYCTL_SET_CCM_LENGTHS, ctl_params,
-                           sizeof(ctl_params));
-    if (err)
-      {
-        fail ("cipher-ccm-huge, gcry_cipher_ctl GCRYCTL_SET_CCM_LENGTHS failed:"
-              "%s\n", gpg_strerror (err));
-        gcry_cipher_close (hde);
-        return;
-      }
+      for (i=0; i < DIM (aad); i++)
+        {
+          if (!aad[i])
+            continue;
+          err = gcry_cipher_authenticate (hde, aad[i], aadlen[i]);
+          if (err)
+            {
+              fail ("cipher-ocb-splitaad,"
+                    " gcry_cipher_authenticate failed (tv=%d,i=%d): %s\n",
+                    tidx, i, gpg_strerror (err));
+              gcry_cipher_close (hde);
+              return;
+            }
+        }
 
-    memset (buf, 0xaa, sizeof(buf));
+      err = gcry_cipher_final (hde);
+      if (!err)
+        err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, plain, plainlen);
+      if (err)
+        {
+          fail ("cipher-ocb-splitaad, gcry_cipher_encrypt failed: %s\n",
+                gpg_strerror (err));
+          gcry_cipher_close (hde);
+          return;
+        }
 
-    for (i = 0; i < aadlen; i += sizeof(buf))
-      {
-        err = gcry_cipher_authenticate (hde, buf, sizeof (buf));
-        if (err)
-          {
-            fail ("cipher-ccm-huge, gcry_cipher_authenticate failed: %s\n",
-                 gpg_strerror (err));
-            gcry_cipher_close (hde);
-            return;
-          }
-      }
+      /* Check that the encrypt output matches the expected cipher
+         text without the tag (i.e. at the length of plaintext).  */
+      if (memcmp (ciph, out, plainlen))
+        {
+          mismatch (ciph, plainlen, out, plainlen);
+          fail ("cipher-ocb-splitaad, encrypt data mismatch\n");
+        }
 
-    for (i = 0; i < enclen; i += sizeof(buf))
-      {
-        memset (buf, 0xee, sizeof(buf));
-        err = gcry_cipher_encrypt (hde, buf, sizeof (buf), NULL, 0);
-        if (err)
-          {
-            fail ("cipher-ccm-huge, gcry_cipher_encrypt failed: %s\n",
-                 gpg_strerror (err));
-            gcry_cipher_close (hde);
-            return;
-          }
-      }
+      /* Check that the tag matches TAGLEN bytes from the end of the
+         expected ciphertext.  */
+      err = gcry_cipher_gettag (hde, tag, 16);
+      if (err)
+        {
+          fail ("cipher-ocb-splitaad, gcry_cipher_gettag failed: %s\n",
+                gpg_strerror (err));
+        }
+      if (memcmp (ciph + ciphlen - 16, tag, 16))
+        {
+          mismatch (ciph + ciphlen - 16, 16, tag, 16);
+          fail ("cipher-ocb-splitaad, encrypt tag mismatch\n");
+        }
 
-    err = gcry_cipher_gettag (hde, buf, taglen);
-    if (err)
-      {
-        fail ("cipher-ccm-huge, gcry_cipher_gettag failed: %s\n",
-              gpg_strerror (err));
-        gcry_cipher_close (hde);
-        return;
-      }
 
-    if (memcmp (buf, tag, taglen) != 0)
-      fail ("cipher-ccm-huge, encrypt mismatch entry\n");
+      gcry_cipher_close (hde);
+      xfree (aad[0]);
+      xfree (aad[1]);
+      xfree (aad[2]);
+      xfree (aad[3]);
+    }
 
-    gcry_cipher_close (hde);
-  }
+  xfree (nonce);
+  xfree (ciph);
+  xfree (plain);
+  xfree (key);
+}
 
-  if (verbose)
-    fprintf (stderr, "  Completed CCM checks.\n");
-#endif
-#endif /*HAVE_U64_TYPEDEF*/
+
+static void
+check_ocb_cipher (void)
+{
+  /* Check OCB cipher with separate destination and source buffers for
+   * encryption/decryption. */
+  do_check_ocb_cipher(0);
+
+  /* Check OCB cipher with inplace encrypt/decrypt. */
+  do_check_ocb_cipher(1);
+
+  /* Check large buffer encryption/decryption. */
+  check_ocb_cipher_largebuf(GCRY_CIPHER_AES, 16,
+                           "\xf5\xf3\x12\x7d\x58\x2d\x96\xe8"
+                           "\x33\xfd\x7a\x4f\x42\x60\x5d\x20");
+  check_ocb_cipher_largebuf(GCRY_CIPHER_AES256, 32,
+                           "\xfa\x26\xa5\xbf\xf6\x7d\x3a\x8d"
+                           "\xfe\x96\x67\xc9\xc8\x41\x03\x51");
+  check_ocb_cipher_largebuf(GCRY_CIPHER_CAMELLIA128, 16,
+                           "\x28\x23\x38\x45\x2b\xfd\x42\x45"
+                           "\x43\x64\x7e\x67\x7f\xf4\x8b\xcd");
+  check_ocb_cipher_largebuf(GCRY_CIPHER_CAMELLIA192, 24,
+                           "\xee\xca\xe5\x39\x27\x2d\x33\xe7"
+                           "\x79\x74\xb0\x1d\x37\x12\xd5\x6c");
+  check_ocb_cipher_largebuf(GCRY_CIPHER_CAMELLIA256, 32,
+                           "\x39\x39\xd0\x2d\x05\x68\x74\xee"
+                           "\x18\x6b\xea\x3d\x0b\xd3\x58\xae");
+  check_ocb_cipher_largebuf(GCRY_CIPHER_TWOFISH, 16,
+                           "\x63\xe3\x0e\xb9\x11\x6f\x14\xba"
+                           "\x79\xe4\xa7\x9e\xad\x3c\x02\x0c");
+  check_ocb_cipher_largebuf(GCRY_CIPHER_TWOFISH, 32,
+                           "\xf6\xd4\xfe\x4e\x50\x85\x13\x59"
+                           "\x69\x0e\x4c\x67\x3e\xdd\x47\x90");
+  check_ocb_cipher_largebuf(GCRY_CIPHER_SERPENT128, 16,
+                           "\x3c\xfb\x66\x14\x3c\xc8\x6c\x67"
+                           "\x26\xb8\x23\xeb\xaf\x43\x98\x69");
+  check_ocb_cipher_largebuf(GCRY_CIPHER_SERPENT192, 24,
+                           "\x5e\x62\x27\xc5\x32\xc3\x1d\xe6"
+                           "\x2e\x65\xe7\xd6\xfb\x05\xd7\xb2");
+  check_ocb_cipher_largebuf(GCRY_CIPHER_SERPENT256, 32,
+                           "\xe7\x8b\xe6\xd4\x2f\x7a\x36\x4c"
+                           "\xba\xee\x20\xe2\x68\xf4\xcb\xcc");
+
+  /* Check that the AAD data is correctly buffered.  */
+  check_ocb_cipher_splitaad ();
 }
 
 
@@ -2415,99 +3972,422 @@ check_stream_cipher (void)
           "\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\x00",
-          "\xF5\xFA\xD5\x3F\x79\xF9\xDF\x58\xC4\xAE\xA0\xD0\xED\x9A\x96\x01"
-          "\xF2\x78\x11\x2C\xA7\x18\x0D\x56\x5B\x42\x0A\x48\x01\x96\x70\xEA"
-          "\xF2\x4C\xE4\x93\xA8\x62\x63\xF6\x77\xB4\x6A\xCE\x19\x24\x77\x3D"
-          "\x2B\xB2\x55\x71\xE1\xAA\x85\x93\x75\x8F\xC3\x82\xB1\x28\x0B\x71"
+          "\xF5\xFA\xD5\x3F\x79\xF9\xDF\x58\xC4\xAE\xA0\xD0\xED\x9A\x96\x01"
+          "\xF2\x78\x11\x2C\xA7\x18\x0D\x56\x5B\x42\x0A\x48\x01\x96\x70\xEA"
+          "\xF2\x4C\xE4\x93\xA8\x62\x63\xF6\x77\xB4\x6A\xCE\x19\x24\x77\x3D"
+          "\x2B\xB2\x55\x71\xE1\xAA\x85\x93\x75\x8F\xC3\x82\xB1\x28\x0B\x71"
+        }
+      }
+    },
+    {
+      "Salsa20/12 128 bit, test 1",
+      GCRY_CIPHER_SALSA20R12, 16, 8,
+      "\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+      "\x00\x00\x00\x00\x00\x00\x00\x00",
+      {
+        { 8,
+          "\x00\x00\x00\x00\x00\x00\x00\x00",
+          "\xFC\x20\x7D\xBF\xC7\x6C\x5E\x17"
+        }
+      }
+    },
+    {
+      "Salsa20/12 128 bit, test 2",
+      GCRY_CIPHER_SALSA20R12, 16, 8,
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+      "\x80\x00\x00\x00\x00\x00\x00\x00",
+      {
+        { 8,
+          "\x00\x00\x00\x00\x00\x00\x00\x00",
+          "\x08\x28\x39\x9A\x6F\xEF\x20\xDA"
+        }
+      }
+    },
+    {
+      "Salsa20/12 128 bit, test 3",
+      GCRY_CIPHER_SALSA20R12, 16, 8,
+      "\x00\x53\xA6\xF9\x4C\x9F\xF2\x45\x98\xEB\x3E\x91\xE4\x37\x8A\xDD",
+      "\x0D\x74\xDB\x42\xA9\x10\x77\xDE",
+      {
+        { 8,
+          "\x00\x00\x00\x00\x00\x00\x00\x00",
+          "\xAD\x9E\x60\xE6\xD2\xA2\x64\xB8"
+        }
+      }
+    },
+    {
+      "Salsa20/12 256 bit, test 1",
+      GCRY_CIPHER_SALSA20R12, 32, 8,
+      "\x80\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",
+      {
+        { 8,
+          "\x00\x00\x00\x00\x00\x00\x00\x00",
+          "\xAF\xE4\x11\xED\x1C\x4E\x07\xE4"
+        }
+      }
+    },
+    {
+      "Salsa20/12 256 bit, test 2",
+      GCRY_CIPHER_SALSA20R12, 32, 8,
+      "\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",
+      "\x80\x00\x00\x00\x00\x00\x00\x00",
+      {
+        { 8,
+          "\x00\x00\x00\x00\x00\x00\x00\x00",
+          "\x17\x2C\x51\x92\xCB\x6E\x64\x5B"
+        }
+      }
+    },
+    {
+      "Salsa20/12 256 bit, ecrypt verified, set 6, vector 0",
+      GCRY_CIPHER_SALSA20R12, 32, 8,
+      "\x00\x53\xA6\xF9\x4C\x9F\xF2\x45\x98\xEB\x3E\x91\xE4\x37\x8A\xDD"
+      "\x30\x83\xD6\x29\x7C\xCF\x22\x75\xC8\x1B\x6E\xC1\x14\x67\xBA\x0D",
+      "\x0D\x74\xDB\x42\xA9\x10\x77\xDE",
+      {
+        { 8,
+          "\x00\x00\x00\x00\x00\x00\x00\x00",
+          "\x52\xE2\x0C\xF8\x77\x5A\xE8\x82"
+        },
+        { 64,
+          "\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\x00"
+          "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+          "\x52\xE2\x0C\xF8\x77\x5A\xE8\x82\xF2\x00\xC2\x99\x9F\xE4\xBA\x31"
+          "\xA7\xA1\x8F\x1D\x5C\x97\x16\x19\x1D\x12\x31\x75\xE1\x47\xBD\x4E"
+          "\x8C\xA6\xED\x16\x6C\xE0\xFC\x8E\x65\xA5\xCA\x60\x84\x20\xFC\x65"
+          "\x44\xC9\x70\x0A\x0F\x21\x38\xE8\xC1\xA2\x86\xFB\x8C\x1F\xBF\xA0"
+        }
+      }
+    },
+#endif /*USE_SALSA20*/
+#ifdef USE_CHACHA20
+    /* From draft-strombergson-chacha-test-vectors-01 */
+    {
+      "ChaCha20 128 bit, TC1",
+      GCRY_CIPHER_CHACHA20, 16, 8,
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+      "\x00\x00\x00\x00\x00\x00\x00\x00",
+      {
+        { 8,
+          "\x00\x00\x00\x00\x00\x00\x00\x00",
+          "\x89\x67\x09\x52\x60\x83\x64\xfd"
+        },
+        { 112,
+          "\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\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\x00\x00"
+          "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+          "\x89\x67\x09\x52\x60\x83\x64\xfd\x00\xb2\xf9\x09\x36\xf0\x31\xc8"
+          "\xe7\x56\xe1\x5d\xba\x04\xb8\x49\x3d\x00\x42\x92\x59\xb2\x0f\x46"
+          "\xcc\x04\xf1\x11\x24\x6b\x6c\x2c\xe0\x66\xbe\x3b\xfb\x32\xd9\xaa"
+          "\x0f\xdd\xfb\xc1\x21\x23\xd4\xb9\xe4\x4f\x34\xdc\xa0\x5a\x10\x3f"
+          "\x6c\xd1\x35\xc2\x87\x8c\x83\x2b\x58\x96\xb1\x34\xf6\x14\x2a\x9d"
+          "\x4d\x8d\x0d\x8f\x10\x26\xd2\x0a\x0a\x81\x51\x2c\xbc\xe6\xe9\x75"
+          "\x8a\x71\x43\xd0\x21\x97\x80\x22\xa3\x84\x14\x1a\x80\xce\xa3\x06"
+        },
+        { 128,
+          "\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\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\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",
+          "\x89\x67\x09\x52\x60\x83\x64\xfd\x00\xb2\xf9\x09\x36\xf0\x31\xc8"
+          "\xe7\x56\xe1\x5d\xba\x04\xb8\x49\x3d\x00\x42\x92\x59\xb2\x0f\x46"
+          "\xcc\x04\xf1\x11\x24\x6b\x6c\x2c\xe0\x66\xbe\x3b\xfb\x32\xd9\xaa"
+          "\x0f\xdd\xfb\xc1\x21\x23\xd4\xb9\xe4\x4f\x34\xdc\xa0\x5a\x10\x3f"
+          "\x6c\xd1\x35\xc2\x87\x8c\x83\x2b\x58\x96\xb1\x34\xf6\x14\x2a\x9d"
+          "\x4d\x8d\x0d\x8f\x10\x26\xd2\x0a\x0a\x81\x51\x2c\xbc\xe6\xe9\x75"
+          "\x8a\x71\x43\xd0\x21\x97\x80\x22\xa3\x84\x14\x1a\x80\xce\xa3\x06"
+          "\x2f\x41\xf6\x7a\x75\x2e\x66\xad\x34\x11\x98\x4c\x78\x7e\x30\xad"
+        }
+      }
+    },
+    {
+      "ChaCha20 256 bit, TC1",
+      GCRY_CIPHER_CHACHA20, 32, 8,
+      "\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",
+      {
+        { 8,
+          "\x00\x00\x00\x00\x00\x00\x00\x00",
+          "\x76\xb8\xe0\xad\xa0\xf1\x3d\x90"
+        },
+        { 112,
+          "\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\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\x00\x00"
+          "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+          "\x76\xb8\xe0\xad\xa0\xf1\x3d\x90\x40\x5d\x6a\xe5\x53\x86\xbd\x28"
+          "\xbd\xd2\x19\xb8\xa0\x8d\xed\x1a\xa8\x36\xef\xcc\x8b\x77\x0d\xc7"
+          "\xda\x41\x59\x7c\x51\x57\x48\x8d\x77\x24\xe0\x3f\xb8\xd8\x4a\x37"
+          "\x6a\x43\xb8\xf4\x15\x18\xa1\x1c\xc3\x87\xb6\x69\xb2\xee\x65\x86"
+          "\x9f\x07\xe7\xbe\x55\x51\x38\x7a\x98\xba\x97\x7c\x73\x2d\x08\x0d"
+          "\xcb\x0f\x29\xa0\x48\xe3\x65\x69\x12\xc6\x53\x3e\x32\xee\x7a\xed"
+          "\x29\xb7\x21\x76\x9c\xe6\x4e\x43\xd5\x71\x33\xb0\x74\xd8\x39\xd5"
+        },
+        { 128,
+          "\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\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\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",
+          "\x76\xb8\xe0\xad\xa0\xf1\x3d\x90\x40\x5d\x6a\xe5\x53\x86\xbd\x28"
+          "\xbd\xd2\x19\xb8\xa0\x8d\xed\x1a\xa8\x36\xef\xcc\x8b\x77\x0d\xc7"
+          "\xda\x41\x59\x7c\x51\x57\x48\x8d\x77\x24\xe0\x3f\xb8\xd8\x4a\x37"
+          "\x6a\x43\xb8\xf4\x15\x18\xa1\x1c\xc3\x87\xb6\x69\xb2\xee\x65\x86"
+          "\x9f\x07\xe7\xbe\x55\x51\x38\x7a\x98\xba\x97\x7c\x73\x2d\x08\x0d"
+          "\xcb\x0f\x29\xa0\x48\xe3\x65\x69\x12\xc6\x53\x3e\x32\xee\x7a\xed"
+          "\x29\xb7\x21\x76\x9c\xe6\x4e\x43\xd5\x71\x33\xb0\x74\xd8\x39\xd5"
+          "\x31\xed\x1f\x28\x51\x0a\xfb\x45\xac\xe1\x0a\x1f\x4b\x79\x4d\x6f"
+        }
+      }
+    },
+    {
+      "ChaCha20 256 bit, TC2",
+      GCRY_CIPHER_CHACHA20, 32, 8,
+      "\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",
+      {
+        { 128,
+          "\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\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\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",
+          "\xc5\xd3\x0a\x7c\xe1\xec\x11\x93\x78\xc8\x4f\x48\x7d\x77\x5a\x85"
+          "\x42\xf1\x3e\xce\x23\x8a\x94\x55\xe8\x22\x9e\x88\x8d\xe8\x5b\xbd"
+          "\x29\xeb\x63\xd0\xa1\x7a\x5b\x99\x9b\x52\xda\x22\xbe\x40\x23\xeb"
+          "\x07\x62\x0a\x54\xf6\xfa\x6a\xd8\x73\x7b\x71\xeb\x04\x64\xda\xc0"
+          "\x10\xf6\x56\xe6\xd1\xfd\x55\x05\x3e\x50\xc4\x87\x5c\x99\x30\xa3"
+          "\x3f\x6d\x02\x63\xbd\x14\xdf\xd6\xab\x8c\x70\x52\x1c\x19\x33\x8b"
+          "\x23\x08\xb9\x5c\xf8\xd0\xbb\x7d\x20\x2d\x21\x02\x78\x0e\xa3\x52"
+          "\x8f\x1c\xb4\x85\x60\xf7\x6b\x20\xf3\x82\xb9\x42\x50\x0f\xce\xac"
         }
       }
     },
     {
-      "Salsa20/12 128 bit, test 1",
-      GCRY_CIPHER_SALSA20R12, 16, 8,
-      "\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
-      "\x00\x00\x00\x00\x00\x00\x00\x00",
+      "ChaCha20 256 bit, TC3",
+      GCRY_CIPHER_CHACHA20, 32, 8,
+      "\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",
+      "\x01\x00\x00\x00\x00\x00\x00\x00",
       {
-        { 8,
-          "\x00\x00\x00\x00\x00\x00\x00\x00",
-          "\xFC\x20\x7D\xBF\xC7\x6C\x5E\x17"
+        { 128,
+          "\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\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\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",
+          "\xef\x3f\xdf\xd6\xc6\x15\x78\xfb\xf5\xcf\x35\xbd\x3d\xd3\x3b\x80"
+          "\x09\x63\x16\x34\xd2\x1e\x42\xac\x33\x96\x0b\xd1\x38\xe5\x0d\x32"
+          "\x11\x1e\x4c\xaf\x23\x7e\xe5\x3c\xa8\xad\x64\x26\x19\x4a\x88\x54"
+          "\x5d\xdc\x49\x7a\x0b\x46\x6e\x7d\x6b\xbd\xb0\x04\x1b\x2f\x58\x6b"
+          "\x53\x05\xe5\xe4\x4a\xff\x19\xb2\x35\x93\x61\x44\x67\x5e\xfb\xe4"
+          "\x40\x9e\xb7\xe8\xe5\xf1\x43\x0f\x5f\x58\x36\xae\xb4\x9b\xb5\x32"
+          "\x8b\x01\x7c\x4b\x9d\xc1\x1f\x8a\x03\x86\x3f\xa8\x03\xdc\x71\xd5"
+          "\x72\x6b\x2b\x6b\x31\xaa\x32\x70\x8a\xfe\x5a\xf1\xd6\xb6\x90\x58"
         }
       }
     },
     {
-      "Salsa20/12 128 bit, test 2",
-      GCRY_CIPHER_SALSA20R12, 16, 8,
-      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
-      "\x80\x00\x00\x00\x00\x00\x00\x00",
+      "ChaCha20 256 bit, TC4",
+      GCRY_CIPHER_CHACHA20, 32, 8,
+      "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
+      "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff",
+      "\xff\xff\xff\xff\xff\xff\xff\xff",
       {
-        { 8,
-          "\x00\x00\x00\x00\x00\x00\x00\x00",
-          "\x08\x28\x39\x9A\x6F\xEF\x20\xDA"
+        { 128,
+          "\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\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\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",
+          "\xd9\xbf\x3f\x6b\xce\x6e\xd0\xb5\x42\x54\x55\x77\x67\xfb\x57\x44"
+          "\x3d\xd4\x77\x89\x11\xb6\x06\x05\x5c\x39\xcc\x25\xe6\x74\xb8\x36"
+          "\x3f\xea\xbc\x57\xfd\xe5\x4f\x79\x0c\x52\xc8\xae\x43\x24\x0b\x79"
+          "\xd4\x90\x42\xb7\x77\xbf\xd6\xcb\x80\xe9\x31\x27\x0b\x7f\x50\xeb"
+          "\x5b\xac\x2a\xcd\x86\xa8\x36\xc5\xdc\x98\xc1\x16\xc1\x21\x7e\xc3"
+          "\x1d\x3a\x63\xa9\x45\x13\x19\xf0\x97\xf3\xb4\xd6\xda\xb0\x77\x87"
+          "\x19\x47\x7d\x24\xd2\x4b\x40\x3a\x12\x24\x1d\x7c\xca\x06\x4f\x79"
+          "\x0f\x1d\x51\xcc\xaf\xf6\xb1\x66\x7d\x4b\xbc\xa1\x95\x8c\x43\x06"
         }
       }
     },
     {
-      "Salsa20/12 128 bit, test 3",
-      GCRY_CIPHER_SALSA20R12, 16, 8,
-      "\x00\x53\xA6\xF9\x4C\x9F\xF2\x45\x98\xEB\x3E\x91\xE4\x37\x8A\xDD",
-      "\x0D\x74\xDB\x42\xA9\x10\x77\xDE",
+      "ChaCha20 256 bit, TC5",
+      GCRY_CIPHER_CHACHA20, 32, 8,
+      "\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55"
+      "\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55",
+      "\x55\x55\x55\x55\x55\x55\x55\x55",
       {
-        { 8,
-          "\x00\x00\x00\x00\x00\x00\x00\x00",
-          "\xAD\x9E\x60\xE6\xD2\xA2\x64\xB8"
+        { 128,
+          "\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\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\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",
+          "\xbe\xa9\x41\x1a\xa4\x53\xc5\x43\x4a\x5a\xe8\xc9\x28\x62\xf5\x64"
+          "\x39\x68\x55\xa9\xea\x6e\x22\xd6\xd3\xb5\x0a\xe1\xb3\x66\x33\x11"
+          "\xa4\xa3\x60\x6c\x67\x1d\x60\x5c\xe1\x6c\x3a\xec\xe8\xe6\x1e\xa1"
+          "\x45\xc5\x97\x75\x01\x7b\xee\x2f\xa6\xf8\x8a\xfc\x75\x80\x69\xf7"
+          "\xe0\xb8\xf6\x76\xe6\x44\x21\x6f\x4d\x2a\x34\x22\xd7\xfa\x36\xc6"
+          "\xc4\x93\x1a\xca\x95\x0e\x9d\xa4\x27\x88\xe6\xd0\xb6\xd1\xcd\x83"
+          "\x8e\xf6\x52\xe9\x7b\x14\x5b\x14\x87\x1e\xae\x6c\x68\x04\xc7\x00"
+          "\x4d\xb5\xac\x2f\xce\x4c\x68\xc7\x26\xd0\x04\xb1\x0f\xca\xba\x86"
         }
       }
     },
     {
-      "Salsa20/12 256 bit, test 1",
-      GCRY_CIPHER_SALSA20R12, 32, 8,
-      "\x80\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",
+      "ChaCha20 256 bit, TC6",
+      GCRY_CIPHER_CHACHA20, 32, 8,
+      "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+      "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+      "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
       {
-        { 8,
-          "\x00\x00\x00\x00\x00\x00\x00\x00",
-          "\xAF\xE4\x11\xED\x1C\x4E\x07\xE4"
+        { 128,
+          "\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\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\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",
+          "\x9a\xa2\xa9\xf6\x56\xef\xde\x5a\xa7\x59\x1c\x5f\xed\x4b\x35\xae"
+          "\xa2\x89\x5d\xec\x7c\xb4\x54\x3b\x9e\x9f\x21\xf5\xe7\xbc\xbc\xf3"
+          "\xc4\x3c\x74\x8a\x97\x08\x88\xf8\x24\x83\x93\xa0\x9d\x43\xe0\xb7"
+          "\xe1\x64\xbc\x4d\x0b\x0f\xb2\x40\xa2\xd7\x21\x15\xc4\x80\x89\x06"
+          "\x72\x18\x44\x89\x44\x05\x45\xd0\x21\xd9\x7e\xf6\xb6\x93\xdf\xe5"
+          "\xb2\xc1\x32\xd4\x7e\x6f\x04\x1c\x90\x63\x65\x1f\x96\xb6\x23\xe6"
+          "\x2a\x11\x99\x9a\x23\xb6\xf7\xc4\x61\xb2\x15\x30\x26\xad\x5e\x86"
+          "\x6a\x2e\x59\x7e\xd0\x7b\x84\x01\xde\xc6\x3a\x09\x34\xc6\xb2\xa9"
         }
       }
     },
     {
-      "Salsa20/12 256 bit, test 2",
-      GCRY_CIPHER_SALSA20R12, 32, 8,
-      "\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",
-      "\x80\x00\x00\x00\x00\x00\x00\x00",
+      "ChaCha20 256 bit, TC7",
+      GCRY_CIPHER_CHACHA20, 32, 8,
+      "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff"
+      "\xff\xee\xdd\xcc\xbb\xaa\x99\x88\x77\x66\x55\x44\x33\x22\x11\x00",
+      "\x0f\x1e\x2d\x3c\x4b\x5a\x69\x78",
       {
-        { 8,
-          "\x00\x00\x00\x00\x00\x00\x00\x00",
-          "\x17\x2C\x51\x92\xCB\x6E\x64\x5B"
+        { 128,
+          "\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\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\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",
+          "\x9f\xad\xf4\x09\xc0\x08\x11\xd0\x04\x31\xd6\x7e\xfb\xd8\x8f\xba"
+          "\x59\x21\x8d\x5d\x67\x08\xb1\xd6\x85\x86\x3f\xab\xbb\x0e\x96\x1e"
+          "\xea\x48\x0f\xd6\xfb\x53\x2b\xfd\x49\x4b\x21\x51\x01\x50\x57\x42"
+          "\x3a\xb6\x0a\x63\xfe\x4f\x55\xf7\xa2\x12\xe2\x16\x7c\xca\xb9\x31"
+          "\xfb\xfd\x29\xcf\x7b\xc1\xd2\x79\xed\xdf\x25\xdd\x31\x6b\xb8\x84"
+          "\x3d\x6e\xde\xe0\xbd\x1e\xf1\x21\xd1\x2f\xa1\x7c\xbc\x2c\x57\x4c"
+          "\xcc\xab\x5e\x27\x51\x67\xb0\x8b\xd6\x86\xf8\xa0\x9d\xf8\x7e\xc3"
+          "\xff\xb3\x53\x61\xb9\x4e\xbf\xa1\x3f\xec\x0e\x48\x89\xd1\x8d\xa5"
         }
       }
     },
     {
-      "Salsa20/12 256 bit, ecrypt verified, set 6, vector 0",
-      GCRY_CIPHER_SALSA20R12, 32, 8,
-      "\x00\x53\xA6\xF9\x4C\x9F\xF2\x45\x98\xEB\x3E\x91\xE4\x37\x8A\xDD"
-      "\x30\x83\xD6\x29\x7C\xCF\x22\x75\xC8\x1B\x6E\xC1\x14\x67\xBA\x0D",
-      "\x0D\x74\xDB\x42\xA9\x10\x77\xDE",
+      "ChaCha20 256 bit, TC8",
+      GCRY_CIPHER_CHACHA20, 32, 8,
+      "\xc4\x6e\xc1\xb1\x8c\xe8\xa8\x78\x72\x5a\x37\xe7\x80\xdf\xb7\x35"
+      "\x1f\x68\xed\x2e\x19\x4c\x79\xfb\xc6\xae\xbe\xe1\xa6\x67\x97\x5d",
+      "\x1a\xda\x31\xd5\xcf\x68\x82\x21",
       {
-        { 8,
-          "\x00\x00\x00\x00\x00\x00\x00\x00",
-          "\x52\xE2\x0C\xF8\x77\x5A\xE8\x82"
-        },
-        { 64,
+        { 128,
+          "\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\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\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",
-          "\x52\xE2\x0C\xF8\x77\x5A\xE8\x82\xF2\x00\xC2\x99\x9F\xE4\xBA\x31"
-          "\xA7\xA1\x8F\x1D\x5C\x97\x16\x19\x1D\x12\x31\x75\xE1\x47\xBD\x4E"
-          "\x8C\xA6\xED\x16\x6C\xE0\xFC\x8E\x65\xA5\xCA\x60\x84\x20\xFC\x65"
-          "\x44\xC9\x70\x0A\x0F\x21\x38\xE8\xC1\xA2\x86\xFB\x8C\x1F\xBF\xA0"
+          "\xf6\x3a\x89\xb7\x5c\x22\x71\xf9\x36\x88\x16\x54\x2b\xa5\x2f\x06"
+          "\xed\x49\x24\x17\x92\x30\x2b\x00\xb5\xe8\xf8\x0a\xe9\xa4\x73\xaf"
+          "\xc2\x5b\x21\x8f\x51\x9a\xf0\xfd\xd4\x06\x36\x2e\x8d\x69\xde\x7f"
+          "\x54\xc6\x04\xa6\xe0\x0f\x35\x3f\x11\x0f\x77\x1b\xdc\xa8\xab\x92"
+          "\xe5\xfb\xc3\x4e\x60\xa1\xd9\xa9\xdb\x17\x34\x5b\x0a\x40\x27\x36"
+          "\x85\x3b\xf9\x10\xb0\x60\xbd\xf1\xf8\x97\xb6\x29\x0f\x01\xd1\x38"
+          "\xae\x2c\x4c\x90\x22\x5b\xa9\xea\x14\xd5\x18\xf5\x59\x29\xde\xa0"
+          "\x98\xca\x7a\x6c\xcf\xe6\x12\x27\x05\x3c\x84\xe4\x9a\x4a\x33\x32"
+        },
+        { 127,
+          "\xf6\x3a\x89\xb7\x5c\x22\x71\xf9\x36\x88\x16\x54\x2b\xa5\x2f\x06"
+          "\xed\x49\x24\x17\x92\x30\x2b\x00\xb5\xe8\xf8\x0a\xe9\xa4\x73\xaf"
+          "\xc2\x5b\x21\x8f\x51\x9a\xf0\xfd\xd4\x06\x36\x2e\x8d\x69\xde\x7f"
+          "\x54\xc6\x04\xa6\xe0\x0f\x35\x3f\x11\x0f\x77\x1b\xdc\xa8\xab\x92"
+          "\xe5\xfb\xc3\x4e\x60\xa1\xd9\xa9\xdb\x17\x34\x5b\x0a\x40\x27\x36"
+          "\x85\x3b\xf9\x10\xb0\x60\xbd\xf1\xf8\x97\xb6\x29\x0f\x01\xd1\x38"
+          "\xae\x2c\x4c\x90\x22\x5b\xa9\xea\x14\xd5\x18\xf5\x59\x29\xde\xa0"
+          "\x98\xca\x7a\x6c\xcf\xe6\x12\x27\x05\x3c\x84\xe4\x9a\x4a\x33",
+          "\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\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\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"
         }
       }
-    }
-#endif /*USE_SALSA20*/
+    },
+    /* from draft-nir-cfrg-chacha20-poly1305-02 */
+    {
+      "ChaCha20 256 bit, IV96-bit",
+      GCRY_CIPHER_CHACHA20, 32, 12,
+      "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+      "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f",
+      "\x07\x00\x00\x00\x40\x41\x42\x43\x44\x45\x46\x47",
+      {
+        { 64,
+          "\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\x00"
+          "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+          "\x7b\xac\x2b\x25\x2d\xb4\x47\xaf\x09\xb6\x7a\x55\xa4\xe9\x55\x84"
+          "\x0a\xe1\xd6\x73\x10\x75\xd9\xeb\x2a\x93\x75\x78\x3e\xd5\x53\xff"
+          "\xa2\x7e\xcc\xde\xad\xdb\x4d\xb4\xd1\x17\x9c\xe4\xc9\x0b\x43\xd8"
+          "\xbc\xb7\x94\x8c\x4b\x4b\x7d\x8b\x7d\xf6\x27\x39\x32\xa4\x69\x16"
+        },
+      },
+    },
+#endif /*USE_CHACHA20*/
   };
 
   gcry_cipher_hd_t hde, hdd;
@@ -2521,6 +4401,13 @@ check_stream_cipher (void)
 
   for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
     {
+      if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode)
+        {
+          if (verbose)
+            fprintf (stderr, "  algorithm %d not available in fips mode\n",
+                    tv[i].algo);
+          continue;
+        }
       if (verbose)
         fprintf (stderr, "    checking stream mode for %s [%i] (%s)\n",
                 gcry_cipher_algo_name (tv[i].algo), tv[i].algo, tv[i].name);
@@ -2965,6 +4852,14 @@ check_stream_cipher_large_block (void)
 
   for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
     {
+      if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode)
+        {
+          if (verbose)
+            fprintf (stderr, "  algorithm %d not available in fips mode\n",
+                    tv[i].algo);
+          continue;
+        }
+
       if (verbose)
         fprintf (stderr, "    checking large block stream for %s [%i] (%s)\n",
                 gcry_cipher_algo_name (tv[i].algo), tv[i].algo, tv[i].name);
@@ -3333,6 +5228,69 @@ check_bulk_cipher_modes (void)
 }
 
 
+static unsigned int
+get_algo_mode_blklen (int algo, int mode)
+{
+  unsigned int blklen = gcry_cipher_get_algo_blklen(algo);
+
+  /* Some modes override blklen. */
+  switch (mode)
+    {
+    case GCRY_CIPHER_MODE_STREAM:
+    case GCRY_CIPHER_MODE_OFB:
+    case GCRY_CIPHER_MODE_CTR:
+    case GCRY_CIPHER_MODE_CCM:
+    case GCRY_CIPHER_MODE_GCM:
+    case GCRY_CIPHER_MODE_POLY1305:
+      return 1;
+    }
+
+  return blklen;
+}
+
+
+static int
+check_one_cipher_core_reset (gcry_cipher_hd_t hd, int algo, int mode, int pass,
+                             int nplain)
+{
+  static const unsigned char iv[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
+  u64 ctl_params[3];
+  int err;
+
+  gcry_cipher_reset (hd);
+
+  if (mode == GCRY_CIPHER_MODE_OCB || mode == GCRY_CIPHER_MODE_CCM)
+    {
+      err = gcry_cipher_setiv (hd, iv, sizeof(iv));
+      if (err)
+        {
+          fail ("pass %d, algo %d, mode %d, gcry_cipher_setiv failed: %s\n",
+                pass, algo, mode, gpg_strerror (err));
+          gcry_cipher_close (hd);
+          return -1;
+        }
+    }
+
+  if (mode == GCRY_CIPHER_MODE_CCM)
+    {
+      ctl_params[0] = nplain; /* encryptedlen */
+      ctl_params[1] = 0; /* aadlen */
+      ctl_params[2] = 16; /* authtaglen */
+      err = gcry_cipher_ctl (hd, GCRYCTL_SET_CCM_LENGTHS, ctl_params,
+                            sizeof(ctl_params));
+      if (err)
+        {
+          fail ("pass %d, algo %d, mode %d, gcry_cipher_ctl "
+                "GCRYCTL_SET_CCM_LENGTHS failed: %s\n",
+                pass, algo, mode, gpg_strerror (err));
+          gcry_cipher_close (hd);
+          return -1;
+        }
+    }
+
+  return 0;
+}
+
 /* The core of the cipher check.  In addition to the parameters passed
    to check_one_cipher it also receives the KEY and the plain data.
    PASS is printed with error messages.  The function returns 0 on
@@ -3345,14 +5303,27 @@ check_one_cipher_core (int algo, int mode, int flags,
 {
   gcry_cipher_hd_t hd;
   unsigned char in_buffer[1040+1], out_buffer[1040+1];
+  unsigned char enc_result[1040];
   unsigned char *in, *out;
   int keylen;
   gcry_error_t err = 0;
+  unsigned int blklen;
+  unsigned int piecelen;
+  unsigned int pos;
+
+  blklen = get_algo_mode_blklen(algo, mode);
 
   assert (nkey == 32);
   assert (nplain == 1040);
   assert (sizeof(in_buffer) == nplain + 1);
   assert (sizeof(out_buffer) == sizeof(in_buffer));
+  assert (blklen > 0);
+
+  if (mode == GCRY_CIPHER_MODE_CBC && (flags & GCRY_CIPHER_CBC_CTS))
+    {
+      /* TODO: examine why CBC with CTS fails. */
+      blklen = nplain;
+    }
 
   if (!bufshift)
     {
@@ -3406,6 +5377,9 @@ check_one_cipher_core (int algo, int mode, int flags,
       return -1;
     }
 
+  if (check_one_cipher_core_reset (hd, algo, mode, pass, nplain) < 0)
+    return -1;
+
   err = gcry_cipher_encrypt (hd, out, nplain, plain, nplain);
   if (err)
     {
@@ -3415,7 +5389,10 @@ check_one_cipher_core (int algo, int mode, int flags,
       return -1;
     }
 
-  gcry_cipher_reset (hd);
+  memcpy (enc_result, out, nplain);
+
+  if (check_one_cipher_core_reset (hd, algo, mode, pass, nplain) < 0)
+    return -1;
 
   err = gcry_cipher_decrypt (hd, in, nplain, out, nplain);
   if (err)
@@ -3431,7 +5408,8 @@ check_one_cipher_core (int algo, int mode, int flags,
           pass, algo, mode);
 
   /* Again, using in-place encryption.  */
-  gcry_cipher_reset (hd);
+  if (check_one_cipher_core_reset (hd, algo, mode, pass, nplain) < 0)
+    return -1;
 
   memcpy (out, plain, nplain);
   err = gcry_cipher_encrypt (hd, out, nplain, NULL, 0);
@@ -3444,7 +5422,12 @@ check_one_cipher_core (int algo, int mode, int flags,
       return -1;
     }
 
-  gcry_cipher_reset (hd);
+  if (memcmp (enc_result, out, nplain))
+    fail ("pass %d, algo %d, mode %d, in-place, encrypt mismatch\n",
+          pass, algo, mode);
+
+  if (check_one_cipher_core_reset (hd, algo, mode, pass, nplain) < 0)
+    return -1;
 
   err = gcry_cipher_decrypt (hd, out, nplain, NULL, 0);
   if (err)
@@ -3460,6 +5443,123 @@ check_one_cipher_core (int algo, int mode, int flags,
     fail ("pass %d, algo %d, mode %d, in-place, encrypt-decrypt mismatch\n",
           pass, algo, mode);
 
+  /* Again, splitting encryption in multiple operations. */
+  if (check_one_cipher_core_reset (hd, algo, mode, pass, nplain) < 0)
+    return -1;
+
+  piecelen = blklen;
+  pos = 0;
+  while (pos < nplain)
+    {
+      if (piecelen > nplain - pos)
+        piecelen = nplain - pos;
+
+      err = gcry_cipher_encrypt (hd, out + pos, piecelen, plain + pos,
+                                 piecelen);
+      if (err)
+        {
+          fail ("pass %d, algo %d, mode %d, split-buffer (pos: %d, "
+                "piecelen: %d), gcry_cipher_encrypt failed: %s\n",
+                pass, algo, mode, pos, piecelen, gpg_strerror (err));
+          gcry_cipher_close (hd);
+          return -1;
+        }
+
+      pos += piecelen;
+      piecelen = piecelen * 2 - ((piecelen != blklen) ? blklen : 0);
+    }
+
+  if (memcmp (enc_result, out, nplain))
+    fail ("pass %d, algo %d, mode %d, split-buffer, encrypt mismatch\n",
+          pass, algo, mode);
+
+  if (check_one_cipher_core_reset (hd, algo, mode, pass, nplain) < 0)
+    return -1;
+
+  piecelen = blklen;
+  pos = 0;
+  while (pos < nplain)
+    {
+      if (piecelen > nplain - pos)
+        piecelen = nplain - pos;
+
+      err = gcry_cipher_decrypt (hd, in + pos, piecelen, out + pos, piecelen);
+      if (err)
+        {
+          fail ("pass %d, algo %d, mode %d, split-buffer (pos: %d, "
+                "piecelen: %d), gcry_cipher_decrypt failed: %s\n",
+                pass, algo, mode, pos, piecelen, gpg_strerror (err));
+          gcry_cipher_close (hd);
+          return -1;
+        }
+
+      pos += piecelen;
+      piecelen = piecelen * 2 - ((piecelen != blklen) ? blklen : 0);
+    }
+
+  if (memcmp (plain, in, nplain))
+    fail ("pass %d, algo %d, mode %d, split-buffer, encrypt-decrypt mismatch\n",
+          pass, algo, mode);
+
+  /* Again, using in-place encryption and splitting encryption in multiple
+   * operations. */
+  if (check_one_cipher_core_reset (hd, algo, mode, pass, nplain) < 0)
+    return -1;
+
+  piecelen = blklen;
+  pos = 0;
+  while (pos < nplain)
+    {
+      if (piecelen > nplain - pos)
+        piecelen = nplain - pos;
+
+      memcpy (out + pos, plain + pos, piecelen);
+      err = gcry_cipher_encrypt (hd, out + pos, piecelen, NULL, 0);
+      if (err)
+        {
+          fail ("pass %d, algo %d, mode %d, in-place split-buffer (pos: %d, "
+                "piecelen: %d), gcry_cipher_encrypt failed: %s\n",
+                pass, algo, mode, pos, piecelen, gpg_strerror (err));
+          gcry_cipher_close (hd);
+          return -1;
+        }
+
+      pos += piecelen;
+      piecelen = piecelen * 2 - ((piecelen != blklen) ? blklen : 0);
+    }
+
+  if (memcmp (enc_result, out, nplain))
+    fail ("pass %d, algo %d, mode %d, in-place split-buffer, encrypt mismatch\n",
+          pass, algo, mode);
+
+  if (check_one_cipher_core_reset (hd, algo, mode, pass, nplain) < 0)
+    return -1;
+
+  piecelen = blklen;
+  pos = 0;
+  while (pos < nplain)
+    {
+      if (piecelen > nplain - pos)
+        piecelen = nplain - pos;
+
+      err = gcry_cipher_decrypt (hd, out + pos, piecelen, NULL, 0);
+      if (err)
+        {
+          fail ("pass %d, algo %d, mode %d, in-place split-buffer (pos: %d, "
+                "piecelen: %d), gcry_cipher_decrypt failed: %s\n",
+                pass, algo, mode, pos, piecelen, gpg_strerror (err));
+          gcry_cipher_close (hd);
+          return -1;
+        }
+
+      pos += piecelen;
+      piecelen = piecelen * 2 - ((piecelen != blklen) ? blklen : 0);
+    }
+
+  if (memcmp (plain, out, nplain))
+    fail ("pass %d, algo %d, mode %d, in-place split-buffer, encrypt-decrypt"
+          " mismatch\n", pass, algo, mode);
+
 
   gcry_cipher_close (hd);
 
@@ -3572,6 +5672,9 @@ check_ciphers (void)
     GCRY_CIPHER_SALSA20,
     GCRY_CIPHER_SALSA20R12,
 #endif
+#if USE_CHACHA20
+    GCRY_CIPHER_CHACHA20,
+#endif
     0
   };
   int i;
@@ -3598,17 +5701,21 @@ check_ciphers (void)
       check_one_cipher (algos[i], GCRY_CIPHER_MODE_CBC, 0);
       check_one_cipher (algos[i], GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_CTS);
       check_one_cipher (algos[i], GCRY_CIPHER_MODE_CTR, 0);
+      if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_CCM_BLOCK_LEN)
+        check_one_cipher (algos[i], GCRY_CIPHER_MODE_CCM, 0);
       if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_GCM_BLOCK_LEN)
         check_one_cipher (algos[i], GCRY_CIPHER_MODE_GCM, 0);
+      if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_OCB_BLOCK_LEN)
+        check_one_cipher (algos[i], GCRY_CIPHER_MODE_OCB, 0);
     }
 
   for (i = 0; algos2[i]; i++)
     {
-      if (gcry_cipher_test_algo (algos[i]) && in_fips_mode)
+      if (gcry_cipher_test_algo (algos2[i]) && in_fips_mode)
         {
           if (verbose)
             fprintf (stderr, "  algorithm %d not available in fips mode\n",
-                    algos[i]);
+                    algos2[i]);
           continue;
         }
       if (verbose)
@@ -3616,6 +5723,8 @@ check_ciphers (void)
                 gcry_cipher_algo_name (algos2[i]));
 
       check_one_cipher (algos2[i], GCRY_CIPHER_MODE_STREAM, 0);
+      if (algos2[i] == GCRY_CIPHER_CHACHA20)
+       check_one_cipher (algos2[i], GCRY_CIPHER_MODE_POLY1305, 0);
     }
   /* we have now run all cipher's selftests */
 
@@ -3639,6 +5748,8 @@ check_cipher_modes(void)
   check_ofb_cipher ();
   check_ccm_cipher ();
   check_gcm_cipher ();
+  check_poly1305_cipher ();
+  check_ocb_cipher ();
   check_stream_cipher ();
   check_stream_cipher_large_block ();
 
@@ -3646,13 +5757,23 @@ check_cipher_modes(void)
     fprintf (stderr, "Completed Cipher Mode checks.\n");
 }
 
+
+static void
+fillbuf_count (char *buf, size_t buflen, unsigned char pos)
+{
+  while (buflen--)
+    *((unsigned char *)(buf++)) = pos++;
+}
+
+
 static void
-check_one_md (int algo, const char *data, int len, const char *expect)
+check_one_md (int algo, const char *data, int len, const char *expect, int elen)
 {
   gcry_md_hd_t hd, hd2;
   unsigned char *p;
   int mdlen;
   int i;
+  int xof = 0;
   gcry_error_t err = 0;
 
   err = gcry_md_open (&hd, algo, 0);
@@ -3665,18 +5786,65 @@ check_one_md (int algo, const char *data, int len, const char *expect)
   mdlen = gcry_md_get_algo_dlen (algo);
   if (mdlen < 1 || mdlen > 500)
     {
-      fail ("algo %d, gcry_md_get_algo_dlen failed: %d\n", algo, mdlen);
-      return;
+      if (mdlen == 0 && (algo == GCRY_MD_SHAKE128 || algo == GCRY_MD_SHAKE256))
+        {
+          xof = 1;
+        }
+      else
+        {
+          fail ("algo %d, gcry_md_get_algo_dlen failed: %d\n", algo, mdlen);
+          return;
+        }
     }
 
-  if (*data == '!' && !data[1])
-    {                          /* hash one million times a "a" */
+  if ((*data == '!' && !data[1]) || /* hash one million times a "a" */
+      (*data == '?' && !data[1]))   /* hash million byte data-set with byte pattern 0x00,0x01,0x02,... */
+    {
       char aaa[1000];
+      size_t left = 1000 * 1000;
+      size_t startlen = 1;
+      size_t piecelen = startlen;
+
+      if (*data == '!')
+        memset (aaa, 'a', 1000);
+
+      /* Write in chuck with all sizes 1 to 1000 (500500 bytes)  */
+      for (i = 1; i <= 1000 && left > 0; i++)
+        {
+          piecelen = i;
+          if (piecelen > sizeof(aaa))
+            piecelen = sizeof(aaa);
+          if (piecelen > left)
+            piecelen = left;
+
+         if (*data == '?')
+           fillbuf_count(aaa, piecelen, 1000 * 1000 - left);
+
+          gcry_md_write (hd, aaa, piecelen);
+
+          left -= piecelen;
+        }
 
       /* Write in odd size chunks so that we test the buffering.  */
-      memset (aaa, 'a', 1000);
-      for (i = 0; i < 1000; i++)
-        gcry_md_write (hd, aaa, 1000);
+      while (left > 0)
+        {
+          if (piecelen > sizeof(aaa))
+            piecelen = sizeof(aaa);
+          if (piecelen > left)
+            piecelen = left;
+
+         if (*data == '?')
+           fillbuf_count(aaa, piecelen, 1000 * 1000 - left);
+
+          gcry_md_write (hd, aaa, piecelen);
+
+          left -= piecelen;
+
+          if (piecelen == sizeof(aaa))
+            piecelen = ++startlen;
+          else
+            piecelen = piecelen * 2 - ((piecelen != startlen) ? startlen : 0);
+        }
     }
   else
     gcry_md_write (hd, data, len);
@@ -3689,19 +5857,168 @@ check_one_md (int algo, const char *data, int len, const char *expect)
 
   gcry_md_close (hd);
 
-  p = gcry_md_read (hd2, algo);
+  if (!xof)
+    {
+      p = gcry_md_read (hd2, algo);
 
-  if (memcmp (p, expect, mdlen))
+      if (memcmp (p, expect, mdlen))
+        {
+          printf ("computed: ");
+          for (i = 0; i < mdlen; i++)
+            printf ("%02x ", p[i] & 0xFF);
+          printf ("\nexpected: ");
+          for (i = 0; i < mdlen; i++)
+            printf ("%02x ", expect[i] & 0xFF);
+          printf ("\n");
+
+          fail ("algo %d, digest mismatch\n", algo);
+        }
+
+    }
+  else
     {
-      printf ("computed: ");
-      for (i = 0; i < mdlen; i++)
-       printf ("%02x ", p[i] & 0xFF);
-      printf ("\nexpected: ");
-      for (i = 0; i < mdlen; i++)
-       printf ("%02x ", expect[i] & 0xFF);
-      printf ("\n");
+      char buf[1000];
+      int outmax = sizeof(buf) > elen ? elen : sizeof(buf);
 
-      fail ("algo %d, digest mismatch\n", algo);
+      err = gcry_md_copy (&hd, hd2);
+      if (err)
+       {
+         fail ("algo %d, gcry_md_copy failed: %s\n", algo, gpg_strerror (err));
+       }
+
+      err = gcry_md_extract(hd2, algo, buf, outmax);
+      if (err)
+       {
+         fail ("algo %d, gcry_md_extract failed: %s\n", algo, gpg_strerror (err));
+       }
+
+      if (memcmp (buf, expect, outmax))
+       {
+         printf ("computed: ");
+         for (i = 0; i < outmax; i++)
+           printf ("%02x ", buf[i] & 0xFF);
+         printf ("\nexpected: ");
+         for (i = 0; i < outmax; i++)
+           printf ("%02x ", expect[i] & 0xFF);
+         printf ("\n");
+
+         fail ("algo %d, digest mismatch\n", algo);
+       }
+
+      memset(buf, 0, sizeof(buf));
+
+      /* Extract one byte at time. */
+      for (i = 0; i < outmax && !err; i++)
+       err = gcry_md_extract(hd, algo, &buf[i], 1);
+      if (err)
+       {
+         fail ("algo %d, gcry_md_extract failed: %s\n", algo, gpg_strerror (err));
+       }
+
+      if (memcmp (buf, expect, outmax))
+       {
+         printf ("computed: ");
+         for (i = 0; i < outmax; i++)
+           printf ("%02x ", buf[i] & 0xFF);
+         printf ("\nexpected: ");
+         for (i = 0; i < outmax; i++)
+           printf ("%02x ", expect[i] & 0xFF);
+         printf ("\n");
+
+         fail ("algo %d, digest mismatch\n", algo);
+       }
+
+      if (*data == '!' && !data[1])
+       {
+         int crcalgo = GCRY_MD_RMD160;
+         gcry_md_hd_t crc1, crc2;
+         size_t startlen;
+         size_t piecelen;
+         size_t left;
+         const unsigned char *p1, *p2;
+         int crclen;
+
+         crclen = gcry_md_get_algo_dlen (crcalgo);
+
+         err = gcry_md_open (&crc1, crcalgo, 0);
+         if (err)
+           {
+             fail ("algo %d, crcalgo: %d, gcry_md_open failed: %s\n", algo,
+                   crcalgo, gpg_strerror (err));
+             return;
+           }
+
+         err = gcry_md_open (&crc2, crcalgo, 0);
+         if (err)
+           {
+             fail ("algo %d, crcalgo: %d, gcry_md_open failed: %s\n", algo,
+                   crcalgo, gpg_strerror (err));
+             return;
+           }
+
+         /* Extract large chucks, total 1000000 additional bytes. */
+         for (i = 0; i < 1000; i++)
+           {
+             err = gcry_md_extract(hd, algo, buf, 1000);
+             if (!err)
+               gcry_md_write(crc1, buf, 1000);
+           }
+         if (err)
+           {
+             fail ("algo %d, gcry_md_extract failed: %s\n", algo,
+                   gpg_strerror (err));
+           }
+
+         /* Extract in odd size chunks, total 1000000 additional bytes.  */
+         left = 1000 * 1000;
+         startlen = 1;
+         piecelen = startlen;
+
+         while (!err && left > 0)
+           {
+             if (piecelen > sizeof(buf))
+               piecelen = sizeof(buf);
+             if (piecelen > left)
+               piecelen = left;
+
+             err = gcry_md_extract (hd2, algo, buf, piecelen);
+             if (!err)
+               gcry_md_write(crc2, buf, piecelen);
+             if (err)
+               {
+                 fail ("algo %d, gcry_md_extract failed: %s\n", algo,
+                       gpg_strerror (err));
+               }
+
+             left -= piecelen;
+
+             if (piecelen == sizeof(buf))
+               piecelen = ++startlen;
+             else
+               piecelen = piecelen * 2 - ((piecelen != startlen) ? startlen : 0);
+           }
+
+         p1 = gcry_md_read (crc1, crcalgo);
+         p2 = gcry_md_read (crc2, crcalgo);
+
+         if (memcmp (p1, p2, crclen))
+           {
+             printf ("computed: ");
+             for (i = 0; i < crclen; i++)
+               printf ("%02x ", p2[i] & 0xFF);
+             printf ("\nexpected: ");
+             for (i = 0; i < crclen; i++)
+               printf ("%02x ", p1[i] & 0xFF);
+             printf ("\n");
+
+             fail ("algo %d, large xof output mismatch\n", algo);
+           }
+
+         gcry_md_close (crc1);
+         gcry_md_close (crc2);
+       }
+
+      gcry_md_close (hd);
     }
 
   gcry_md_close (hd2);
@@ -3721,6 +6038,9 @@ check_one_md_multi (int algo, const char *data, int len, const char *expect)
   mdlen = gcry_md_get_algo_dlen (algo);
   if (mdlen < 1 || mdlen > 64)
     {
+      if (mdlen == 0 && (algo == GCRY_MD_SHAKE128 || algo == GCRY_MD_SHAKE256))
+        return;
+
       fail ("check_one_md_multi: algo %d, gcry_md_get_algo_dlen failed: %d\n",
             algo, mdlen);
       return;
@@ -3728,6 +6048,8 @@ check_one_md_multi (int algo, const char *data, int len, const char *expect)
 
   if (*data == '!' && !data[1])
     return;  /* We can't do that here.  */
+  if (*data == '?' && !data[1])
+    return;  /* We can't do that here.  */
 
   memset (iov, 0, sizeof iov);
 
@@ -3782,8 +6104,16 @@ check_digests (void)
     int md;
     const char *data;
     const char *expect;
+    int datalen;
+    int expectlen;
   } algos[] =
     {
+      { GCRY_MD_MD2, "",
+        "\x83\x50\xe5\xa3\xe2\x4c\x15\x3d\xf2\x27\x5c\x9f\x80\x69\x27\x73" },
+      { GCRY_MD_MD2, "a",
+        "\x32\xec\x01\xec\x4a\x6d\xac\x72\xc0\xab\x96\xfb\x34\xc0\xb5\xd1" },
+      {        GCRY_MD_MD2, "message digest",
+        "\xab\x4f\x49\x6b\xfb\x2a\x53\x0b\x21\x9f\xf3\x30\x31\xfe\x06\xb0" },
       { GCRY_MD_MD4, "",
        "\x31\xD6\xCF\xE0\xD1\x6A\xE9\x31\xB7\x3C\x59\xD7\xE0\xC0\x89\xC0" },
       { GCRY_MD_MD4, "a",
@@ -3798,6 +6128,20 @@ check_digests (void)
        "\x90\x01\x50\x98\x3C\xD2\x4F\xB0\xD6\x96\x3F\x7D\x28\xE1\x7F\x72" },
       { GCRY_MD_MD5, "message digest",
        "\xF9\x6B\x69\x7D\x7C\xB7\x93\x8D\x52\x5A\x2F\x31\xAA\xF1\x61\xD0" },
+      { GCRY_MD_MD5,
+       "Libgcrypt is free software; you can redistribute it and/or modif"
+       "y it under the terms of the GNU Lesser general Public License as"
+       " published by the Free Software Foundation; either version 2.1 o"
+       "f the License, or (at your option) any later version.\nLibgcrypt"
+       " is distributed in the hope that it will be useful, but WITHOUT "
+       "ANY WARRANTY; without even the implied warranty of MERCHANTABILI"
+       "TY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser Gene"
+       "ral Public License for more details.",
+       "\xc4\x1a\x5c\x0b\x44\x5f\xba\x1a\xda\xbc\xc0\x38\x0e\x0c\x9e\x33" },
+      { GCRY_MD_MD5, "!",
+        "\x77\x07\xd6\xae\x4e\x02\x7c\x70\xee\xa2\xa9\x35\xc2\x29\x6f\x21" },
+      { GCRY_MD_MD5, "?",
+        "\x5c\x72\x5c\xbc\x2d\xbb\xe1\x14\x81\x59\xe9\xd9\xcf\x90\x64\x8f" },
       { GCRY_MD_SHA1, "abc",
        "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E"
        "\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D" },
@@ -3808,6 +6152,20 @@ check_digests (void)
       { GCRY_MD_SHA1, "!" /* kludge for "a"*1000000 */ ,
        "\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E"
        "\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F" },
+      { GCRY_MD_SHA1, "?" /* kludge for "\x00\x01\x02"..."\xfe\xff\x00\x01"... (length 1000000) */ ,
+       "\x5f\x8d\x3c\x4f\x12\xf0\x49\x9e\x28\x73"
+       "\x79\xec\x97\x3b\x98\x4c\x94\x75\xaa\x8f" },
+      { GCRY_MD_SHA1,
+       "Libgcrypt is free software; you can redistribute it and/or modif"
+       "y it under the terms of the GNU Lesser general Public License as"
+       " published by the Free Software Foundation; either version 2.1 o"
+       "f the License, or (at your option) any later version.\nLibgcrypt"
+       " is distributed in the hope that it will be useful, but WITHOUT "
+       "ANY WARRANTY; without even the implied warranty of MERCHANTABILI"
+       "TY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser Gene"
+       "ral Public License for more details.",
+       "\xf5\xd9\xcb\x66\x91\xb4\x7a\x7c\x60\x35\xe2\x1c\x38\x26\x52\x13"
+       "\x8e\xd5\xe5\xdf" },
       /* From RFC3874 */
       {        GCRY_MD_SHA224, "abc",
        "\x23\x09\x7d\x22\x34\x05\xd8\x22\x86\x42\xa4\x77\xbd\xa2\x55\xb3"
@@ -3819,6 +6177,20 @@ check_digests (void)
       {        GCRY_MD_SHA224, "!",
        "\x20\x79\x46\x55\x98\x0c\x91\xd8\xbb\xb4\xc1\xea\x97\x61\x8a\x4b"
        "\xf0\x3f\x42\x58\x19\x48\xb2\xee\x4e\xe7\xad\x67" },
+      {        GCRY_MD_SHA224, "?",
+       "\xfa\xb9\xf0\xdf\x12\xfe\xa1\x1a\x34\x78\x96\x31\xe6\x53\x48\xbf"
+       "\x3b\xca\x70\x78\xf2\x44\xdf\x62\xab\x27\xb8\xda" },
+      { GCRY_MD_SHA224,
+       "Libgcrypt is free software; you can redistribute it and/or modif"
+       "y it under the terms of the GNU Lesser general Public License as"
+       " published by the Free Software Foundation; either version 2.1 o"
+       "f the License, or (at your option) any later version.\nLibgcrypt"
+       " is distributed in the hope that it will be useful, but WITHOUT "
+       "ANY WARRANTY; without even the implied warranty of MERCHANTABILI"
+       "TY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser Gene"
+       "ral Public License for more details.",
+       "\x80\xf0\x60\x79\xb0\xe9\x65\xab\x8a\x76\xbf\x6e\x88\x64\x75\xe7"
+       "\xfd\xf0\xc2\x4c\xf6\xf2\xa6\x01\xed\x50\x71\x08" },
       {        GCRY_MD_SHA256, "abc",
        "\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23"
        "\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad" },
@@ -3829,15 +6201,170 @@ check_digests (void)
       {        GCRY_MD_SHA256, "!",
        "\xcd\xc7\x6e\x5c\x99\x14\xfb\x92\x81\xa1\xc7\xe2\x84\xd7\x3e\x67"
        "\xf1\x80\x9a\x48\xa4\x97\x20\x0e\x04\x6d\x39\xcc\xc7\x11\x2c\xd0" },
+      {        GCRY_MD_SHA256, "?",
+       "\x67\x87\x0d\xfc\x9c\x64\xe7\xaa\x27\x0a\x3f\x7e\x80\x51\xae\x65"
+       "\xd2\x07\xf9\x3f\xc3\xdf\x04\xd7\x57\x2e\x63\x65\xaf\x69\xcd\x0d" },
+      { GCRY_MD_SHA256,
+       "Libgcrypt is free software; you can redistribute it and/or modif"
+       "y it under the terms of the GNU Lesser general Public License as"
+       " published by the Free Software Foundation; either version 2.1 o"
+       "f the License, or (at your option) any later version.\nLibgcrypt"
+       " is distributed in the hope that it will be useful, but WITHOUT "
+       "ANY WARRANTY; without even the implied warranty of MERCHANTABILI"
+       "TY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser Gene"
+       "ral Public License for more details.",
+       "\xb0\x18\x70\x67\xb8\xac\x68\x50\xec\x95\x43\x77\xb5\x44\x5b\x0f"
+       "\x2e\xbd\x40\xc9\xdc\x2a\x2c\x33\x8b\x53\xeb\x3e\x9e\x01\xd7\x02" },
       {        GCRY_MD_SHA384, "abc",
        "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50\x07"
        "\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff\x5b\xed"
        "\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34\xc8\x25\xa7" },
+      { GCRY_MD_SHA384,
+       "Libgcrypt is free software; you can redistribute it and/or modif"
+       "y it under the terms of the GNU Lesser general Public License as"
+       " published by the Free Software Foundation; either version 2.1 o"
+       "f the License, or (at your option) any later version.\nLibgcrypt"
+       " is distributed in the hope that it will be useful, but WITHOUT "
+       "ANY WARRANTY; without even the implied warranty of MERCHANTABILI"
+       "TY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser Gene"
+       "ral Public License for more details.",
+       "\xe4\x6d\xb4\x28\x33\x77\x99\x49\x94\x0f\xcf\x87\xc2\x2f\x30\xd6"
+       "\x06\x24\x82\x9d\x80\x64\x8a\x07\xa1\x20\x8f\x5f\xf3\x85\xb3\xaa"
+       "\x39\xb8\x61\x00\xfc\x7f\x18\xc6\x82\x23\x4b\x45\xfa\xf1\xbc\x69" },
+      { GCRY_MD_SHA384, "!",
+        "\x9d\x0e\x18\x09\x71\x64\x74\xcb\x08\x6e\x83\x4e\x31\x0a\x4a\x1c"
+        "\xed\x14\x9e\x9c\x00\xf2\x48\x52\x79\x72\xce\xc5\x70\x4c\x2a\x5b"
+        "\x07\xb8\xb3\xdc\x38\xec\xc4\xeb\xae\x97\xdd\xd8\x7f\x3d\x89\x85" },
+      { GCRY_MD_SHA384, "?",
+        "\xfa\x77\xbb\x86\x3a\xd5\xae\x88\xa9\x9c\x5e\xda\xb5\xc7\xcb\x40"
+       "\xcd\xf4\x30\xef\xa8\x1b\x23\x7b\xa9\xde\xfd\x81\x12\xf6\x7e\xed"
+       "\xa7\xd2\x27\x91\xd1\xbc\x76\x44\x57\x59\x71\x11\xe6\x8a\x2c\xde" },
       {        GCRY_MD_SHA512, "abc",
        "\xDD\xAF\x35\xA1\x93\x61\x7A\xBA\xCC\x41\x73\x49\xAE\x20\x41\x31"
        "\x12\xE6\xFA\x4E\x89\xA9\x7E\xA2\x0A\x9E\xEE\xE6\x4B\x55\xD3\x9A"
        "\x21\x92\x99\x2A\x27\x4F\xC1\xA8\x36\xBA\x3C\x23\xA3\xFE\xEB\xBD"
        "\x45\x4D\x44\x23\x64\x3C\xE8\x0E\x2A\x9A\xC9\x4F\xA5\x4C\xA4\x9F" },
+      { GCRY_MD_SHA512,
+       "Libgcrypt is free software; you can redistribute it and/or modif"
+       "y it under the terms of the GNU Lesser general Public License as"
+       " published by the Free Software Foundation; either version 2.1 o"
+       "f the License, or (at your option) any later version.\nLibgcrypt"
+       " is distributed in the hope that it will be useful, but WITHOUT "
+       "ANY WARRANTY; without even the implied warranty of MERCHANTABILI"
+       "TY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser Gene"
+       "ral Public License for more details.",
+       "\x72\x8c\xde\xd8\xe4\xd7\xb6\xa5\x0f\xde\x6b\x4d\x33\xaf\x15\x19"
+       "\xdd\xec\x62\x0f\xf7\x1a\x1e\x10\x32\x05\x02\xa6\xb0\x1f\x70\x37"
+       "\xbc\xd7\x15\xed\x71\x6c\x78\x20\xc8\x54\x87\xd0\x66\x6a\x17\x83"
+       "\x05\x61\x92\xbe\xcc\x8f\x3b\xbf\x11\x72\x22\x69\x23\x5b\x48\x5c" },
+      { GCRY_MD_SHA512, "!",
+        "\xe7\x18\x48\x3d\x0c\xe7\x69\x64\x4e\x2e\x42\xc7\xbc\x15\xb4\x63"
+        "\x8e\x1f\x98\xb1\x3b\x20\x44\x28\x56\x32\xa8\x03\xaf\xa9\x73\xeb"
+        "\xde\x0f\xf2\x44\x87\x7e\xa6\x0a\x4c\xb0\x43\x2c\xe5\x77\xc3\x1b"
+        "\xeb\x00\x9c\x5c\x2c\x49\xaa\x2e\x4e\xad\xb2\x17\xad\x8c\xc0\x9b" },
+      { GCRY_MD_SHA512, "?",
+        "\x91\xe9\x42\x4e\xa9\xdc\x44\x01\x40\x64\xa4\x5a\x69\xcc\xac\xa3"
+        "\x74\xee\x78\xeb\x79\x1f\x94\x38\x5b\x73\xef\xf8\xfd\x5d\x74\xd8"
+        "\x51\x36\xfe\x63\x52\xde\x07\x70\x95\xd6\x78\x2b\x7b\x46\x8a\x2c"
+        "\x30\x0f\x48\x0c\x74\x43\x06\xdb\xa3\x8d\x64\x3d\xe9\xa1\xa7\x72" },
+      { GCRY_MD_SHA3_224, "abc",
+       "\xe6\x42\x82\x4c\x3f\x8c\xf2\x4a\xd0\x92\x34\xee\x7d\x3c\x76\x6f"
+       "\xc9\xa3\xa5\x16\x8d\x0c\x94\xad\x73\xb4\x6f\xdf" },
+      { GCRY_MD_SHA3_256, "abc",
+       "\x3a\x98\x5d\xa7\x4f\xe2\x25\xb2\x04\x5c\x17\x2d\x6b\xd3\x90\xbd"
+       "\x85\x5f\x08\x6e\x3e\x9d\x52\x5b\x46\xbf\xe2\x45\x11\x43\x15\x32" },
+      { GCRY_MD_SHA3_384, "abc",
+       "\xec\x01\x49\x82\x88\x51\x6f\xc9\x26\x45\x9f\x58\xe2\xc6\xad\x8d"
+       "\xf9\xb4\x73\xcb\x0f\xc0\x8c\x25\x96\xda\x7c\xf0\xe4\x9b\xe4\xb2"
+       "\x98\xd8\x8c\xea\x92\x7a\xc7\xf5\x39\xf1\xed\xf2\x28\x37\x6d\x25" },
+      { GCRY_MD_SHA3_512, "abc",
+       "\xb7\x51\x85\x0b\x1a\x57\x16\x8a\x56\x93\xcd\x92\x4b\x6b\x09\x6e"
+       "\x08\xf6\x21\x82\x74\x44\xf7\x0d\x88\x4f\x5d\x02\x40\xd2\x71\x2e"
+       "\x10\xe1\x16\xe9\x19\x2a\xf3\xc9\x1a\x7e\xc5\x76\x47\xe3\x93\x40"
+       "\x57\x34\x0b\x4c\xf4\x08\xd5\xa5\x65\x92\xf8\x27\x4e\xec\x53\xf0" },
+      { GCRY_MD_SHA3_224, "",
+       "\x6b\x4e\x03\x42\x36\x67\xdb\xb7\x3b\x6e\x15\x45\x4f\x0e\xb1\xab"
+       "\xd4\x59\x7f\x9a\x1b\x07\x8e\x3f\x5b\x5a\x6b\xc7" },
+      { GCRY_MD_SHA3_256, "",
+       "\xa7\xff\xc6\xf8\xbf\x1e\xd7\x66\x51\xc1\x47\x56\xa0\x61\xd6\x62"
+       "\xf5\x80\xff\x4d\xe4\x3b\x49\xfa\x82\xd8\x0a\x4b\x80\xf8\x43\x4a" },
+      { GCRY_MD_SHA3_384, "",
+       "\x0c\x63\xa7\x5b\x84\x5e\x4f\x7d\x01\x10\x7d\x85\x2e\x4c\x24\x85"
+       "\xc5\x1a\x50\xaa\xaa\x94\xfc\x61\x99\x5e\x71\xbb\xee\x98\x3a\x2a"
+       "\xc3\x71\x38\x31\x26\x4a\xdb\x47\xfb\x6b\xd1\xe0\x58\xd5\xf0\x04" },
+      { GCRY_MD_SHA3_512, "",
+       "\xa6\x9f\x73\xcc\xa2\x3a\x9a\xc5\xc8\xb5\x67\xdc\x18\x5a\x75\x6e"
+       "\x97\xc9\x82\x16\x4f\xe2\x58\x59\xe0\xd1\xdc\xc1\x47\x5c\x80\xa6"
+       "\x15\xb2\x12\x3a\xf1\xf5\xf9\x4c\x11\xe3\xe9\x40\x2c\x3a\xc5\x58"
+       "\xf5\x00\x19\x9d\x95\xb6\xd3\xe3\x01\x75\x85\x86\x28\x1d\xcd\x26" },
+      { GCRY_MD_SHA3_224, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlm"
+       "nomnopnopq",
+       "\x8a\x24\x10\x8b\x15\x4a\xda\x21\xc9\xfd\x55\x74\x49\x44\x79\xba"
+       "\x5c\x7e\x7a\xb7\x6e\xf2\x64\xea\xd0\xfc\xce\x33" },
+      { GCRY_MD_SHA3_256, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlm"
+       "nomnopnopq",
+       "\x41\xc0\xdb\xa2\xa9\xd6\x24\x08\x49\x10\x03\x76\xa8\x23\x5e\x2c"
+       "\x82\xe1\xb9\x99\x8a\x99\x9e\x21\xdb\x32\xdd\x97\x49\x6d\x33\x76" },
+      { GCRY_MD_SHA3_384, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlm"
+       "nomnopnopq",
+       "\x99\x1c\x66\x57\x55\xeb\x3a\x4b\x6b\xbd\xfb\x75\xc7\x8a\x49\x2e"
+       "\x8c\x56\xa2\x2c\x5c\x4d\x7e\x42\x9b\xfd\xbc\x32\xb9\xd4\xad\x5a"
+       "\xa0\x4a\x1f\x07\x6e\x62\xfe\xa1\x9e\xef\x51\xac\xd0\x65\x7c\x22" },
+      { GCRY_MD_SHA3_512, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlm"
+       "nomnopnopq",
+       "\x04\xa3\x71\xe8\x4e\xcf\xb5\xb8\xb7\x7c\xb4\x86\x10\xfc\xa8\x18"
+       "\x2d\xd4\x57\xce\x6f\x32\x6a\x0f\xd3\xd7\xec\x2f\x1e\x91\x63\x6d"
+       "\xee\x69\x1f\xbe\x0c\x98\x53\x02\xba\x1b\x0d\x8d\xc7\x8c\x08\x63"
+       "\x46\xb5\x33\xb4\x9c\x03\x0d\x99\xa2\x7d\xaf\x11\x39\xd6\xe7\x5e" },
+      { GCRY_MD_SHA3_224, "abcdefghbcdefghicdefghijdefghijkefghijklfghijk"
+       "lmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+       "\x54\x3e\x68\x68\xe1\x66\x6c\x1a\x64\x36\x30\xdf\x77\x36\x7a\xe5"
+       "\xa6\x2a\x85\x07\x0a\x51\xc1\x4c\xbf\x66\x5c\xbc" },
+      { GCRY_MD_SHA3_256, "abcdefghbcdefghicdefghijdefghijkefghijklfghijk"
+       "lmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+       "\x91\x6f\x60\x61\xfe\x87\x97\x41\xca\x64\x69\xb4\x39\x71\xdf\xdb"
+       "\x28\xb1\xa3\x2d\xc3\x6c\xb3\x25\x4e\x81\x2b\xe2\x7a\xad\x1d\x18" },
+      { GCRY_MD_SHA3_384, "abcdefghbcdefghicdefghijdefghijkefghijklfghijk"
+       "lmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+       "\x79\x40\x7d\x3b\x59\x16\xb5\x9c\x3e\x30\xb0\x98\x22\x97\x47\x91"
+       "\xc3\x13\xfb\x9e\xcc\x84\x9e\x40\x6f\x23\x59\x2d\x04\xf6\x25\xdc"
+       "\x8c\x70\x9b\x98\xb4\x3b\x38\x52\xb3\x37\x21\x61\x79\xaa\x7f\xc7" },
+      { GCRY_MD_SHA3_512, "abcdefghbcdefghicdefghijdefghijkefghijklfghijk"
+       "lmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+       "\xaf\xeb\xb2\xef\x54\x2e\x65\x79\xc5\x0c\xad\x06\xd2\xe5\x78\xf9"
+       "\xf8\xdd\x68\x81\xd7\xdc\x82\x4d\x26\x36\x0f\xee\xbf\x18\xa4\xfa"
+       "\x73\xe3\x26\x11\x22\x94\x8e\xfc\xfd\x49\x2e\x74\xe8\x2e\x21\x89"
+       "\xed\x0f\xb4\x40\xd1\x87\xf3\x82\x27\x0c\xb4\x55\xf2\x1d\xd1\x85" },
+      { GCRY_MD_SHA3_224, "!",
+       "\xd6\x93\x35\xb9\x33\x25\x19\x2e\x51\x6a\x91\x2e\x6d\x19\xa1\x5c"
+       "\xb5\x1c\x6e\xd5\xc1\x52\x43\xe7\xa7\xfd\x65\x3c" },
+      { GCRY_MD_SHA3_256, "!",
+       "\x5c\x88\x75\xae\x47\x4a\x36\x34\xba\x4f\xd5\x5e\xc8\x5b\xff\xd6"
+       "\x61\xf3\x2a\xca\x75\xc6\xd6\x99\xd0\xcd\xcb\x6c\x11\x58\x91\xc1" },
+      { GCRY_MD_SHA3_384, "!",
+       "\xee\xe9\xe2\x4d\x78\xc1\x85\x53\x37\x98\x34\x51\xdf\x97\xc8\xad"
+       "\x9e\xed\xf2\x56\xc6\x33\x4f\x8e\x94\x8d\x25\x2d\x5e\x0e\x76\x84"
+       "\x7a\xa0\x77\x4d\xdb\x90\xa8\x42\x19\x0d\x2c\x55\x8b\x4b\x83\x40" },
+      { GCRY_MD_SHA3_512, "!",
+       "\x3c\x3a\x87\x6d\xa1\x40\x34\xab\x60\x62\x7c\x07\x7b\xb9\x8f\x7e"
+       "\x12\x0a\x2a\x53\x70\x21\x2d\xff\xb3\x38\x5a\x18\xd4\xf3\x88\x59"
+       "\xed\x31\x1d\x0a\x9d\x51\x41\xce\x9c\xc5\xc6\x6e\xe6\x89\xb2\x66"
+       "\xa8\xaa\x18\xac\xe8\x28\x2a\x0e\x0d\xb5\x96\xc9\x0b\x0a\x7b\x87" },
+      { GCRY_MD_SHA3_224, "?",
+       "\x1b\xd1\xc6\x12\x02\x35\x52\x8b\x44\x7e\x16\x39\x20\x05\xec\x67"
+       "\x2d\x57\x20\xe0\x90\xc9\x78\x08\x86\x4f\x1b\xd0" },
+      { GCRY_MD_SHA3_256, "?",
+       "\xfe\xb7\xf4\x76\x78\x97\x48\x2f\xe2\x29\x1b\x66\x85\xc1\x7b\x45"
+       "\xc5\x08\xed\x82\x50\xcc\x5d\x99\x96\xd2\xc3\x82\x1a\xa8\xd4\xa7" },
+      { GCRY_MD_SHA3_384, "?",
+       "\x45\x1f\x0b\x93\x4b\xca\x3e\x65\x93\xd4\xaa\x8c\x18\xc1\x04\x84"
+       "\x12\xd5\x1e\x35\xe1\x05\xd9\x77\x3f\xc1\x08\x8b\x77\x36\xad\x4a"
+       "\x33\x70\xaf\x49\x8b\xea\x4c\x5c\x52\xe7\x5b\xed\x31\x74\x57\x12" },
+      { GCRY_MD_SHA3_512, "?",
+       "\xa2\xee\xb5\x6f\x2a\x87\xa5\xb3\x9b\xd9\x1c\xf0\xaa\xdf\xb1\xd5"
+       "\xad\x0a\x1a\xaa\xd3\x63\x81\xcf\xb8\x7c\x36\xa7\x80\x3b\x03\xd6"
+       "\x31\x5c\x5d\x33\x8e\x52\xb1\x42\x4d\x27\x1c\xa2\xa5\xf2\xc5\x97"
+       "\x10\x12\xe5\xee\x86\xa3\xcc\xaf\x91\x7a\x94\x28\x65\xea\x66\xe3" },
       {        GCRY_MD_RMD160, "",
        "\x9c\x11\x85\xa5\xc5\xe9\xfc\x54\x61\x28"
        "\x08\x97\x7e\xe8\xf5\x48\xb2\x25\x8d\x31" },
@@ -3850,25 +6377,57 @@ check_digests (void)
       {        GCRY_MD_RMD160, "message digest",
        "\x5d\x06\x89\xef\x49\xd2\xfa\xe5\x72\xb8"
        "\x81\xb1\x23\xa8\x5f\xfa\x21\x59\x5f\x36" },
+      { GCRY_MD_RMD160,
+       "Libgcrypt is free software; you can redistribute it and/or modif"
+       "y it under the terms of the GNU Lesser general Public License as"
+       " published by the Free Software Foundation; either version 2.1 o"
+       "f the License, or (at your option) any later version.\nLibgcrypt"
+       " is distributed in the hope that it will be useful, but WITHOUT "
+       "ANY WARRANTY; without even the implied warranty of MERCHANTABILI"
+       "TY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser Gene"
+       "ral Public License for more details.",
+       "\x06\x6d\x3c\x4e\xc9\xba\x89\x75\x16\x90\x96\x4e\xfd\x43\x07\xde"
+       "\x04\xca\x69\x6b" },
+      { GCRY_MD_RMD160, "!",
+        "\x52\x78\x32\x43\xc1\x69\x7b\xdb\xe1\x6d\x37\xf9\x7f\x68\xf0\x83"
+        "\x25\xdc\x15\x28" },
+      { GCRY_MD_RMD160, "?",
+       "\x68\x14\x86\x70\x3d\x51\x4e\x36\x68\x50\xf8\xb3\x00\x75\xda\x49"
+       "\x0a\xaa\x2c\xf6" },
       {        GCRY_MD_CRC32, "", "\x00\x00\x00\x00" },
       {        GCRY_MD_CRC32, "foo", "\x8c\x73\x65\x21" },
+      { GCRY_MD_CRC32,
+       "Libgcrypt is free software; you can redistribute it and/or modif"
+       "y it under the terms of the GNU Lesser general Public License as"
+       " published by the Free Software Foundation; either version 2.1 o"
+       "f the License, or (at your option) any later version.\nLibgcrypt"
+       " is distributed in the hope that it will be useful, but WITHOUT "
+       "ANY WARRANTY; without even the implied warranty of MERCHANTABILI"
+       "TY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser Gene"
+       "ral Public License for more details.",
+       "\x4A\x53\x7D\x67" },
+      { GCRY_MD_CRC32, "123456789", "\xcb\xf4\x39\x26" },
+      { GCRY_MD_CRC32, "!", "\xdc\x25\xbf\xbc" },
+      { GCRY_MD_CRC32, "?", "\x61\x82\x29\x1B" },
       { GCRY_MD_CRC32_RFC1510, "", "\x00\x00\x00\x00" },
       {        GCRY_MD_CRC32_RFC1510, "foo", "\x73\x32\xbc\x33" },
       {        GCRY_MD_CRC32_RFC1510, "test0123456789", "\xb8\x3e\x88\xd6" },
       {        GCRY_MD_CRC32_RFC1510, "MASSACHVSETTS INSTITVTE OF TECHNOLOGY",
        "\xe3\x41\x80\xf7" },
-#if 0
-      {        GCRY_MD_CRC32_RFC1510, "\x80\x00", "\x3b\x83\x98\x4b" },
-      {        GCRY_MD_CRC32_RFC1510, "\x00\x08", "\x0e\xdb\x88\x32" },
-      {        GCRY_MD_CRC32_RFC1510, "\x00\x80", "\xed\xb8\x83\x20" },
-#endif
+      {        GCRY_MD_CRC32_RFC1510, "\x80\x00", "\x3b\x83\x98\x4b", 2 },
+      {        GCRY_MD_CRC32_RFC1510, "\x00\x08", "\x0e\xdb\x88\x32", 2 },
+      {        GCRY_MD_CRC32_RFC1510, "\x00\x80", "\xed\xb8\x83\x20", 2 },
       {        GCRY_MD_CRC32_RFC1510, "\x80", "\xed\xb8\x83\x20" },
-#if 0
-      {        GCRY_MD_CRC32_RFC1510, "\x80\x00\x00\x00", "\xed\x59\xb6\x3b" },
-      {        GCRY_MD_CRC32_RFC1510, "\x00\x00\x00\x01", "\x77\x07\x30\x96" },
-#endif
+      {        GCRY_MD_CRC32_RFC1510, "\x80\x00\x00\x00", "\xed\x59\xb6\x3b", 4 },
+      {        GCRY_MD_CRC32_RFC1510, "\x00\x00\x00\x01", "\x77\x07\x30\x96", 4 },
+      { GCRY_MD_CRC32_RFC1510, "123456789", "\x2d\xfd\x2d\x88" },
+      { GCRY_MD_CRC32_RFC1510, "!", "\xce\x5c\x74\x22" },
+      {        GCRY_MD_CRC32_RFC1510, "?", "\x73\xfb\xe2\x85" },
       {        GCRY_MD_CRC24_RFC2440, "", "\xb7\x04\xce" },
       {        GCRY_MD_CRC24_RFC2440, "foo", "\x4f\xc2\x55" },
+      { GCRY_MD_CRC24_RFC2440, "123456789", "\x21\xcf\x02" },
+      { GCRY_MD_CRC24_RFC2440, "!", "\xa5\xcb\x6b" },
+      { GCRY_MD_CRC24_RFC2440, "?", "\x7f\x67\x03" },
 
       {        GCRY_MD_TIGER, "",
        "\x24\xF0\x13\x0C\x63\xAC\x93\x32\x16\x16\x6E\x76"
@@ -3939,6 +6498,20 @@ check_digests (void)
       {        GCRY_MD_TIGER1, "!",
        "\x6D\xB0\xE2\x72\x9C\xBE\xAD\x93\xD7\x15\xC6\xA7"
         "\xD3\x63\x02\xE9\xB3\xCE\xE0\xD2\xBC\x31\x4B\x41" },
+      { GCRY_MD_TIGER1,
+       "Libgcrypt is free software; you can redistribute it and/or modif"
+       "y it under the terms of the GNU Lesser general Public License as"
+       " published by the Free Software Foundation; either version 2.1 o"
+       "f the License, or (at your option) any later version.\nLibgcrypt"
+       " is distributed in the hope that it will be useful, but WITHOUT "
+       "ANY WARRANTY; without even the implied warranty of MERCHANTABILI"
+       "TY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser Gene"
+       "ral Public License for more details.",
+       "\x60\xee\xdf\x95\x39\xc8\x44\x94\x64\xdc\xdf\x3d\x2e\x1c\xe5\x79"
+       "\x6a\x95\xbd\x30\x68\x8c\x7e\xb8" },
+      {        GCRY_MD_TIGER1, "?",
+       "\x4b\xe2\x3f\x23\xf5\x34\xbe\xbf\x97\x42\x95\x80"
+       "\x54\xe4\x6c\x12\x64\x85\x44\x0a\xa9\x49\x9b\x65" },
 
       {        GCRY_MD_TIGER2, "",
         "\x44\x41\xBE\x75\xF6\x01\x87\x73\xC2\x06\xC2\x27"
@@ -3983,11 +6556,11 @@ check_digests (void)
        "\xF0\xDF\xF5\x94\x13\x14\x5E\x69\x73\xC4\x50\x01\xD0\x08\x7B\x42"
        "\xD1\x1B\xC6\x45\x41\x3A\xEF\xF6\x3A\x42\x39\x1A\x39\x14\x5A\x59"
        "\x1A\x92\x20\x0D\x56\x01\x95\xE5\x3B\x47\x85\x84\xFD\xAE\x23\x1A" },
-      { GCRY_MD_WHIRLPOOL, "a",
-       "\x8A\xCA\x26\x02\x79\x2A\xEC\x6F\x11\xA6\x72\x06\x53\x1F\xB7\xD7"
-       "\xF0\xDF\xF5\x94\x13\x14\x5E\x69\x73\xC4\x50\x01\xD0\x08\x7B\x42"
-       "\xD1\x1B\xC6\x45\x41\x3A\xEF\xF6\x3A\x42\x39\x1A\x39\x14\x5A\x59"
-       "\x1A\x92\x20\x0D\x56\x01\x95\xE5\x3B\x47\x85\x84\xFD\xAE\x23\x1A" },
+      { GCRY_MD_WHIRLPOOL, "?",
+       "\x88\xf0\x78\x6d\x0d\x47\xe5\x32\x1f\x88\xb1\x48\x05\x53\x58\x7d"
+       "\x19\x4b\x32\x9b\xf1\xfb\x17\xc5\x98\x3a\x87\xa2\x48\x61\x3d\x2b"
+       "\xb2\xbc\x9f\x0d\xd2\x14\x37\x30\x55\x30\x91\xa7\xb8\x0c\x0f\x80"
+       "\x7c\x7b\x94\xf6\x55\xf6\x0b\x12\x85\x0c\x8e\x6d\x17\x5b\x1e\x71" },
       { GCRY_MD_WHIRLPOOL,
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
        "\xDC\x37\xE0\x08\xCF\x9E\xE6\x9B\xF1\x1F\x00\xED\x9A\xBA\x26\x90"
@@ -4000,7 +6573,19 @@ check_digests (void)
         "\x29\x05\x7F\xD8\x6B\x20\xBF\xD6\x2D\xEC\xA0\xF1\xCC\xEA\x4A\xF5"
         "\x1F\xC1\x54\x90\xED\xDC\x47\xAF\x32\xBB\x2B\x66\xC3\x4F\xF9\xAD"
         "\x8C\x60\x08\xAD\x67\x7F\x77\x12\x69\x53\xB2\x26\xE4\xED\x8B\x01" },
-#ifdef USE_GOST_R_3411_94
+      { GCRY_MD_WHIRLPOOL,
+       "Libgcrypt is free software; you can redistribute it and/or modif"
+       "y it under the terms of the GNU Lesser general Public License as"
+       " published by the Free Software Foundation; either version 2.1 o"
+       "f the License, or (at your option) any later version.\nLibgcrypt"
+       " is distributed in the hope that it will be useful, but WITHOUT "
+       "ANY WARRANTY; without even the implied warranty of MERCHANTABILI"
+       "TY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser Gene"
+       "ral Public License for more details.",
+       "\xcd\x4a\xa4\xaf\xf6\x7f\xec\xce\xbb\x6c\xdf\x91\x96\xe1\xf3\xf6"
+       "\x78\xe2\x8e\x3a\x76\xcf\x06\xc7\xa1\x20\x7b\x81\x32\x60\xf7\x8e"
+       "\x68\x19\x62\x33\x4f\xe5\x0a\x24\xfb\x9e\x74\x03\x74\xe4\x61\x29"
+       "\x6f\xb3\x13\xe6\x7e\xc2\x88\x99\x9e\xfb\xe7\x9d\x11\x30\x89\xd2" },
       { GCRY_MD_GOSTR3411_94,
        "This is message, length=32 bytes",
        "\xB1\xC4\x66\xD3\x75\x19\xB8\x2E\x83\x19\x81\x9F\xF3\x25\x95\xE0"
@@ -4017,8 +6602,17 @@ check_digests (void)
        "!",
        "\x5C\x00\xCC\xC2\x73\x4C\xDD\x33\x32\xD3\xD4\x74\x95\x76\xE3\xC1"
        "\xA7\xDB\xAF\x0E\x7E\xA7\x4E\x9F\xA6\x02\x41\x3C\x90\xA1\x29\xFA" },
-#endif
-#ifdef USE_GOST_R_3411_12
+      { GCRY_MD_GOSTR3411_94,
+       "Libgcrypt is free software; you can redistribute it and/or modif"
+       "y it under the terms of the GNU Lesser general Public License as"
+       " published by the Free Software Foundation; either version 2.1 o"
+       "f the License, or (at your option) any later version.\nLibgcrypt"
+       " is distributed in the hope that it will be useful, but WITHOUT "
+       "ANY WARRANTY; without even the implied warranty of MERCHANTABILI"
+       "TY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser Gene"
+       "ral Public License for more details.",
+       "\x00\x0c\x85\xc8\x54\xd2\x9a\x6e\x47\x2e\xff\xa4\xa2\xe7\xd0\x2e"
+       "\x8a\xcc\x14\x53\xb4\x87\xc8\x5c\x95\x9a\x3e\x85\x8c\x7d\x6e\x0c" },
       { GCRY_MD_STRIBOG512,
         "012345678901234567890123456789012345678901234567890123456789012",
         "\x1b\x54\xd0\x1a\x4a\xf5\xb9\xd5\xcc\x3d\x86\xd6\x8d\x28\x54\x62"
@@ -4047,8 +6641,242 @@ check_digests (void)
         "\x20\xc8\xe3\xee\xf0\xe5\xe2\xfb",
         "\x9d\xd2\xfe\x4e\x90\x40\x9e\x5d\xa8\x7f\x53\x97\x6d\x74\x05\xb0"
         "\xc0\xca\xc6\x28\xfc\x66\x9a\x74\x1d\x50\x06\x3c\x55\x7e\x8f\x50" },
-#endif
-      {        0 }
+#include "./sha3-224.h"
+#include "./sha3-256.h"
+#include "./sha3-384.h"
+#include "./sha3-512.h"
+      { GCRY_MD_SHAKE128,
+       "",
+       "\x7F\x9C\x2B\xA4\xE8\x8F\x82\x7D\x61\x60\x45\x50\x76\x05\x85\x3E"
+       "\xD7\x3B\x80\x93\xF6\xEF\xBC\x88\xEB\x1A\x6E\xAC\xFA\x66\xEF\x26"
+       "\x3C\xB1\xEE\xA9\x88\x00\x4B\x93\x10\x3C\xFB\x0A\xEE\xFD\x2A\x68"
+       "\x6E\x01\xFA\x4A\x58\xE8\xA3\x63\x9C\xA8\xA1\xE3\xF9\xAE\x57\xE2"
+       "\x35\xB8\xCC\x87\x3C\x23\xDC\x62\xB8\xD2\x60\x16\x9A\xFA\x2F\x75"
+       "\xAB\x91\x6A\x58\xD9\x74\x91\x88\x35\xD2\x5E\x6A\x43\x50\x85\xB2"
+       "\xBA\xDF\xD6\xDF\xAA\xC3\x59\xA5\xEF\xBB\x7B\xCC\x4B\x59\xD5\x38"
+       "\xDF\x9A\x04\x30\x2E\x10\xC8\xBC\x1C\xBF\x1A\x0B\x3A\x51\x20\xEA"
+       "\x17\xCD\xA7\xCF\xAD\x76\x5F\x56\x23\x47\x4D\x36\x8C\xCC\xA8\xAF"
+       "\x00\x07\xCD\x9F\x5E\x4C\x84\x9F\x16\x7A\x58\x0B\x14\xAA\xBD\xEF"
+       "\xAE\xE7\xEE\xF4\x7C\xB0\xFC\xA9\x76\x7B\xE1\xFD\xA6\x94\x19\xDF"
+       "\xB9\x27\xE9\xDF\x07\x34\x8B\x19\x66\x91\xAB\xAE\xB5\x80\xB3\x2D"
+       "\xEF\x58\x53\x8B\x8D\x23\xF8\x77\x32\xEA\x63\xB0\x2B\x4F\xA0\xF4"
+       "\x87\x33\x60\xE2\x84\x19\x28\xCD\x60\xDD\x4C\xEE\x8C\xC0\xD4\xC9"
+       "\x22\xA9\x61\x88\xD0\x32\x67\x5C\x8A\xC8\x50\x93\x3C\x7A\xFF\x15"
+       "\x33\xB9\x4C\x83\x4A\xDB\xB6\x9C\x61\x15\xBA\xD4\x69\x2D\x86\x19"
+       "\xF9\x0B\x0C\xDF\x8A\x7B\x9C\x26\x40\x29\xAC\x18\x5B\x70\xB8\x3F"
+       "\x28\x01\xF2\xF4\xB3\xF7\x0C\x59\x3E\xA3\xAE\xEB\x61\x3A\x7F\x1B"
+       "\x1D\xE3\x3F\xD7\x50\x81\xF5\x92\x30\x5F\x2E\x45\x26\xED\xC0\x96"
+       "\x31\xB1\x09\x58\xF4\x64\xD8\x89\xF3\x1B\xA0\x10\x25\x0F\xDA\x7F"
+       "\x13\x68\xEC\x29\x67\xFC\x84\xEF\x2A\xE9\xAF\xF2\x68\xE0\xB1\x70"
+       "\x0A\xFF\xC6\x82\x0B\x52\x3A\x3D\x91\x71\x35\xF2\xDF\xF2\xEE\x06"
+       "\xBF\xE7\x2B\x31\x24\x72\x1D\x4A\x26\xC0\x4E\x53\xA7\x5E\x30\xE7"
+       "\x3A\x7A\x9C\x4A\x95\xD9\x1C\x55\xD4\x95\xE9\xF5\x1D\xD0\xB5\xE9"
+       "\xD8\x3C\x6D\x5E\x8C\xE8\x03\xAA\x62\xB8\xD6\x54\xDB\x53\xD0\x9B"
+       "\x8D\xCF\xF2\x73\xCD\xFE\xB5\x73\xFA\xD8\xBC\xD4\x55\x78\xBE\xC2"
+       "\xE7\x70\xD0\x1E\xFD\xE8\x6E\x72\x1A\x3F\x7C\x6C\xCE\x27\x5D\xAB"
+       "\xE6\xE2\x14\x3F\x1A\xF1\x8D\xA7\xEF\xDD\xC4\xC7\xB7\x0B\x5E\x34"
+       "\x5D\xB9\x3C\xC9\x36\xBE\xA3\x23\x49\x1C\xCB\x38\xA3\x88\xF5\x46"
+       "\xA9\xFF\x00\xDD\x4E\x13\x00\xB9\xB2\x15\x3D\x20\x41\xD2\x05\xB4"
+       "\x43\xE4\x1B\x45\xA6\x53\xF2\xA5\xC4\x49\x2C\x1A\xDD\x54\x45\x12"
+       "\xDD\xA2\x52\x98\x33\x46\x2B\x71\xA4\x1A\x45\xBE\x97\x29\x0B\x6F",
+       0, 512, },
+      { GCRY_MD_SHAKE128,
+       "\x5A\xAB\x62\x75\x6D\x30\x7A\x66\x9D\x14\x6A\xBA\x98\x8D\x90\x74"
+       "\xC5\xA1\x59\xB3\xDE\x85\x15\x1A\x81\x9B\x11\x7C\xA1\xFF\x65\x97"
+       "\xF6\x15\x6E\x80\xFD\xD2\x8C\x9C\x31\x76\x83\x51\x64\xD3\x7D\xA7"
+       "\xDA\x11\xD9\x4E\x09\xAD\xD7\x70\xB6\x8A\x6E\x08\x1C\xD2\x2C\xA0"
+       "\xC0\x04\xBF\xE7\xCD\x28\x3B\xF4\x3A\x58\x8D\xA9\x1F\x50\x9B\x27"
+       "\xA6\x58\x4C\x47\x4A\x4A\x2F\x3E\xE0\xF1\xF5\x64\x47\x37\x92\x40"
+       "\xA5\xAB\x1F\xB7\x7F\xDC\xA4\x9B\x30\x5F\x07\xBA\x86\xB6\x27\x56"
+       "\xFB\x9E\xFB\x4F\xC2\x25\xC8\x68\x45\xF0\x26\xEA\x54\x20\x76\xB9"
+       "\x1A\x0B\xC2\xCD\xD1\x36\xE1\x22\xC6\x59\xBE\x25\x9D\x98\xE5\x84"
+       "\x1D\xF4\xC2\xF6\x03\x30\xD4\xD8\xCD\xEE\x7B\xF1\xA0\xA2\x44\x52"
+       "\x4E\xEC\xC6\x8F\xF2\xAE\xF5\xBF\x00\x69\xC9\xE8\x7A\x11\xC6\xE5"
+       "\x19\xDE\x1A\x40\x62\xA1\x0C\x83\x83\x73\x88\xF7\xEF\x58\x59\x8A"
+       "\x38\x46\xF4\x9D\x49\x96\x82\xB6\x83\xC4\xA0\x62\xB4\x21\x59\x4F"
+       "\xAF\xBC\x13\x83\xC9\x43\xBA\x83\xBD\xEF\x51\x5E\xFC\xF1\x0D",
+       "\xF0\x71\x5D\xE3\x56\x92\xFD\x70\x12\x3D\xC6\x83\x68\xD0\xFE\xEC"
+       "\x06\xA0\xC7\x4C\xF8\xAD\xB0\x5D\xDC\x25\x54\x87\xB1\xA8\xD4\xD1"
+       "\x21\x3E\x9E\xAB\xAF\x41\xF1\x16\x17\x19\xD0\x65\xD7\x94\xB7\x50"
+       "\xF8\x4B\xE3\x2A\x32\x34\xB4\xD5\x36\x46\x0D\x55\x20\x68\x8A\x5A"
+       "\x79\xA1\x7A\x4B\xA8\x98\x7F\xCB\x61\xBF\x7D\xAA\x8B\x54\x7B\xF5"
+       "\xC1\xCE\x36\xB5\x6A\x73\x25\x7D\xBB\xF1\xBA\xBB\x64\xF2\x49\xBD"
+       "\xCE\xB6\x7B\xA1\xC8\x88\x37\x0A\x96\x3D\xFD\x6B\x6A\x2A\xDE\x2C"
+       "\xEF\xD1\x4C\x32\x52\xCB\x37\x58\x52\x0F\x0C\x65\xF4\x52\x46\x82"
+       "\x77\x24\x99\x46\x3A\xE1\xA3\x41\x80\x01\x83\xAA\x60\xEF\xA0\x51"
+       "\x18\xA2\x82\x01\x74\x4F\x7B\xA0\xB0\xA3\x92\x8D\xD7\xC0\x26\x3F"
+       "\xD2\x64\xB7\xCD\x7B\x2E\x2E\x09\xB3\x22\xBF\xCE\xA8\xEE\xD0\x42"
+       "\x75\x79\x5B\xE7\xC0\xF0\x0E\x11\x38\x27\x37\x0D\x05\x1D\x50\x26"
+       "\x95\x80\x30\x00\x05\xAC\x12\x88\xFE\xA6\xCD\x9A\xE9\xF4\xF3\x7C"
+       "\xE0\xF8\xAC\xE8\xBF\x3E\xBE\x1D\x70\x56\x25\x59\x54\xC7\x61\x93"
+       "\x1D\x3C\x42\xED\x62\xF7\xF1\xCE\x1B\x94\x5C\xDE\xCC\x0A\x74\x32"
+       "\x2D\x7F\x64\xD6\x00\x4F\xF2\x16\x84\x14\x93\x07\x28\x8B\x44\x8E"
+       "\x45\x43\x34\x75\xB1\xEA\x13\x14\xB0\x0F\x1F\xC4\x50\x08\x9A\x9D"
+       "\x1F\x77\x10\xC6\xD7\x65\x2E\xCF\x65\x4F\x3B\x48\x7D\x02\x83\xD4"
+       "\xD8\xA2\x8E\xFB\x50\x66\xC4\x25\x0D\x5A\xD6\x98\xE1\x5D\xBA\x88"
+       "\xE9\x25\xE4\xDE\x99\xB6\x9B\xC3\x83\xAC\x80\x45\xB7\xF1\x02\x2A"
+       "\xDD\x39\xD4\x43\x54\x6A\xE0\x92\x4F\x13\xF4\x89\x60\x96\xDF\xDF"
+       "\x37\xCA\x72\x20\x79\x87\xC4\xA7\x70\x5A\x7A\xBE\x72\x4B\x7F\xA1"
+       "\x0C\x90\x9F\x39\x25\x44\x9F\x01\x0D\x61\xE2\x07\xAD\xD9\x52\x19"
+       "\x07\x1A\xCE\xED\xB9\xB9\xDC\xED\x32\xA9\xE1\x23\x56\x1D\x60\x82"
+       "\xD4\x6A\xEF\xAE\x07\xEE\x1B\xD1\x32\x76\x5E\x3E\x51\x3C\x66\x50"
+       "\x1B\x38\x7A\xB2\xEE\x09\xA0\x4A\xE6\x3E\x25\x80\x85\x17\xAF\xEA"
+       "\x3E\x05\x11\x69\xCF\xD2\xFF\xF8\xC5\x85\x8E\x2D\x96\x23\x89\x7C"
+       "\x9E\x85\x17\x5A\xC5\xA8\x63\x94\xCD\x0A\x32\xA0\xA6\x2A\x8F\x5D"
+       "\x6C\xCC\xBF\x49\x3D\xAA\x43\xF7\x83\x62\xBB\xCA\x40\xAD\xF7\x33"
+       "\xF8\x71\xE0\xC0\x09\x98\xD9\xBF\xD6\x88\x06\x56\x66\x6C\xD7\xBE"
+       "\x4F\xE9\x89\x2C\x61\xDC\xD5\xCD\x23\xA5\xE4\x27\x7E\xEE\x8B\x4A"
+       "\xFD\x29\xB6\x9B\xBA\x55\x66\x0A\x21\x71\x12\xFF\x6E\x34\x56\xB1",
+       223, 512, },
+      { GCRY_MD_SHAKE128,
+       "!",
+       "\x9d\x22\x2c\x79\xc4\xff\x9d\x09\x2c\xf6\xca\x86\x14\x3a\xa4\x11"
+       "\xe3\x69\x97\x38\x08\xef\x97\x09\x32\x55\x82\x6c\x55\x72\xef\x58"
+       "\x42\x4c\x4b\x5c\x28\x47\x5f\xfd\xcf\x98\x16\x63\x86\x7f\xec\x63"
+       "\x21\xc1\x26\x2e\x38\x7b\xcc\xf8\xca\x67\x68\x84\xc4\xa9\xd0\xc1"
+       "\x3b\xfa\x68\x69\x76\x3d\x5a\xe4\xbb\xc9\xb3\xcc\xd0\x9d\x1c\xa5"
+       "\xea\x74\x46\x53\x8d\x69\xb3\xfb\x98\xc7\x2b\x59\xa2\xb4\x81\x7d"
+       "\xb5\xea\xdd\x90\x11\xf9\x0f\xa7\x10\x91\x93\x1f\x81\x34\xf4\xf0"
+       "\x0b\x56\x2e\x2f\xe1\x05\x93\x72\x70\x36\x1c\x19\x09\x86\x2a\xd4"
+       "\x50\x46\xe3\x93\x2f\x5d\xd3\x11\xec\x72\xfe\xc5\xf8\xfb\x8f\x60"
+       "\xb4\x5a\x3b\xee\x3f\x85\xbb\xf7\xfc\xed\xc6\xa5\x55\x67\x76\x48"
+       "\xe0\x65\x4b\x38\x19\x41\xa8\x6b\xd3\xe5\x12\x65\x7b\x0d\x57\xa7"
+       "\x99\x1f\xc4\x54\x3f\x89\xd8\x29\x04\x92\x22\x2c\xe4\xa3\x3e\x17"
+       "\x60\x2b\x3b\x99\xc0\x09\xf7\x65\x5f\x87\x53\x5c\xda\xa3\x71\x6f"
+       "\x58\xc4\x7b\x8a\x15\x7a\xd1\x95\xf0\x28\x09\xf2\x75\x00\xb9\x25"
+       "\x49\x79\x31\x1c\x6b\xb4\x15\x96\x8c\xd1\x04\x31\x16\x9a\x27\xd5"
+       "\xa8\xd6\x1e\x13\xa6\xb8\xb7\x7a\xf1\xf8\xb6\xdd\x2e\xef\xde\xa0"
+       "\x40\x78\x96\x80\x49\x0b\x5e\xdc\xb1\xd3\xe5\x38\xa4\x66\xf7\x57"
+       "\xad\x71\x8f\xe1\xfd\x9f\xae\xef\xa4\x72\x46\xad\x5e\x36\x7f\x87"
+       "\xd3\xb4\x85\x0d\x44\x86\xeb\x21\x99\xe9\x4a\x79\x79\xe2\x09\x1a"
+       "\xbc\xdf\x3b\xc1\x33\x79\xc8\x96\xdc\xeb\x79\xa8\xfd\x08\xf1\x10"
+       "\x73\xf3\x3e\x3f\x99\x23\x22\xb3\x12\x02\xde\xe2\x34\x33\x0c\xf3"
+       "\x30\x4a\x58\x8f\x0d\x59\xda\xe4\xe6\x3b\xa2\xac\x3c\xe6\x82\xcc"
+       "\x19\xd4\xe3\x41\x67\x8c\xc3\xa6\x7a\x47\xc1\x13\xb4\xdb\x89\x0f"
+       "\x30\xa9\x2a\xa0\x8a\x1f\x6d\xc8\xfb\x64\x63\xf8\x03\x8c\x2b\x40"
+       "\xb2\x53\x00\x77\xb2\x36\xce\x88\xaf\xcc\xcd\xa0\x8a\xd6\xd7\x5e"
+       "\xee\x18\x99\xb1\x0c\xd8\x00\xc2\xce\x53\x72\xbf\xf2\x2e\xe3\xa3"
+       "\x39\xd4\xb9\xc1\xa2\xf5\xf4\xb8\x20\xf6\x87\xe5\x51\x9b\xd0\x5b"
+       "\x1f\xc5\xda\x0e\xb4\x53\x36\x81\x4f\x48\x13\x2c\x64\x0e\x66\xc3"
+       "\xa0\x2a\x22\xe6\x35\x98\xf9\x4f\x22\xf3\x51\x84\x11\x04\x46\xb6"
+       "\x48\xcf\x84\x74\xf3\x0c\x43\xea\xd5\x83\x09\xfb\x25\x90\x16\x09"
+       "\xe2\x41\x87\xe8\x01\xc8\x09\x56\x1a\x64\x80\x94\x50\xe6\x03\xc4"
+       "\xa8\x03\x95\x25\xc4\x76\xb5\x8e\x32\xce\x2c\x47\xb3\x7d\xa5\x91",
+       0, 512, },
+      { GCRY_MD_SHAKE256,
+       "",
+       "\x46\xB9\xDD\x2B\x0B\xA8\x8D\x13\x23\x3B\x3F\xEB\x74\x3E\xEB\x24"
+       "\x3F\xCD\x52\xEA\x62\xB8\x1B\x82\xB5\x0C\x27\x64\x6E\xD5\x76\x2F"
+       "\xD7\x5D\xC4\xDD\xD8\xC0\xF2\x00\xCB\x05\x01\x9D\x67\xB5\x92\xF6"
+       "\xFC\x82\x1C\x49\x47\x9A\xB4\x86\x40\x29\x2E\xAC\xB3\xB7\xC4\xBE"
+       "\x14\x1E\x96\x61\x6F\xB1\x39\x57\x69\x2C\xC7\xED\xD0\xB4\x5A\xE3"
+       "\xDC\x07\x22\x3C\x8E\x92\x93\x7B\xEF\x84\xBC\x0E\xAB\x86\x28\x53"
+       "\x34\x9E\xC7\x55\x46\xF5\x8F\xB7\xC2\x77\x5C\x38\x46\x2C\x50\x10"
+       "\xD8\x46\xC1\x85\xC1\x51\x11\xE5\x95\x52\x2A\x6B\xCD\x16\xCF\x86"
+       "\xF3\xD1\x22\x10\x9E\x3B\x1F\xDD\x94\x3B\x6A\xEC\x46\x8A\x2D\x62"
+       "\x1A\x7C\x06\xC6\xA9\x57\xC6\x2B\x54\xDA\xFC\x3B\xE8\x75\x67\xD6"
+       "\x77\x23\x13\x95\xF6\x14\x72\x93\xB6\x8C\xEA\xB7\xA9\xE0\xC5\x8D"
+       "\x86\x4E\x8E\xFD\xE4\xE1\xB9\xA4\x6C\xBE\x85\x47\x13\x67\x2F\x5C"
+       "\xAA\xAE\x31\x4E\xD9\x08\x3D\xAB\x4B\x09\x9F\x8E\x30\x0F\x01\xB8"
+       "\x65\x0F\x1F\x4B\x1D\x8F\xCF\x3F\x3C\xB5\x3F\xB8\xE9\xEB\x2E\xA2"
+       "\x03\xBD\xC9\x70\xF5\x0A\xE5\x54\x28\xA9\x1F\x7F\x53\xAC\x26\x6B"
+       "\x28\x41\x9C\x37\x78\xA1\x5F\xD2\x48\xD3\x39\xED\xE7\x85\xFB\x7F"
+       "\x5A\x1A\xAA\x96\xD3\x13\xEA\xCC\x89\x09\x36\xC1\x73\xCD\xCD\x0F"
+       "\xAB\x88\x2C\x45\x75\x5F\xEB\x3A\xED\x96\xD4\x77\xFF\x96\x39\x0B"
+       "\xF9\xA6\x6D\x13\x68\xB2\x08\xE2\x1F\x7C\x10\xD0\x4A\x3D\xBD\x4E"
+       "\x36\x06\x33\xE5\xDB\x4B\x60\x26\x01\xC1\x4C\xEA\x73\x7D\xB3\xDC"
+       "\xF7\x22\x63\x2C\xC7\x78\x51\xCB\xDD\xE2\xAA\xF0\xA3\x3A\x07\xB3"
+       "\x73\x44\x5D\xF4\x90\xCC\x8F\xC1\xE4\x16\x0F\xF1\x18\x37\x8F\x11"
+       "\xF0\x47\x7D\xE0\x55\xA8\x1A\x9E\xDA\x57\xA4\xA2\xCF\xB0\xC8\x39"
+       "\x29\xD3\x10\x91\x2F\x72\x9E\xC6\xCF\xA3\x6C\x6A\xC6\xA7\x58\x37"
+       "\x14\x30\x45\xD7\x91\xCC\x85\xEF\xF5\xB2\x19\x32\xF2\x38\x61\xBC"
+       "\xF2\x3A\x52\xB5\xDA\x67\xEA\xF7\xBA\xAE\x0F\x5F\xB1\x36\x9D\xB7"
+       "\x8F\x3A\xC4\x5F\x8C\x4A\xC5\x67\x1D\x85\x73\x5C\xDD\xDB\x09\xD2"
+       "\xB1\xE3\x4A\x1F\xC0\x66\xFF\x4A\x16\x2C\xB2\x63\xD6\x54\x12\x74"
+       "\xAE\x2F\xCC\x86\x5F\x61\x8A\xBE\x27\xC1\x24\xCD\x8B\x07\x4C\xCD"
+       "\x51\x63\x01\xB9\x18\x75\x82\x4D\x09\x95\x8F\x34\x1E\xF2\x74\xBD"
+       "\xAB\x0B\xAE\x31\x63\x39\x89\x43\x04\xE3\x58\x77\xB0\xC2\x8A\x9B"
+       "\x1F\xD1\x66\xC7\x96\xB9\xCC\x25\x8A\x06\x4A\x8F\x57\xE2\x7F\x2A",
+       0, 512, },
+      { GCRY_MD_SHAKE256,
+       "\xB3\x2D\x95\xB0\xB9\xAA\xD2\xA8\x81\x6D\xE6\xD0\x6D\x1F\x86\x00"
+       "\x85\x05\xBD\x8C\x14\x12\x4F\x6E\x9A\x16\x3B\x5A\x2A\xDE\x55\xF8"
+       "\x35\xD0\xEC\x38\x80\xEF\x50\x70\x0D\x3B\x25\xE4\x2C\xC0\xAF\x05"
+       "\x0C\xCD\x1B\xE5\xE5\x55\xB2\x30\x87\xE0\x4D\x7B\xF9\x81\x36\x22"
+       "\x78\x0C\x73\x13\xA1\x95\x4F\x87\x40\xB6\xEE\x2D\x3F\x71\xF7\x68"
+       "\xDD\x41\x7F\x52\x04\x82\xBD\x3A\x08\xD4\xF2\x22\xB4\xEE\x9D\xBD"
+       "\x01\x54\x47\xB3\x35\x07\xDD\x50\xF3\xAB\x42\x47\xC5\xDE\x9A\x8A"
+       "\xBD\x62\xA8\xDE\xCE\xA0\x1E\x3B\x87\xC8\xB9\x27\xF5\xB0\x8B\xEB"
+       "\x37\x67\x4C\x6F\x8E\x38\x0C\x04",
+       "\xCC\x2E\xAA\x04\xEE\xF8\x47\x9C\xDA\xE8\x56\x6E\xB8\xFF\xA1\x10"
+       "\x0A\x40\x79\x95\xBF\x99\x9A\xE9\x7E\xDE\x52\x66\x81\xDC\x34\x90"
+       "\x61\x6F\x28\x44\x2D\x20\xDA\x92\x12\x4C\xE0\x81\x58\x8B\x81\x49"
+       "\x1A\xED\xF6\x5C\xAA\xF0\xD2\x7E\x82\xA4\xB0\xE1\xD1\xCA\xB2\x38"
+       "\x33\x32\x8F\x1B\x8D\xA4\x30\xC8\xA0\x87\x66\xA8\x63\x70\xFA\x84"
+       "\x8A\x79\xB5\x99\x8D\xB3\xCF\xFD\x05\x7B\x96\xE1\xE2\xEE\x0E\xF2"
+       "\x29\xEC\xA1\x33\xC1\x55\x48\xF9\x83\x99\x02\x04\x37\x30\xE4\x4B"
+       "\xC5\x2C\x39\xFA\xDC\x1D\xDE\xEA\xD9\x5F\x99\x39\xF2\x20\xCA\x30"
+       "\x06\x61\x54\x0D\xF7\xED\xD9\xAF\x37\x8A\x5D\x4A\x19\xB2\xB9\x3E"
+       "\x6C\x78\xF4\x9C\x35\x33\x43\xA0\xB5\xF1\x19\x13\x2B\x53\x12\xD0"
+       "\x04\x83\x1D\x01\x76\x9A\x31\x6D\x2F\x51\xBF\x64\xCC\xB2\x0A\x21"
+       "\xC2\xCF\x7A\xC8\xFB\x6F\x6E\x90\x70\x61\x26\xBD\xAE\x06\x11\xDD"
+       "\x13\x96\x2E\x8B\x53\xD6\xEA\xE2\x6C\x7B\x0D\x25\x51\xDA\xF6\x24"
+       "\x8E\x9D\x65\x81\x73\x82\xB0\x4D\x23\x39\x2D\x10\x8E\x4D\x34\x43"
+       "\xDE\x5A\xDC\x72\x73\xC7\x21\xA8\xF8\x32\x0E\xCF\xE8\x17\x7A\xC0"
+       "\x67\xCA\x8A\x50\x16\x9A\x6E\x73\x00\x0E\xBC\xDC\x1E\x4E\xE6\x33"
+       "\x9F\xC8\x67\xC3\xD7\xAE\xAB\x84\x14\x63\x98\xD7\xBA\xDE\x12\x1D"
+       "\x19\x89\xFA\x45\x73\x35\x56\x4E\x97\x57\x70\xA3\xA0\x02\x59\xCA"
+       "\x08\x70\x61\x08\x26\x1A\xA2\xD3\x4D\xE0\x0F\x8C\xAC\x7D\x45\xD3"
+       "\x5E\x5A\xA6\x3E\xA6\x9E\x1D\x1A\x2F\x7D\xAB\x39\x00\xD5\x1E\x0B"
+       "\xC6\x53\x48\xA2\x55\x54\x00\x70\x39\xA5\x2C\x3C\x30\x99\x80\xD1"
+       "\x7C\xAD\x20\xF1\x15\x63\x10\xA3\x9C\xD3\x93\x76\x0C\xFE\x58\xF6"
+       "\xF8\xAD\xE4\x21\x31\x28\x82\x80\xA3\x5E\x1D\xB8\x70\x81\x83\xB9"
+       "\x1C\xFA\xF5\x82\x7E\x96\xB0\xF7\x74\xC4\x50\x93\xB4\x17\xAF\xF9"
+       "\xDD\x64\x17\xE5\x99\x64\xA0\x1B\xD2\xA6\x12\xFF\xCF\xBA\x18\xA0"
+       "\xF1\x93\xDB\x29\x7B\x9A\x6C\xC1\xD2\x70\xD9\x7A\xAE\x8F\x8A\x3A"
+       "\x6B\x26\x69\x5A\xB6\x64\x31\xC2\x02\xE1\x39\xD6\x3D\xD3\xA2\x47"
+       "\x78\x67\x6C\xEF\xE3\xE2\x1B\x02\xEC\x4E\x8F\x5C\xFD\x66\x58\x7A"
+       "\x12\xB4\x40\x78\xFC\xD3\x9E\xEE\x44\xBB\xEF\x4A\x94\x9A\x63\xC0"
+       "\xDF\xD5\x8C\xF2\xFB\x2C\xD5\xF0\x02\xE2\xB0\x21\x92\x66\xCF\xC0"
+       "\x31\x81\x74\x86\xDE\x70\xB4\x28\x5A\x8A\x70\xF3\xD3\x8A\x61\xD3"
+       "\x15\x5D\x99\xAA\xF4\xC2\x53\x90\xD7\x36\x45\xAB\x3E\x8D\x80\xF0",
+       136, 512, },
+      { GCRY_MD_SHAKE256,
+       "!",
+       "\x35\x78\xa7\xa4\xca\x91\x37\x56\x9c\xdf\x76\xed\x61\x7d\x31\xbb"
+       "\x99\x4f\xca\x9c\x1b\xbf\x8b\x18\x40\x13\xde\x82\x34\xdf\xd1\x3a"
+       "\x3f\xd1\x24\xd4\xdf\x76\xc0\xa5\x39\xee\x7d\xd2\xf6\xe1\xec\x34"
+       "\x61\x24\xc8\x15\xd9\x41\x0e\x14\x5e\xb5\x61\xbc\xd9\x7b\x18\xab"
+       "\x6c\xe8\xd5\x55\x3e\x0e\xab\x3d\x1f\x7d\xfb\x8f\x9d\xee\xfe\x16"
+       "\x84\x7e\x21\x92\xf6\xf6\x1f\xb8\x2f\xb9\x0d\xde\x60\xb1\x90\x63"
+       "\xc5\x6a\x4c\x55\xcd\xd7\xb6\x72\xb7\x5b\xf5\x15\xad\xbf\xe2\x04"
+       "\x90\x3c\x8c\x00\x36\xde\x54\xa2\x99\x9a\x92\x0d\xe9\x0f\x66\xd7"
+       "\xff\x6e\xc8\xe4\xc9\x3d\x24\xae\x34\x6f\xdc\xb3\xa5\xa5\xbd\x57"
+       "\x39\xec\x15\xa6\xed\xdb\x5c\xe5\xb0\x2d\xa5\x30\x39\xfa\xc6\x3e"
+       "\x19\x55\x5f\xaa\x2e\xdd\xc6\x93\xb1\xf0\xc2\xa6\xfc\xbe\x7c\x0a"
+       "\x0a\x09\x1d\x0e\xe7\x00\xd7\x32\x2e\x4b\x0f\xf0\x95\x90\xde\x16"
+       "\x64\x22\xf9\xea\xd5\xda\x4c\x99\x3d\x60\x5f\xe4\xd9\xc6\x34\x84"
+       "\x3a\xa1\x78\xb1\x76\x72\xc6\x56\x8c\x8a\x2e\x62\xab\xeb\xea\x2c"
+       "\x21\xc3\x02\xbd\x36\x6a\xd6\x98\x95\x9e\x1f\x6e\x43\x4a\xf1\x55"
+       "\x56\x8b\x27\x34\xd8\x37\x9f\xcd\x3f\xfe\x64\x89\xba\xff\xa6\xd7"
+       "\x11\x09\x44\x2e\x1b\x34\x4f\x13\x8a\x09\xca\xe3\xe2\xd3\x94\x2e"
+       "\xee\x82\x8f\xc4\x7e\x64\xde\xb5\xe0\x0a\x02\x4a\xe1\xf2\xc0\x77"
+       "\xe6\xb7\xb1\x33\xf6\xc1\xde\x91\x30\x92\xd4\xe8\x29\xec\xd2\xb2"
+       "\xef\x28\xca\x80\x20\x82\x1e\x2b\x8b\xe5\x17\xd9\x3e\xd0\x88\x36"
+       "\xf6\xf0\x66\xcc\x3d\x03\xb6\x25\xd8\x49\x7f\x29\xdb\xc1\xc3\x9e"
+       "\x6f\xe4\x63\x22\x6f\x85\xc1\x28\xa2\xc2\x98\x88\x11\x2e\x06\xa9"
+       "\x9c\x5d\x17\xb2\x5e\x90\x0d\x20\x4f\x39\x72\x31\xcd\xf7\x9c\x31"
+       "\x34\x46\x53\x2d\xad\x07\xf4\xc0\xbd\x9f\xba\x1d\xd4\x13\xd8\xa7"
+       "\xe6\xcb\xc0\xa0\x86\x2c\xc7\x69\x23\x9a\x89\xf9\xdb\x08\x5b\x78"
+       "\xa0\x54\x59\x6a\xd7\x08\x0d\xdf\x96\x01\x9b\x73\x99\xb5\x03\x48"
+       "\x0e\x5a\x65\xa2\x20\x8d\x74\x72\x4c\x98\x7d\x32\x5e\x9b\x0e\x82"
+       "\xfe\xcd\x4f\x27\xf3\x13\x5b\x1d\x9e\x27\xb4\x8e\x69\xdd\x6f\x59"
+       "\x62\xb8\xa6\x3b\x48\x92\x1e\xc8\xee\x53\x86\x9f\x1a\xc1\xc8\x18"
+       "\x23\x87\xee\x0d\x6c\xfe\xf6\x53\xff\x8b\xf6\x05\xf1\x47\x04\xb7"
+       "\x1b\xeb\x65\x53\xf2\x81\xfa\x75\x69\x48\xc4\x38\x49\x4b\x19\xb4"
+       "\xee\x69\xa5\x43\x6b\x22\x2b\xc9\x88\xed\xa4\xac\x60\x00\x24\xc9",
+       0, 512, },
+      { 0 }
     };
   gcry_error_t err;
   int i;
@@ -4058,8 +6886,12 @@ check_digests (void)
 
   for (i = 0; algos[i].md; i++)
     {
-      if ((gcry_md_test_algo (algos[i].md) || algos[i].md == GCRY_MD_MD5)
-          && in_fips_mode)
+      if (gcry_md_test_algo (algos[i].md))
+        {
+          show_md_not_available (algos[i].md);
+          continue;
+        }
+      if (gcry_md_test_algo (algos[i].md) && in_fips_mode)
         {
           if (verbose)
             fprintf (stderr, "  algorithm %d not available in fips mode\n",
@@ -4073,9 +6905,13 @@ check_digests (void)
                  !strcmp (algos[i].data, "!")?
                  1000000 : (int)strlen(algos[i].data));
 
-      check_one_md (algos[i].md, algos[i].data, strlen (algos[i].data),
-                   algos[i].expect);
-      check_one_md_multi (algos[i].md, algos[i].data, strlen (algos[i].data),
+      check_one_md (algos[i].md, algos[i].data,
+                   algos[i].datalen > 0 ? algos[i].datalen
+                                        : strlen (algos[i].data),
+                   algos[i].expect, algos[i].expectlen);
+      check_one_md_multi (algos[i].md, algos[i].data,
+                         algos[i].datalen > 0 ? algos[i].datalen
+                                              : strlen (algos[i].data),
                           algos[i].expect);
     }
 
@@ -4482,8 +7318,12 @@ check_hmac (void)
 
   for (i = 0; algos[i].md; i++)
     {
-      if ((gcry_md_test_algo (algos[i].md) || algos[i].md == GCRY_MD_MD5)
-          && in_fips_mode)
+      if (gcry_md_test_algo (algos[i].md))
+        {
+          show_old_hmac_not_available (algos[i].md);
+          continue;
+        }
+      if (gcry_md_test_algo (algos[i].md) && in_fips_mode)
         {
           if (verbose)
             fprintf (stderr, "  algorithm %d not available in fips mode\n",
@@ -4526,6 +7366,12 @@ check_one_mac (int algo, const char *data, int datalen,
       return;
     }
 
+  i = gcry_mac_get_algo (hd);
+  if (i != algo)
+    {
+      fail ("algo %d, gcry_mac_get_algo failed: %d\n", algo, i);
+    }
+
   maclen = gcry_mac_get_algo_maclen (algo);
   if (maclen < 1 || maclen > 500)
     {
@@ -4620,6 +7466,8 @@ check_mac (void)
     const char *key;
     const char *expect;
     const char *iv;
+    unsigned int dlen;
+    unsigned int klen;
   } algos[] =
     {
       { GCRY_MAC_HMAC_MD5, "what do ya want for nothing?", "Jefe",
@@ -4893,6 +7741,169 @@ check_mac (void)
         "\xde\xbd\x71\xf8\x86\x72\x89\x86\x5d\xf5\xa3\x2d\x20\xcd\xc9\x44"
         "\xb6\x02\x2c\xac\x3c\x49\x82\xb1\x0d\x5e\xeb\x55\xc3\xe4\xde\x15"
         "\x13\x46\x76\xfb\x6d\xe0\x44\x60\x65\xc9\x74\x40\xfa\x8c\x6a\x58" },
+      /* HMAC-SHA3 test vectors from
+       * http://wolfgang-ehrhardt.de/hmac-sha3-testvectors.html */
+      { GCRY_MAC_HMAC_SHA3_224,
+       "Hi There",
+       "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+       "\x0b\x0b\x0b",
+       "\x3b\x16\x54\x6b\xbc\x7b\xe2\x70\x6a\x03\x1d\xca\xfd\x56\x37\x3d"
+       "\x98\x84\x36\x76\x41\xd8\xc5\x9a\xf3\xc8\x60\xf7" },
+      { GCRY_MAC_HMAC_SHA3_256,
+       "Hi There",
+       "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+       "\x0b\x0b\x0b",
+       "\xba\x85\x19\x23\x10\xdf\xfa\x96\xe2\xa3\xa4\x0e\x69\x77\x43\x51"
+       "\x14\x0b\xb7\x18\x5e\x12\x02\xcd\xcc\x91\x75\x89\xf9\x5e\x16\xbb" },
+      { GCRY_MAC_HMAC_SHA3_512,
+       "Hi There",
+       "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+       "\x0b\x0b\x0b",
+       "\xeb\x3f\xbd\x4b\x2e\xaa\xb8\xf5\xc5\x04\xbd\x3a\x41\x46\x5a\xac"
+       "\xec\x15\x77\x0a\x7c\xab\xac\x53\x1e\x48\x2f\x86\x0b\x5e\xc7\xba"
+       "\x47\xcc\xb2\xc6\xf2\xaf\xce\x8f\x88\xd2\x2b\x6d\xc6\x13\x80\xf2"
+       "\x3a\x66\x8f\xd3\x88\x8b\xb8\x05\x37\xc0\xa0\xb8\x64\x07\x68\x9e" },
+      { GCRY_MAC_HMAC_SHA3_224, "what do ya want for nothing?", "Jefe",
+       "\x7f\xdb\x8d\xd8\x8b\xd2\xf6\x0d\x1b\x79\x86\x34\xad\x38\x68\x11"
+       "\xc2\xcf\xc8\x5b\xfa\xf5\xd5\x2b\xba\xce\x5e\x66" },
+      { GCRY_MAC_HMAC_SHA3_256, "what do ya want for nothing?", "Jefe",
+       "\xc7\xd4\x07\x2e\x78\x88\x77\xae\x35\x96\xbb\xb0\xda\x73\xb8\x87"
+       "\xc9\x17\x1f\x93\x09\x5b\x29\x4a\xe8\x57\xfb\xe2\x64\x5e\x1b\xa5" },
+      { GCRY_MAC_HMAC_SHA3_384, "what do ya want for nothing?", "Jefe",
+       "\xf1\x10\x1f\x8c\xbf\x97\x66\xfd\x67\x64\xd2\xed\x61\x90\x3f\x21"
+       "\xca\x9b\x18\xf5\x7c\xf3\xe1\xa2\x3c\xa1\x35\x08\xa9\x32\x43\xce"
+       "\x48\xc0\x45\xdc\x00\x7f\x26\xa2\x1b\x3f\x5e\x0e\x9d\xf4\xc2\x0a" },
+      { GCRY_MAC_HMAC_SHA3_512, "what do ya want for nothing?", "Jefe",
+       "\x5a\x4b\xfe\xab\x61\x66\x42\x7c\x7a\x36\x47\xb7\x47\x29\x2b\x83"
+       "\x84\x53\x7c\xdb\x89\xaf\xb3\xbf\x56\x65\xe4\xc5\xe7\x09\x35\x0b"
+       "\x28\x7b\xae\xc9\x21\xfd\x7c\xa0\xee\x7a\x0c\x31\xd0\x22\xa9\x5e"
+       "\x1f\xc9\x2b\xa9\xd7\x7d\xf8\x83\x96\x02\x75\xbe\xb4\xe6\x20\x24" },
+      { GCRY_MAC_HMAC_SHA3_224,
+       "Test Using Larger Than Block-Size Key - Hash Key First",
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa",
+       "\xb9\x6d\x73\x0c\x14\x8c\x2d\xaa\xd8\x64\x9d\x83\xde\xfa\xa3\x71"
+       "\x97\x38\xd3\x47\x75\x39\x7b\x75\x71\xc3\x85\x15" },
+      { GCRY_MAC_HMAC_SHA3_256,
+       "Test Using Larger Than Block-Size Key - Hash Key First",
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa",
+       "\xa6\x07\x2f\x86\xde\x52\xb3\x8b\xb3\x49\xfe\x84\xcd\x6d\x97\xfb"
+       "\x6a\x37\xc4\xc0\xf6\x2a\xae\x93\x98\x11\x93\xa7\x22\x9d\x34\x67" },
+      { GCRY_MAC_HMAC_SHA3_384,
+       "Test Using Larger Than Block-Size Key - Hash Key First",
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa",
+       "\x71\x3d\xff\x03\x02\xc8\x50\x86\xec\x5a\xd0\x76\x8d\xd6\x5a\x13"
+       "\xdd\xd7\x90\x68\xd8\xd4\xc6\x21\x2b\x71\x2e\x41\x64\x94\x49\x11"
+       "\x14\x80\x23\x00\x44\x18\x5a\x99\x10\x3e\xd8\x20\x04\xdd\xbf\xcc" },
+      { GCRY_MAC_HMAC_SHA3_512,
+       "Test Using Larger Than Block-Size Key - Hash Key First",
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa",
+       "\xb1\x48\x35\xc8\x19\xa2\x90\xef\xb0\x10\xac\xe6\xd8\x56\x8d\xc6"
+       "\xb8\x4d\xe6\x0b\xc4\x9b\x00\x4c\x3b\x13\xed\xa7\x63\x58\x94\x51"
+       "\xe5\xdd\x74\x29\x28\x84\xd1\xbd\xce\x64\xe6\xb9\x19\xdd\x61\xdc"
+       "\x9c\x56\xa2\x82\xa8\x1c\x0b\xd1\x4f\x1f\x36\x5b\x49\xb8\x3a\x5b" },
+      { GCRY_MAC_HMAC_SHA3_224,
+       "This is a test using a larger than block-size key and a larger "
+       "than block-size data. The key needs to be hashed before being "
+       "used by the HMAC algorithm.",
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa",
+       "\xc7\x9c\x9b\x09\x34\x24\xe5\x88\xa9\x87\x8b\xbc\xb0\x89\xe0\x18"
+       "\x27\x00\x96\xe9\xb4\xb1\xa9\xe8\x22\x0c\x86\x6a" },
+      { GCRY_MAC_HMAC_SHA3_256,
+       "This is a test using a larger than block-size key and a larger "
+       "than block-size data. The key needs to be hashed before being "
+       "used by the HMAC algorithm.",
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa",
+       "\xe6\xa3\x6d\x9b\x91\x5f\x86\xa0\x93\xca\xc7\xd1\x10\xe9\xe0\x4c"
+       "\xf1\xd6\x10\x0d\x30\x47\x55\x09\xc2\x47\x5f\x57\x1b\x75\x8b\x5a" },
+      { GCRY_MAC_HMAC_SHA3_384,
+       "This is a test using a larger than block-size key and a larger "
+       "than block-size data. The key needs to be hashed before being "
+       "used by the HMAC algorithm.",
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa",
+       "\xca\xd1\x8a\x8f\xf6\xc4\xcc\x3a\xd4\x87\xb9\x5f\x97\x69\xe9\xb6"
+       "\x1c\x06\x2a\xef\xd6\x95\x25\x69\xe6\xe6\x42\x18\x97\x05\x4c\xfc"
+       "\x70\xb5\xfd\xc6\x60\x5c\x18\x45\x71\x12\xfc\x6a\xaa\xd4\x55\x85" },
+      { GCRY_MAC_HMAC_SHA3_512,
+       "This is a test using a larger than block-size key and a larger "
+       "than block-size data. The key needs to be hashed before being "
+       "used by the HMAC algorithm.",
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+       "\xaa\xaa\xaa",
+       "\xdc\x03\x0e\xe7\x88\x70\x34\xf3\x2c\xf4\x02\xdf\x34\x62\x2f\x31"
+       "\x1f\x3e\x6c\xf0\x48\x60\xc6\xbb\xd7\xfa\x48\x86\x74\x78\x2b\x46"
+       "\x59\xfd\xbd\xf3\xfd\x87\x78\x52\x88\x5c\xfe\x6e\x22\x18\x5f\xe7"
+       "\xb2\xee\x95\x20\x43\x62\x9b\xc9\xd5\xf3\x29\x8a\x41\xd0\x2c\x66" },
       /* CMAC AES and DES test vectors from
          http://web.archive.org/web/20130930212819/http://csrc.nist.gov/publica\
          tions/nistpubs/800-38B/Updated_CMAC_Examples.pdf */
@@ -5070,6 +8081,208 @@ check_mac (void)
         "\xc9\xfc\xa7\x29\xab\x60\xad\xa0",
         "\x20\x4b\xdb\x1b\xd6\x21\x54\xbf\x08\x92\x2a\xaa\x54\xee\xd7\x05",
         "\x05\xad\x13\xa5\xe2\xc2\xab\x66\x7e\x1a\x6f\xbc" },
+      /* from NaCl */
+      { GCRY_MAC_POLY1305,
+        "\x8e\x99\x3b\x9f\x48\x68\x12\x73\xc2\x96\x50\xba\x32\xfc\x76\xce"
+        "\x48\x33\x2e\xa7\x16\x4d\x96\xa4\x47\x6f\xb8\xc5\x31\xa1\x18\x6a"
+        "\xc0\xdf\xc1\x7c\x98\xdc\xe8\x7b\x4d\xa7\xf0\x11\xec\x48\xc9\x72"
+        "\x71\xd2\xc2\x0f\x9b\x92\x8f\xe2\x27\x0d\x6f\xb8\x63\xd5\x17\x38"
+        "\xb4\x8e\xee\xe3\x14\xa7\xcc\x8a\xb9\x32\x16\x45\x48\xe5\x26\xae"
+        "\x90\x22\x43\x68\x51\x7a\xcf\xea\xbd\x6b\xb3\x73\x2b\xc0\xe9\xda"
+        "\x99\x83\x2b\x61\xca\x01\xb6\xde\x56\x24\x4a\x9e\x88\xd5\xf9\xb3"
+        "\x79\x73\xf6\x22\xa4\x3d\x14\xa6\x59\x9b\x1f\x65\x4c\xb4\x5a\x74"
+        "\xe3\x55\xa5",
+        "\xee\xa6\xa7\x25\x1c\x1e\x72\x91\x6d\x11\xc2\xcb\x21\x4d\x3c\x25"
+        "\x25\x39\x12\x1d\x8e\x23\x4e\x65\x2d\x65\x1f\xa4\xc8\xcf\xf8\x80",
+        "\xf3\xff\xc7\x70\x3f\x94\x00\xe5\x2a\x7d\xfb\x4b\x3d\x33\x05\xd9" },
+      /* from draft-nir-cfrg-chacha20-poly1305-03 */
+      { GCRY_MAC_POLY1305,
+        "Cryptographic Forum Research Group",
+        "\x85\xd6\xbe\x78\x57\x55\x6d\x33\x7f\x44\x52\xfe\x42\xd5\x06\xa8"
+        "\x01\x03\x80\x8a\xfb\x0d\xb2\xfd\x4a\xbf\xf6\xaf\x41\x49\xf5\x1b",
+        "\xa8\x06\x1d\xc1\x30\x51\x36\xc6\xc2\x2b\x8b\xaf\x0c\x01\x27\xa9" },
+      { GCRY_MAC_POLY1305,
+        "'Twas brillig, and the slithy toves\n"
+        "Did gyre and gimble in the wabe:\n"
+        "All mimsy were the borogoves,\n"
+        "And the mome raths outgrabe.",
+        "\x1c\x92\x40\xa5\xeb\x55\xd3\x8a\xf3\x33\x88\x86\x04\xf6\xb5\xf0"
+        "\x47\x39\x17\xc1\x40\x2b\x80\x09\x9d\xca\x5c\xbc\x20\x70\x75\xc0",
+        "\x45\x41\x66\x9a\x7e\xaa\xee\x61\xe7\x08\xdc\x7c\xbc\xc5\xeb\x62" },
+      { GCRY_MAC_POLY1305,
+        "\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\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\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\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\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\x00\x00\x00\x00",
+        NULL,
+        191, 32 },
+      { GCRY_MAC_POLY1305,
+        "Any submission to the IETF intended by the Contributor for "
+        "publication as all or part of an IETF Internet-Draft or RFC and "
+        "any statement made within the context of an IETF activity is "
+        "considered an \"IETF Contribution\". Such statements include "
+        "oral statements in IETF sessions, as well as written and "
+        "electronic communications made at any time or place, which are "
+        "addressed to",
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x36\xe5\xf6\xb5\xc5\xe0\x60\x70\xf0\xef\xca\x96\x22\x7a\x86\x3e",
+        "\x36\xe5\xf6\xb5\xc5\xe0\x60\x70\xf0\xef\xca\x96\x22\x7a\x86\x3e",
+        NULL,
+        0, 32 },
+      { GCRY_MAC_POLY1305,
+        "Any submission to the IETF intended by the Contributor for "
+        "publication as all or part of an IETF Internet-Draft or RFC and "
+        "any statement made within the context of an IETF activity is "
+        "considered an \"IETF Contribution\". Such statements include "
+        "oral statements in IETF sessions, as well as written and "
+        "electronic communications made at any time or place, which are "
+        "addressed to",
+        "\x36\xe5\xf6\xb5\xc5\xe0\x60\x70\xf0\xef\xca\x96\x22\x7a\x86\x3e"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+        "\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",
+        "\x85\x1f\xc4\x0c\x34\x67\xac\x0b\xe0\x5c\xc2\x04\x04\xf3\xf7\x00"
+        "\x58\x0b\x3b\x0f\x94\x47\xbb\x1e\x69\xd0\x95\xb5\x92\x8b\x6d\xbc",
+        "\xf4\xc6\x33\xc3\x04\x4f\xc1\x45\xf8\x4f\x33\x5c\xb8\x19\x53\xde",
+        NULL,
+        0, 32 },
+      { GCRY_MAC_POLY1305,
+        "",
+        "\xa0\xf3\x08\x00\x00\xf4\x64\x00\xd0\xc7\xe9\x07\x6c\x83\x44\x03"
+        "\xdd\x3f\xab\x22\x51\xf1\x1a\xc7\x59\xf0\x88\x71\x29\xcc\x2e\xe7",
+        "\xdd\x3f\xab\x22\x51\xf1\x1a\xc7\x59\xf0\x88\x71\x29\xcc\x2e\xe7",
+        NULL,
+        0, 32 },
+      { GCRY_MAC_POLY1305,
+        "\x66\x3c\xea\x19\x0f\xfb\x83\xd8\x95\x93\xf3\xf4\x76\xb6\xbc\x24"
+        "\xd7\xe6\x79\x10\x7e\xa2\x6a\xdb\x8c\xaf\x66\x52\xd0\x65\x61\x36",
+        "\x48\x44\x3d\x0b\xb0\xd2\x11\x09\xc8\x9a\x10\x0b\x5c\xe2\xc2\x08"
+        "\x83\x14\x9c\x69\xb5\x61\xdd\x88\x29\x8a\x17\x98\xb1\x07\x16\xef",
+        "\x0e\xe1\xc1\x6b\xb7\x3f\x0f\x4f\xd1\x98\x81\x75\x3c\x01\xcd\xbe",
+        NULL,
+        0, 32 },
+      { GCRY_MAC_POLY1305,
+        "\xab\x08\x12\x72\x4a\x7f\x1e\x34\x27\x42\xcb\xed\x37\x4d\x94\xd1"
+        "\x36\xc6\xb8\x79\x5d\x45\xb3\x81\x98\x30\xf2\xc0\x44\x91\xfa\xf0"
+        "\x99\x0c\x62\xe4\x8b\x80\x18\xb2\xc3\xe4\xa0\xfa\x31\x34\xcb\x67"
+        "\xfa\x83\xe1\x58\xc9\x94\xd9\x61\xc4\xcb\x21\x09\x5c\x1b\xf9",
+        "\x12\x97\x6a\x08\xc4\x42\x6d\x0c\xe8\xa8\x24\x07\xc4\xf4\x82\x07"
+        "\x80\xf8\xc2\x0a\xa7\x12\x02\xd1\xe2\x91\x79\xcb\xcb\x55\x5a\x57",
+        "\x51\x54\xad\x0d\x2c\xb2\x6e\x01\x27\x4f\xc5\x11\x48\x49\x1f\x1b" },
+      /* from http://cr.yp.to/mac/poly1305-20050329.pdf */
+      { GCRY_MAC_POLY1305_AES,
+        "\xf3\xf6",
+        "\xec\x07\x4c\x83\x55\x80\x74\x17\x01\x42\x5b\x62\x32\x35\xad\xd6"
+        "\x85\x1f\xc4\x0c\x34\x67\xac\x0b\xe0\x5c\xc2\x04\x04\xf3\xf7\x00",
+        "\xf4\xc6\x33\xc3\x04\x4f\xc1\x45\xf8\x4f\x33\x5c\xb8\x19\x53\xde",
+        "\xfb\x44\x73\x50\xc4\xe8\x68\xc5\x2a\xc3\x27\x5c\xf9\xd4\x32\x7e",
+        0, 32 },
+      { GCRY_MAC_POLY1305_AES,
+        "",
+        "\x75\xde\xaa\x25\xc0\x9f\x20\x8e\x1d\xc4\xce\x6b\x5c\xad\x3f\xbf"
+        "\xa0\xf3\x08\x00\x00\xf4\x64\x00\xd0\xc7\xe9\x07\x6c\x83\x44\x03",
+        "\xdd\x3f\xab\x22\x51\xf1\x1a\xc7\x59\xf0\x88\x71\x29\xcc\x2e\xe7",
+        "\x61\xee\x09\x21\x8d\x29\xb0\xaa\xed\x7e\x15\x4a\x2c\x55\x09\xcc",
+        0, 32 },
+      { GCRY_MAC_POLY1305_AES,
+        "\x66\x3c\xea\x19\x0f\xfb\x83\xd8\x95\x93\xf3\xf4\x76\xb6\xbc\x24"
+        "\xd7\xe6\x79\x10\x7e\xa2\x6a\xdb\x8c\xaf\x66\x52\xd0\x65\x61\x36",
+        "\x6a\xcb\x5f\x61\xa7\x17\x6d\xd3\x20\xc5\xc1\xeb\x2e\xdc\xdc\x74"
+        "\x48\x44\x3d\x0b\xb0\xd2\x11\x09\xc8\x9a\x10\x0b\x5c\xe2\xc2\x08",
+        "\x0e\xe1\xc1\x6b\xb7\x3f\x0f\x4f\xd1\x98\x81\x75\x3c\x01\xcd\xbe",
+        "\xae\x21\x2a\x55\x39\x97\x29\x59\x5d\xea\x45\x8b\xc6\x21\xff\x0e",
+        0, 32 },
+      { GCRY_MAC_POLY1305_AES,
+        "\xab\x08\x12\x72\x4a\x7f\x1e\x34\x27\x42\xcb\xed\x37\x4d\x94\xd1"
+        "\x36\xc6\xb8\x79\x5d\x45\xb3\x81\x98\x30\xf2\xc0\x44\x91\xfa\xf0"
+        "\x99\x0c\x62\xe4\x8b\x80\x18\xb2\xc3\xe4\xa0\xfa\x31\x34\xcb\x67"
+        "\xfa\x83\xe1\x58\xc9\x94\xd9\x61\xc4\xcb\x21\x09\x5c\x1b\xf9",
+        "\xe1\xa5\x66\x8a\x4d\x5b\x66\xa5\xf6\x8c\xc5\x42\x4e\xd5\x98\x2d"
+        "\x12\x97\x6a\x08\xc4\x42\x6d\x0c\xe8\xa8\x24\x07\xc4\xf4\x82\x07",
+        "\x51\x54\xad\x0d\x2c\xb2\x6e\x01\x27\x4f\xc5\x11\x48\x49\x1f\x1b",
+       "\x9a\xe8\x31\xe7\x43\x97\x8d\x3a\x23\x52\x7c\x71\x28\x14\x9e\x3a",
+        0, 32 },
       { 0 },
     };
   int i;
@@ -5079,8 +8292,14 @@ check_mac (void)
 
   for (i = 0; algos[i].algo; i++)
     {
-      if ((gcry_mac_test_algo (algos[i].algo)
-          || algos[i].algo == GCRY_MAC_HMAC_MD5) && in_fips_mode)
+      size_t klen, dlen;
+
+      if (gcry_mac_test_algo (algos[i].algo))
+        {
+          show_mac_not_available (algos[i].algo);
+          continue;
+        }
+      if (gcry_mac_test_algo (algos[i].algo) && in_fips_mode)
         {
           if (verbose)
             fprintf (stderr, "  algorithm %d not available in fips mode\n",
@@ -5094,13 +8313,14 @@ check_mac (void)
                 algos[i].algo,
                 (int)strlen(algos[i].key), (int)strlen(algos[i].data));
 
-      check_one_mac (algos[i].algo, algos[i].data, strlen (algos[i].data),
-                    algos[i].key, strlen(algos[i].key), algos[i].iv,
-                    algos[i].iv ? strlen(algos[i].iv) : 0,
+      klen = algos[i].klen ? algos[i].klen : strlen(algos[i].key);
+      dlen = algos[i].dlen ? algos[i].dlen : strlen (algos[i].data);
+
+      check_one_mac (algos[i].algo, algos[i].data, dlen, algos[i].key, klen,
+                    algos[i].iv, algos[i].iv ? strlen(algos[i].iv) : 0,
                     algos[i].expect, 0);
-      check_one_mac (algos[i].algo, algos[i].data, strlen (algos[i].data),
-                    algos[i].key, strlen(algos[i].key), algos[i].iv,
-                    algos[i].iv ? strlen(algos[i].iv) : 0,
+      check_one_mac (algos[i].algo, algos[i].data, dlen, algos[i].key, klen,
+                    algos[i].iv, algos[i].iv ? strlen(algos[i].iv) : 0,
                     algos[i].expect, 1);
     }
 
@@ -5149,6 +8369,10 @@ check_pubkey_sign (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo)
        " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n",
        GCRY_PK_RSA,
        0 },
+      { "(data\n (flags pkcs1-raw)\n"
+       " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n",
+       GCRY_PK_RSA,
+       GPG_ERR_CONFLICT },
       { "(data\n (flags oaep)\n"
        " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n",
        0,
@@ -5181,6 +8405,10 @@ check_pubkey_sign (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo)
        " (value #11223344556677889900AA#))\n",
        GCRY_PK_RSA,
        GPG_ERR_CONFLICT },
+      { "(data\n (flags pkcs1-raw)\n"
+       " (value #11223344556677889900AA#))\n",
+       GCRY_PK_RSA,
+       0 },
       { "(data\n (flags raw foo)\n"
        " (value #11223344556677889900AA#))\n",
        0,
@@ -5651,7 +8879,7 @@ get_keys_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
   if (verbose)
     fprintf (stderr, "  generating RSA key:");
   rc = gcry_sexp_new (&key_spec,
-                     in_fips_mode ? "(genkey (rsa (nbits 4:1024)))"
+                     in_fips_mode ? "(genkey (rsa (nbits 4:2048)))"
                       : "(genkey (rsa (nbits 4:1024)(transient-key)))",
                       0, 1);
   if (rc)
@@ -5948,7 +9176,7 @@ check_pubkey (void)
 
       "(public-key\n"
       " (ecc\n"
-      "  (curve GOST2001-test)\n"
+      "  (curve GOST2012-test)\n"
       "  (q #04115DC5BC96760C7B48598D8AB9E740D4C4A85A65BE33C1"
       "        815B5C320C854621DD5A515856D13314AF69BC5B924C8B"
       "        4DDFF75C45415C1D9DD9DD33612CD530EFE137C7C90CD4"
@@ -5958,6 +9186,28 @@ check_pubkey (void)
 
       "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
       "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }
+  },
+  { /* secp256k1 test 256 bit.  */
+    GCRY_PK_ECDSA, FLAG_SIGN,
+    {
+      "(private-key\n"
+      " (ecc\n"
+      "  (curve secp256k1)\n"
+      "  (q #0439A36013301597DAEF41FBE593A02CC513D0B55527EC2D"
+      "      F1050E2E8FF49C85C23CBE7DED0E7CE6A594896B8F62888F"
+      "      DBC5C8821305E2EA42BF01E37300116281#)\n"
+      "  (d #E8F32E723DECF4051AEFAC8E2C93C9C5B214313817CDB01A"
+      "      1494B917C8436B35#)))\n",
+
+      "(public-key\n"
+      " (ecc\n"
+      "  (curve secp256k1)\n"
+      "  (q #0439A36013301597DAEF41FBE593A02CC513D0B55527EC2D"
+      "      F1050E2E8FF49C85C23CBE7DED0E7CE6A594896B8F62888F"
+      "      DBC5C8821305E2EA42BF01E37300116281#)))\n"
+
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }
     }
   };
   int i;
@@ -6007,6 +9257,7 @@ main (int argc, char **argv)
   int use_fips = 0;
   int selftest_only = 0;
   int pubkey_only = 0;
+  int cipher_modes_only = 0;
   int loop = 0;
   unsigned int loopcount = 0;
 
@@ -6047,6 +9298,11 @@ main (int argc, char **argv)
           pubkey_only = 1;
           argc--; argv++;
         }
+      else if (!strcmp (*argv, "--cipher-modes"))
+        {
+          cipher_modes_only = 1;
+          argc--; argv++;
+        }
       else if (!strcmp (*argv, "--die"))
         {
           die_on_error = 1;
@@ -6061,6 +9317,21 @@ main (int argc, char **argv)
               argc--; argv++;
             }
         }
+      else if (!strcmp (*argv, "--disable-hwf"))
+        {
+          argc--;
+          argv++;
+          if (argc)
+            {
+              if (gcry_control (GCRYCTL_DISABLE_HWF, *argv, NULL))
+                fprintf (stderr,
+                        PGM
+                        ": unknown hardware feature `%s' - option ignored\n",
+                        *argv);
+              argc--;
+              argv++;
+            }
+        }
     }
 
   gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose);
@@ -6092,6 +9363,11 @@ main (int argc, char **argv)
     {
       if (pubkey_only)
         check_pubkey ();
+      else if (cipher_modes_only)
+        {
+          check_ciphers ();
+          check_cipher_modes ();
+        }
       else if (!selftest_only)
         {
           check_ciphers ();
index bd05064..d97494c 100644 (file)
@@ -442,6 +442,7 @@ do_slope_benchmark (struct bench_obj *obj)
               &overhead);
 
   free (measurement_raw);
+  free (measurements);
   free (real_buffer);
   obj->ops->finalize (obj);
 
@@ -519,8 +520,6 @@ bench_print_result_std (double nsecs_per_byte)
   char mbpsec_buf[16];
   char cpbyte_buf[16];
 
-  strcpy (cpbyte_buf, "-");
-
   double_to_str (nsecpbyte_buf, sizeof (nsecpbyte_buf), nsecs_per_byte);
 
   /* If user didn't provide CPU speed, we cannot show cycles/byte results.  */
@@ -529,16 +528,15 @@ bench_print_result_std (double nsecs_per_byte)
       cycles_per_byte = nsecs_per_byte * cpu_ghz;
       double_to_str (cpbyte_buf, sizeof (cpbyte_buf), cycles_per_byte);
     }
+  else
+    strcpy (cpbyte_buf, "-");
 
   mbytes_per_sec =
     (1000.0 * 1000.0 * 1000.0) / (nsecs_per_byte * 1024 * 1024);
   double_to_str (mbpsec_buf, sizeof (mbpsec_buf), mbytes_per_sec);
 
-  strncat (nsecpbyte_buf, " ns/B", sizeof (nsecpbyte_buf) - 1);
-  strncat (mbpsec_buf, " MiB/s", sizeof (mbpsec_buf) - 1);
-  strncat (cpbyte_buf, " c/B", sizeof (cpbyte_buf) - 1);
-
-  printf ("%14s %15s %13s\n", nsecpbyte_buf, mbpsec_buf, cpbyte_buf);
+  printf ("%9s ns/B %9s MiB/s %9s c/B\n",
+          nsecpbyte_buf, mbpsec_buf, cpbyte_buf);
 }
 
 static void
@@ -740,7 +738,6 @@ static struct bench_ops decrypt_ops = {
 };
 
 
-#ifdef HAVE_U64_TYPEDEF
 static void
 bench_ccm_encrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
 {
@@ -903,20 +900,19 @@ static struct bench_ops ccm_authenticate_ops = {
   &bench_encrypt_free,
   &bench_ccm_authenticate_do_bench
 };
-#endif /*HAVE_U64_TYPEDEF*/
 
 
 static void
-bench_gcm_encrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
+bench_aead_encrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen,
+                            const char *nonce, size_t noncelen)
 {
   gcry_cipher_hd_t hd = obj->priv;
   int err;
   char tag[16];
-  char nonce[12] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce,
-                     0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88, };
 
-  gcry_cipher_setiv (hd, nonce, sizeof (nonce));
+  gcry_cipher_setiv (hd, nonce, noncelen);
 
+  gcry_cipher_final (hd);
   err = gcry_cipher_encrypt (hd, buf, buflen, buf, buflen);
   if (err)
     {
@@ -937,16 +933,16 @@ bench_gcm_encrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
 }
 
 static void
-bench_gcm_decrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
+bench_aead_decrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen,
+                            const char *nonce, size_t noncelen)
 {
   gcry_cipher_hd_t hd = obj->priv;
   int err;
   char tag[16] = { 0, };
-  char nonce[12] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce,
-                     0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88, };
 
-  gcry_cipher_setiv (hd, nonce, sizeof (nonce));
+  gcry_cipher_setiv (hd, nonce, noncelen);
 
+  gcry_cipher_final (hd);
   err = gcry_cipher_decrypt (hd, buf, buflen, buf, buflen);
   if (err)
     {
@@ -969,17 +965,23 @@ bench_gcm_decrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
 }
 
 static void
-bench_gcm_authenticate_do_bench (struct bench_obj *obj, void *buf,
-           size_t buflen)
+bench_aead_authenticate_do_bench (struct bench_obj *obj, void *buf,
+                                 size_t buflen, const char *nonce,
+                                 size_t noncelen)
 {
   gcry_cipher_hd_t hd = obj->priv;
   int err;
   char tag[16] = { 0, };
-  char nonce[12] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce,
-                     0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88, };
   char data = 0xff;
 
-  gcry_cipher_setiv (hd, nonce, sizeof (nonce));
+  err = gcry_cipher_setiv (hd, nonce, noncelen);
+  if (err)
+    {
+      fprintf (stderr, PGM ": gcry_cipher_setiv failed: %s\n",
+           gpg_strerror (err));
+      gcry_cipher_close (hd);
+      exit (1);
+    }
 
   err = gcry_cipher_authenticate (hd, buf, buflen);
   if (err)
@@ -990,6 +992,7 @@ bench_gcm_authenticate_do_bench (struct bench_obj *obj, void *buf,
       exit (1);
     }
 
+  gcry_cipher_final (hd);
   err = gcry_cipher_encrypt (hd, &data, sizeof (data), &data, sizeof (data));
   if (err)
     {
@@ -1009,6 +1012,34 @@ bench_gcm_authenticate_do_bench (struct bench_obj *obj, void *buf,
     }
 }
 
+
+static void
+bench_gcm_encrypt_do_bench (struct bench_obj *obj, void *buf,
+                           size_t buflen)
+{
+  char nonce[12] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce,
+                     0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88 };
+  bench_aead_encrypt_do_bench (obj, buf, buflen, nonce, sizeof(nonce));
+}
+
+static void
+bench_gcm_decrypt_do_bench (struct bench_obj *obj, void *buf,
+                           size_t buflen)
+{
+  char nonce[12] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce,
+                     0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88 };
+  bench_aead_decrypt_do_bench (obj, buf, buflen, nonce, sizeof(nonce));
+}
+
+static void
+bench_gcm_authenticate_do_bench (struct bench_obj *obj, void *buf,
+                                size_t buflen)
+{
+  char nonce[12] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce,
+                     0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88 };
+  bench_aead_authenticate_do_bench (obj, buf, buflen, nonce, sizeof(nonce));
+}
+
 static struct bench_ops gcm_encrypt_ops = {
   &bench_encrypt_init,
   &bench_encrypt_free,
@@ -1028,6 +1059,98 @@ static struct bench_ops gcm_authenticate_ops = {
 };
 
 
+static void
+bench_ocb_encrypt_do_bench (struct bench_obj *obj, void *buf,
+                           size_t buflen)
+{
+  char nonce[15] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce,
+                     0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88,
+                     0x00, 0x00, 0x01 };
+  bench_aead_encrypt_do_bench (obj, buf, buflen, nonce, sizeof(nonce));
+}
+
+static void
+bench_ocb_decrypt_do_bench (struct bench_obj *obj, void *buf,
+                           size_t buflen)
+{
+  char nonce[15] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce,
+                     0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88,
+                     0x00, 0x00, 0x01 };
+  bench_aead_decrypt_do_bench (obj, buf, buflen, nonce, sizeof(nonce));
+}
+
+static void
+bench_ocb_authenticate_do_bench (struct bench_obj *obj, void *buf,
+                                size_t buflen)
+{
+  char nonce[15] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce,
+                     0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88,
+                     0x00, 0x00, 0x01 };
+  bench_aead_authenticate_do_bench (obj, buf, buflen, nonce, sizeof(nonce));
+}
+
+static struct bench_ops ocb_encrypt_ops = {
+  &bench_encrypt_init,
+  &bench_encrypt_free,
+  &bench_ocb_encrypt_do_bench
+};
+
+static struct bench_ops ocb_decrypt_ops = {
+  &bench_encrypt_init,
+  &bench_encrypt_free,
+  &bench_ocb_decrypt_do_bench
+};
+
+static struct bench_ops ocb_authenticate_ops = {
+  &bench_encrypt_init,
+  &bench_encrypt_free,
+  &bench_ocb_authenticate_do_bench
+};
+
+
+static void
+bench_poly1305_encrypt_do_bench (struct bench_obj *obj, void *buf,
+                                size_t buflen)
+{
+  char nonce[8] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad };
+  bench_aead_encrypt_do_bench (obj, buf, buflen, nonce, sizeof(nonce));
+}
+
+static void
+bench_poly1305_decrypt_do_bench (struct bench_obj *obj, void *buf,
+                                size_t buflen)
+{
+  char nonce[8] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad };
+  bench_aead_decrypt_do_bench (obj, buf, buflen, nonce, sizeof(nonce));
+}
+
+static void
+bench_poly1305_authenticate_do_bench (struct bench_obj *obj, void *buf,
+                                     size_t buflen)
+{
+  char nonce[8] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad };
+  bench_aead_authenticate_do_bench (obj, buf, buflen, nonce, sizeof(nonce));
+}
+
+static struct bench_ops poly1305_encrypt_ops = {
+  &bench_encrypt_init,
+  &bench_encrypt_free,
+  &bench_poly1305_encrypt_do_bench
+};
+
+static struct bench_ops poly1305_decrypt_ops = {
+  &bench_encrypt_init,
+  &bench_encrypt_free,
+  &bench_poly1305_decrypt_do_bench
+};
+
+static struct bench_ops poly1305_authenticate_ops = {
+  &bench_encrypt_init,
+  &bench_encrypt_free,
+  &bench_poly1305_authenticate_do_bench
+};
+
+
 static struct bench_cipher_mode cipher_modes[] = {
   {GCRY_CIPHER_MODE_ECB, "ECB enc", &encrypt_ops},
   {GCRY_CIPHER_MODE_ECB, "ECB dec", &decrypt_ops},
@@ -1039,14 +1162,18 @@ static struct bench_cipher_mode cipher_modes[] = {
   {GCRY_CIPHER_MODE_OFB, "OFB dec", &decrypt_ops},
   {GCRY_CIPHER_MODE_CTR, "CTR enc", &encrypt_ops},
   {GCRY_CIPHER_MODE_CTR, "CTR dec", &decrypt_ops},
-#ifdef HAVE_U64_TYPEDEF
   {GCRY_CIPHER_MODE_CCM, "CCM enc", &ccm_encrypt_ops},
   {GCRY_CIPHER_MODE_CCM, "CCM dec", &ccm_decrypt_ops},
   {GCRY_CIPHER_MODE_CCM, "CCM auth", &ccm_authenticate_ops},
-#endif
   {GCRY_CIPHER_MODE_GCM, "GCM enc", &gcm_encrypt_ops},
   {GCRY_CIPHER_MODE_GCM, "GCM dec", &gcm_decrypt_ops},
   {GCRY_CIPHER_MODE_GCM, "GCM auth", &gcm_authenticate_ops},
+  {GCRY_CIPHER_MODE_OCB, "OCB enc",  &ocb_encrypt_ops},
+  {GCRY_CIPHER_MODE_OCB, "OCB dec",  &ocb_decrypt_ops},
+  {GCRY_CIPHER_MODE_OCB, "OCB auth", &ocb_authenticate_ops},
+  {GCRY_CIPHER_MODE_POLY1305, "POLY1305 enc", &poly1305_encrypt_ops},
+  {GCRY_CIPHER_MODE_POLY1305, "POLY1305 dec", &poly1305_decrypt_ops},
+  {GCRY_CIPHER_MODE_POLY1305, "POLY1305 auth", &poly1305_authenticate_ops},
   {0},
 };
 
@@ -1066,8 +1193,9 @@ cipher_bench_one (int algo, struct bench_cipher_mode *pmode)
   if (!blklen)
     return;
 
-  /* Stream cipher? Only test with ECB. */
-  if (blklen == 1 && mode.mode != GCRY_CIPHER_MODE_ECB)
+  /* Stream cipher? Only test with "ECB" and POLY1305. */
+  if (blklen == 1 && (mode.mode != GCRY_CIPHER_MODE_ECB &&
+                     mode.mode != GCRY_CIPHER_MODE_POLY1305))
     return;
   if (blklen == 1 && mode.mode == GCRY_CIPHER_MODE_ECB)
     {
@@ -1075,14 +1203,22 @@ cipher_bench_one (int algo, struct bench_cipher_mode *pmode)
       mode.name = mode.ops == &encrypt_ops ? "STREAM enc" : "STREAM dec";
     }
 
+  /* Poly1305 has restriction for cipher algorithm */
+  if (mode.mode == GCRY_CIPHER_MODE_POLY1305 && algo != GCRY_CIPHER_CHACHA20)
+    return;
+
   /* CCM has restrictions for block-size */
   if (mode.mode == GCRY_CIPHER_MODE_CCM && blklen != GCRY_CCM_BLOCK_LEN)
     return;
 
-  /* CCM has restrictions for block-size */
+  /* GCM has restrictions for block-size */
   if (mode.mode == GCRY_CIPHER_MODE_GCM && blklen != GCRY_GCM_BLOCK_LEN)
     return;
 
+  /* Our OCB implementaion has restrictions for block-size.  */
+  if (mode.mode == GCRY_CIPHER_MODE_OCB && blklen != 16)
+    return;
+
   bench_print_mode (14, mode.name);
 
   obj.ops = mode.ops;
@@ -1121,17 +1257,17 @@ cipher_bench (char **argv, int argc)
   if (argv && argc)
     {
       for (i = 0; i < argc; i++)
-       {
-         algo = gcry_cipher_map_name (argv[i]);
-         if (algo)
-           _cipher_bench (algo);
-       }
+        {
+          algo = gcry_cipher_map_name (argv[i]);
+          if (algo)
+            _cipher_bench (algo);
+        }
     }
   else
     {
       for (i = 1; i < 400; i++)
-       if (!gcry_cipher_test_algo (i))
-         _cipher_bench (i);
+        if (!gcry_cipher_test_algo (i))
+          _cipher_bench (i);
     }
 }
 
@@ -1308,16 +1444,30 @@ bench_mac_init (struct bench_obj *obj)
     }
 
   err = gcry_mac_setkey (hd, key, keylen);
-  free (key);
   if (err)
     {
       fprintf (stderr, PGM ": error setting key for mac `%s'\n",
               gcry_mac_algo_name (mode->algo));
+      free (key);
       exit (1);
     }
 
+  switch (mode->algo)
+    {
+    default:
+      break;
+    case GCRY_MAC_POLY1305_AES:
+    case GCRY_MAC_POLY1305_CAMELLIA:
+    case GCRY_MAC_POLY1305_TWOFISH:
+    case GCRY_MAC_POLY1305_SERPENT:
+    case GCRY_MAC_POLY1305_SEED:
+      gcry_mac_setiv (hd, key, 16);
+      break;
+    }
+
   obj->priv = hd;
 
+  free (key);
   return 0;
 }
 
@@ -1405,7 +1555,7 @@ mac_bench (char **argv, int argc)
     }
   else
     {
-      for (i = 1; i < 500; i++)
+      for (i = 1; i < 600; i++)
        if (!gcry_mac_test_algo (i))
          _mac_bench (i);
     }
@@ -1414,13 +1564,182 @@ mac_bench (char **argv, int argc)
 }
 
 
+/************************************************************ KDF benchmarks. */
+
+struct bench_kdf_mode
+{
+  struct bench_ops *ops;
+
+  int algo;
+  int subalgo;
+};
+
+
+static int
+bench_kdf_init (struct bench_obj *obj)
+{
+  struct bench_kdf_mode *mode = obj->priv;
+
+  if (mode->algo == GCRY_KDF_PBKDF2)
+    {
+      obj->min_bufsize = 2;
+      obj->max_bufsize = 2 * 32;
+      obj->step_size = 2;
+    }
+
+  obj->num_measure_repetitions = num_measurement_repetitions;
+
+  return 0;
+}
+
+static void
+bench_kdf_free (struct bench_obj *obj)
+{
+  (void)obj;
+}
+
+static void
+bench_kdf_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
+{
+  struct bench_kdf_mode *mode = obj->priv;
+  char keybuf[16];
+
+  (void)buf;
+
+  if (mode->algo == GCRY_KDF_PBKDF2)
+    {
+      gcry_kdf_derive("qwerty", 6, mode->algo, mode->subalgo, "01234567", 8,
+                     buflen, sizeof(keybuf), keybuf);
+    }
+}
+
+static struct bench_ops kdf_ops = {
+  &bench_kdf_init,
+  &bench_kdf_free,
+  &bench_kdf_do_bench
+};
+
+
+static void
+kdf_bench_one (int algo, int subalgo)
+{
+  struct bench_kdf_mode mode = { &kdf_ops };
+  struct bench_obj obj = { 0 };
+  double nsecs_per_iteration;
+  double cycles_per_iteration;
+  char algo_name[32];
+  char nsecpiter_buf[16];
+  char cpiter_buf[16];
+
+  mode.algo = algo;
+  mode.subalgo = subalgo;
+
+  switch (subalgo)
+    {
+    case GCRY_MD_CRC32:
+    case GCRY_MD_CRC32_RFC1510:
+    case GCRY_MD_CRC24_RFC2440:
+    case GCRY_MD_MD4:
+      /* Skip CRC32s. */
+      return;
+    }
+
+  if (gcry_md_get_algo_dlen (subalgo) == 0)
+    {
+      /* Skip XOFs */
+      return;
+    }
+
+  *algo_name = 0;
+
+  if (algo == GCRY_KDF_PBKDF2)
+    {
+      snprintf (algo_name, sizeof(algo_name), "PBKDF2-HMAC-%s",
+               gcry_md_algo_name (subalgo));
+    }
+
+  bench_print_algo (-24, algo_name);
+
+  obj.ops = mode.ops;
+  obj.priv = &mode;
+
+  nsecs_per_iteration = do_slope_benchmark (&obj);
+
+  strcpy(cpiter_buf, csv_mode ? "" : "-");
+
+  double_to_str (nsecpiter_buf, sizeof (nsecpiter_buf), nsecs_per_iteration);
+
+  /* If user didn't provide CPU speed, we cannot show cycles/iter results.  */
+  if (cpu_ghz > 0.0)
+    {
+      cycles_per_iteration = nsecs_per_iteration * cpu_ghz;
+      double_to_str (cpiter_buf, sizeof (cpiter_buf), cycles_per_iteration);
+    }
+
+  if (csv_mode)
+    {
+      printf ("%s,%s,%s,,,,,,,,,%s,ns/iter,%s,c/iter\n",
+             current_section_name,
+             current_algo_name ? current_algo_name : "",
+             current_mode_name ? current_mode_name : "",
+             nsecpiter_buf,
+             cpiter_buf);
+    }
+  else
+    {
+      printf ("%14s %13s\n", nsecpiter_buf, cpiter_buf);
+    }
+}
+
+void
+kdf_bench (char **argv, int argc)
+{
+  char algo_name[32];
+  int i, j;
+
+  bench_print_section ("kdf", "KDF");
+
+  if (!csv_mode)
+    {
+      printf (" %-*s | ", 24, "");
+      printf ("%14s %13s\n", "nanosecs/iter", "cycles/iter");
+    }
+
+  if (argv && argc)
+    {
+      for (i = 0; i < argc; i++)
+       {
+         for (j = 1; j < 400; j++)
+           {
+             if (gcry_md_test_algo (j))
+               continue;
+
+             snprintf (algo_name, sizeof(algo_name), "PBKDF2-HMAC-%s",
+                       gcry_md_algo_name (j));
+
+             if (!strcmp(argv[i], algo_name))
+               kdf_bench_one (GCRY_KDF_PBKDF2, j);
+           }
+       }
+    }
+  else
+    {
+      for (i = 1; i < 400; i++)
+       if (!gcry_md_test_algo (i))
+         kdf_bench_one (GCRY_KDF_PBKDF2, i);
+    }
+
+  bench_print_footer (24);
+}
+
+
 /************************************************************** Main program. */
 
 void
 print_help (void)
 {
   static const char *help_lines[] = {
-    "usage: bench-slope [options] [hash|mac|cipher [algonames]]",
+    "usage: bench-slope [options] [hash|mac|cipher|kdf [algonames]]",
     "",
     " options:",
     "   --cpu-mhz <mhz>           Set CPU speed for calculating cycles",
@@ -1587,6 +1906,7 @@ main (int argc, char **argv)
       hash_bench (NULL, 0);
       mac_bench (NULL, 0);
       cipher_bench (NULL, 0);
+      kdf_bench (NULL, 0);
     }
   else if (!strcmp (*argv, "hash"))
     {
@@ -1612,6 +1932,14 @@ main (int argc, char **argv)
       warm_up_cpu ();
       cipher_bench ((argc == 0) ? NULL : argv, argc);
     }
+  else if (!strcmp (*argv, "kdf"))
+    {
+      argc--;
+      argv++;
+
+      warm_up_cpu ();
+      kdf_bench ((argc == 0) ? NULL : argv, argc);
+    }
   else
     {
       fprintf (stderr, PGM ": unknown argument: %s\n", *argv);
index 5efc083..53b83b1 100644 (file)
@@ -62,6 +62,12 @@ static int in_fips_mode;
 /* Whether we are running as part of the regression test suite.  */
 static int in_regression_test;
 
+/* Whether --progress is in use.  */
+static int with_progress;
+
+/* Runtime flag to switch to a different progress output.  */
+static int single_char_progress;
+
 
 static const char sample_private_dsa_key_1024[] =
 "(private-key\n"
@@ -250,6 +256,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__ );\
@@ -293,9 +435,17 @@ progress_cb (void *cb_data, const char *what, int printchar,
 {
   (void)cb_data;
 
-  fprintf (stderr, PGM ": progress (%s %c %d %d)\n",
-           what, printchar, current, total);
-  fflush (stderr);
+  if (single_char_progress)
+    {
+      fputc (printchar, stdout);
+      fflush (stderr);
+    }
+  else
+    {
+      fprintf (stderr, PGM ": progress (%s %c %d %d)\n",
+               what, printchar, current, total);
+      fflush (stderr);
+    }
 }
 
 
@@ -313,7 +463,7 @@ random_bench (int very_strong)
       for (i=0; i < 100; i++)
         gcry_randomize (buf, sizeof buf, GCRY_STRONG_RANDOM);
       stop_timer ();
-      printf (" %s", elapsed_time ());
+      printf (" %s", elapsed_time (1));
     }
 
   start_timer ();
@@ -321,7 +471,7 @@ random_bench (int very_strong)
     gcry_randomize (buf, 8,
                     very_strong? GCRY_VERY_STRONG_RANDOM:GCRY_STRONG_RANDOM);
   stop_timer ();
-  printf (" %s", elapsed_time ());
+  printf (" %s", elapsed_time (1));
 
   putchar ('\n');
   if (verbose)
@@ -381,7 +531,7 @@ md_bench ( const char *algoname )
       gcry_md_write (hd, buf, bufsize);
   gcry_md_final (hd);
   stop_timer ();
-  printf (" %s", elapsed_time ());
+  printf (" %s", elapsed_time (1));
   fflush (stdout);
 
   gcry_md_reset (hd);
@@ -391,7 +541,7 @@ md_bench ( const char *algoname )
       gcry_md_write (hd, buf, bufsize/10);
   gcry_md_final (hd);
   stop_timer ();
-  printf (" %s", elapsed_time ());
+  printf (" %s", elapsed_time (1));
   fflush (stdout);
 
   gcry_md_reset (hd);
@@ -401,7 +551,7 @@ md_bench ( const char *algoname )
       gcry_md_write (hd, buf, 1);
   gcry_md_final (hd);
   stop_timer ();
-  printf (" %s", elapsed_time ());
+  printf (" %s", elapsed_time (1));
   fflush (stdout);
 
   start_timer ();
@@ -411,7 +561,7 @@ md_bench ( const char *algoname )
         gcry_md_putc (hd, buf[j]);
   gcry_md_final (hd);
   stop_timer ();
-  printf (" %s", elapsed_time ());
+  printf (" %s", elapsed_time (1));
   fflush (stdout);
 
   gcry_md_close (hd);
@@ -435,7 +585,7 @@ md_bench ( const char *algoname )
     for (i=0; i < 100; i++)
       gcry_md_hash_buffer (algo, digest, largebuf, 10000);
   stop_timer ();
-  printf (" %s", elapsed_time ());
+  printf (" %s", elapsed_time (1));
   free (largebuf_base);
 
   putchar ('\n');
@@ -461,7 +611,7 @@ mac_bench ( const char *algoname )
 
   if (!algoname)
     {
-      for (i=1; i < 500; i++)
+      for (i=1; i < 600; i++)
         if (in_fips_mode && i == GCRY_MAC_HMAC_MD5)
           ; /* Don't use MD5 in fips mode.  */
         else if ( !gcry_mac_test_algo (i) )
@@ -509,6 +659,18 @@ mac_bench ( const char *algoname )
   for (i=0; i < bufsize; i++)
     buf[i] = i;
 
+  if (algo >= GCRY_MAC_POLY1305_AES && algo <= GCRY_MAC_POLY1305_SEED)
+    {
+      static const char iv[16] = { 1, 2, 3, 4, };
+      err = gcry_mac_setiv(hd, iv, sizeof(iv));
+      if (err)
+        {
+          fprintf (stderr, PGM ": error setting nonce for mac algorithm `%s': %s\n",
+                   algoname, gpg_strerror (err));
+          exit (1);
+        }
+    }
+
   printf ("%-20s", gcry_mac_algo_name (algo));
 
   start_timer ();
@@ -518,7 +680,7 @@ mac_bench ( const char *algoname )
   macoutlen = maclen;
   gcry_mac_read (hd, mac[0], &macoutlen);
   stop_timer ();
-  printf (" %s", elapsed_time ());
+  printf (" %s", elapsed_time (1));
   fflush (stdout);
 
   gcry_mac_reset (hd);
@@ -530,7 +692,7 @@ mac_bench ( const char *algoname )
   macoutlen = maclen;
   gcry_mac_read (hd, mac[1], &macoutlen);
   stop_timer ();
-  printf (" %s", elapsed_time ());
+  printf (" %s", elapsed_time (1));
   fflush (stdout);
 
   gcry_mac_reset (hd);
@@ -542,7 +704,7 @@ mac_bench ( const char *algoname )
   macoutlen = maclen;
   gcry_mac_read (hd, mac[2], &macoutlen);
   stop_timer ();
-  printf (" %s", elapsed_time ());
+  printf (" %s", elapsed_time (1));
   fflush (stdout);
 
   gcry_mac_close (hd);
@@ -562,7 +724,6 @@ mac_bench ( const char *algoname )
 }
 
 
-#ifdef HAVE_U64_TYPEDEF
 static void ccm_aead_init(gcry_cipher_hd_t hd, size_t buflen, int authlen)
 {
   const int _L = 4;
@@ -594,7 +755,6 @@ static void ccm_aead_init(gcry_cipher_hd_t hd, size_t buflen, int authlen)
       exit (1);
     }
 }
-#endif
 
 
 static void
@@ -617,18 +777,19 @@ cipher_bench ( const char *algoname )
     void (* const aead_init)(gcry_cipher_hd_t hd, size_t buflen, int authlen);
     int req_blocksize;
     int authlen;
+    int noncelen;
   } modes[] = {
     { GCRY_CIPHER_MODE_ECB, "   ECB/Stream", 1 },
     { GCRY_CIPHER_MODE_CBC, "      CBC", 1 },
     { GCRY_CIPHER_MODE_CFB, "      CFB", 0 },
     { GCRY_CIPHER_MODE_OFB, "      OFB", 0 },
     { GCRY_CIPHER_MODE_CTR, "      CTR", 0 },
-#ifdef HAVE_U64_TYPEDEF
     { GCRY_CIPHER_MODE_CCM, "      CCM", 0,
       ccm_aead_init, GCRY_CCM_BLOCK_LEN, 8 },
-#endif
     { GCRY_CIPHER_MODE_GCM, "      GCM", 0,
       NULL, GCRY_GCM_BLOCK_LEN, GCRY_GCM_BLOCK_LEN },
+    { GCRY_CIPHER_MODE_OCB, "      OCB", 1,
+      NULL, 16, 16, 15 },
     { GCRY_CIPHER_MODE_STREAM, "", 0 },
     {0}
   };
@@ -767,9 +928,30 @@ cipher_bench ( const char *algoname )
                   exit (1);
                 }
             }
+
+          if (modes[modeidx].noncelen)
+            {
+              char nonce[100];
+              size_t noncelen;
+
+              noncelen = modes[modeidx].noncelen;
+              if (noncelen > sizeof nonce)
+                noncelen = sizeof nonce;
+              memset (nonce, 42, noncelen);
+              err = gcry_cipher_setiv (hd, nonce, noncelen);
+              if (err)
+                {
+                  fprintf (stderr, "gcry_cipher_setiv failed: %s\n",
+                           gpg_strerror (err));
+                  gcry_cipher_close (hd);
+                  exit (1);
+                }
+            }
+
           if (modes[modeidx].aead_init)
             {
               (*modes[modeidx].aead_init) (hd, buflen, modes[modeidx].authlen);
+              gcry_cipher_final (hd);
               err = gcry_cipher_encrypt (hd, outbuf, buflen, buf, buflen);
               if (err)
                 break;
@@ -782,7 +964,7 @@ cipher_bench ( const char *algoname )
         }
       stop_timer ();
 
-      printf (" %s", elapsed_time ());
+      printf (" %s", elapsed_time (1));
       fflush (stdout);
       gcry_cipher_close (hd);
       if (err)
@@ -825,21 +1007,45 @@ cipher_bench ( const char *algoname )
                   exit (1);
                 }
             }
+
+          if (modes[modeidx].noncelen)
+            {
+              char nonce[100];
+              size_t noncelen;
+
+              noncelen = modes[modeidx].noncelen;
+              if (noncelen > sizeof nonce)
+                noncelen = sizeof nonce;
+              memset (nonce, 42, noncelen);
+              err = gcry_cipher_setiv (hd, nonce, noncelen);
+              if (err)
+                {
+                  fprintf (stderr, "gcry_cipher_setiv failed: %s\n",
+                           gpg_strerror (err));
+                  gcry_cipher_close (hd);
+                  exit (1);
+                }
+            }
+
           if (modes[modeidx].aead_init)
             {
               (*modes[modeidx].aead_init) (hd, buflen, modes[modeidx].authlen);
+              gcry_cipher_final (hd);
               err = gcry_cipher_decrypt (hd, outbuf, buflen, buf, buflen);
               if (err)
                 break;
               err = gcry_cipher_checktag (hd, outbuf, modes[modeidx].authlen);
               if (gpg_err_code (err) == GPG_ERR_CHECKSUM)
-                err = gpg_error (GPG_ERR_NO_ERROR);
+                err = 0;
             }
           else
-            err = gcry_cipher_decrypt (hd, outbuf, buflen, buf, buflen);
+            {
+              gcry_cipher_final (hd);
+              err = gcry_cipher_decrypt (hd, outbuf, buflen, buf, buflen);
+            }
         }
       stop_timer ();
-      printf (" %s", elapsed_time ());
+      printf (" %s", elapsed_time (1));
       fflush (stdout);
       gcry_cipher_close (hd);
       if (err)
@@ -865,7 +1071,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++)
@@ -875,15 +1081,22 @@ rsa_bench (int iterations, int print_header, int no_blinding)
       gcry_sexp_t data;
       gcry_sexp_t sig = NULL;
       int count;
+      unsigned nbits = p_sizes[testno];
 
-      printf ("RSA %3d bit    ", p_sizes[testno]);
+      printf ("RSA %3d bit    ", nbits);
       fflush (stdout);
 
+      if (in_fips_mode && !(nbits == 2048 || nbits == 3072))
+        {
+          puts ("[skipped in fips mode]");
+          continue;
+        }
+
       err = gcry_sexp_build (&key_spec, NULL,
                              gcry_fips_mode_active ()
                              ? "(genkey (RSA (nbits %d)))"
                              : "(genkey (RSA (nbits %d)(transient-key)))",
-                             p_sizes[testno]);
+                             nbits);
       if (err)
         die ("creating S-expression failed: %s\n", gcry_strerror (err));
 
@@ -891,7 +1104,7 @@ rsa_bench (int iterations, int print_header, int no_blinding)
       err = gcry_pk_genkey (&key_pair, key_spec);
       if (err)
         die ("creating %d bit RSA key failed: %s\n",
-             p_sizes[testno], gcry_strerror (err));
+             nbits, gcry_strerror (err));
 
       pub_key = gcry_sexp_find_token (key_pair, "public-key", 0);
       if (! pub_key)
@@ -903,11 +1116,11 @@ rsa_bench (int iterations, int print_header, int no_blinding)
       gcry_sexp_release (key_spec);
 
       stop_timer ();
-      printf ("   %s", elapsed_time ());
+      printf ("   %s", elapsed_time (1));
       fflush (stdout);
 
-      x = gcry_mpi_new (p_sizes[testno]);
-      gcry_mpi_randomize (x, p_sizes[testno]-8, GCRY_WEAK_RANDOM);
+      x = gcry_mpi_new (nbits);
+      gcry_mpi_randomize (x, nbits-8, GCRY_WEAK_RANDOM);
       err = gcry_sexp_build (&data, NULL,
                              "(data (flags raw) (value %m))", x);
       gcry_mpi_release (x);
@@ -923,7 +1136,7 @@ rsa_bench (int iterations, int print_header, int no_blinding)
             die ("signing failed (%d): %s\n", count, gpg_strerror (err));
         }
       stop_timer ();
-      printf ("   %s", elapsed_time ());
+      printf ("   %s", elapsed_time (1));
       fflush (stdout);
 
       start_timer ();
@@ -940,13 +1153,13 @@ rsa_bench (int iterations, int print_header, int no_blinding)
             }
         }
       stop_timer ();
-      printf ("     %s", elapsed_time ());
+      printf ("     %s", elapsed_time (1));
 
       if (no_blinding)
         {
           fflush (stdout);
-          x = gcry_mpi_new (p_sizes[testno]);
-          gcry_mpi_randomize (x, p_sizes[testno]-8, GCRY_WEAK_RANDOM);
+          x = gcry_mpi_new (nbits);
+          gcry_mpi_randomize (x, nbits-8, GCRY_WEAK_RANDOM);
           err = gcry_sexp_build (&data, NULL,
                                  "(data (flags no-blinding) (value %m))", x);
           gcry_mpi_release (x);
@@ -962,7 +1175,7 @@ rsa_bench (int iterations, int print_header, int no_blinding)
                 die ("signing failed (%d): %s\n", count, gpg_strerror (err));
             }
           stop_timer ();
-          printf ("   %s", elapsed_time ());
+          printf ("   %s", elapsed_time (1));
           fflush (stdout);
         }
 
@@ -977,6 +1190,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 (1));
+      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 (1), 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)
@@ -1014,7 +1336,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++)
@@ -1049,7 +1371,7 @@ dsa_bench (int iterations, int print_header)
             }
         }
       stop_timer ();
-      printf ("   %s", elapsed_time ());
+      printf ("   %s", elapsed_time (1));
       fflush (stdout);
 
       start_timer ();
@@ -1065,7 +1387,7 @@ dsa_bench (int iterations, int print_header)
             }
         }
       stop_timer ();
-      printf ("     %s\n", elapsed_time ());
+      printf ("     %s\n", elapsed_time (1));
       fflush (stdout);
 
       gcry_sexp_release (sig);
@@ -1092,7 +1414,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++)
@@ -1108,6 +1430,12 @@ ecc_bench (int iterations, int print_header)
 
       is_ed25519 = !strcmp (p_sizes[testno], "Ed25519");
       is_gost = !strncmp (p_sizes[testno], "gost", 4);
+
+      /* Only P-{224,256,384,521} are allowed in fips mode */
+      if (gcry_fips_mode_active()
+          && (is_ed25519 || is_gost || !strcmp (p_sizes[testno], "192")))
+         continue;
+
       if (is_ed25519)
         {
           p_size = 256;
@@ -1159,7 +1487,7 @@ ecc_bench (int iterations, int print_header)
       gcry_sexp_release (key_spec);
 
       stop_timer ();
-      printf ("     %s", elapsed_time ());
+      printf ("     %s", elapsed_time (1));
       fflush (stdout);
 
       x = gcry_mpi_new (p_size);
@@ -1194,7 +1522,7 @@ ecc_bench (int iterations, int print_header)
             }
         }
       stop_timer ();
-      printf ("   %s", elapsed_time ());
+      printf ("   %s", elapsed_time (1));
       fflush (stdout);
 
       start_timer ();
@@ -1211,7 +1539,7 @@ ecc_bench (int iterations, int print_header)
             }
         }
       stop_timer ();
-      printf ("     %s\n", elapsed_time ());
+      printf ("     %s\n", elapsed_time (1));
       fflush (stdout);
 
       gcry_sexp_release (sig);
@@ -1244,7 +1572,7 @@ do_powm ( const char *n_str, const char *e_str, const char *m_str)
   for (i=0; i < 1000; i++)
     gcry_mpi_powm (cip, msg, e, n);
   stop_timer ();
-  printf (" %s", elapsed_time ()); fflush (stdout);
+  printf (" %s", elapsed_time (1)); fflush (stdout);
 /*    { */
 /*      char *buf; */
 
@@ -1287,6 +1615,51 @@ mpi_bench (void)
 }
 
 
+static void
+prime_bench (void)
+{
+  gpg_error_t err;
+  int i;
+  gcry_mpi_t prime;
+  int old_prog = single_char_progress;
+
+  single_char_progress = 1;
+  if (!with_progress)
+    printf ("%-10s", "prime");
+  fflush (stdout);
+  start_timer ();
+  for (i=0; i < 10; i++)
+    {
+      if (with_progress)
+        fputs ("primegen ", stdout);
+      err = gcry_prime_generate (&prime,
+                                 1024, 0,
+                                 NULL,
+                                 NULL, NULL,
+                                 GCRY_WEAK_RANDOM,
+                                 GCRY_PRIME_FLAG_SECRET);
+      if (with_progress)
+        {
+          fputc ('\n', stdout);
+          fflush (stdout);
+        }
+      if (err)
+        {
+          fprintf (stderr, PGM ": error creating prime: %s\n",
+                   gpg_strerror (err));
+          exit (1);
+        }
+      gcry_mpi_release (prime);
+    }
+  stop_timer ();
+  if (with_progress)
+    printf ("%-10s", "prime");
+  printf (" %s\n", elapsed_time (1)); fflush (stdout);
+
+  single_char_progress = old_prog;
+}
+
+
 int
 main( int argc, char **argv )
 {
@@ -1294,7 +1667,6 @@ main( int argc, char **argv )
   int no_blinding = 0;
   int use_random_daemon = 0;
   int use_secmem = 0;
-  int with_progress = 0;
   int debug = 0;
   int pk_count = 100;
 
@@ -1325,7 +1697,7 @@ main( int argc, char **argv )
       else if (!strcmp (*argv, "--help"))
         {
           fputs ("usage: benchmark "
-                 "[md|mac|cipher|random|mpi|rsa|dsa|ecc [algonames]]\n",
+                 "[md|mac|cipher|random|mpi|rsa|dsa|ecc|prime [algonames]]\n",
                  stdout);
           exit (0);
         }
@@ -1499,6 +1871,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');
@@ -1547,11 +1920,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);
@@ -1562,6 +1948,11 @@ main( int argc, char **argv )
         gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
         ecc_bench (pk_count, 1);
     }
+  else if ( !strcmp (*argv, "prime"))
+    {
+        gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+        prime_bench ();
+    }
   else
     {
       fprintf (stderr, PGM ": bad arguments\n");
index 198693e..2732bbd 100644 (file)
@@ -29,7 +29,7 @@
 #include "../src/gcrypt-int.h"
 
 /* Number of curves defined in ../cipger/ecc.c */
-#define N_CURVES 15
+#define N_CURVES 22
 
 /* A real world sample public key.  */
 static char const sample_key_1[] =
@@ -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"
 "  ))";
@@ -169,6 +171,9 @@ check_get_params (void)
 
   gcry_sexp_release (param);
 
+  /* Brainpool curves are not supported in fips mode */
+  if (gcry_fips_mode_active())
+    return;
 
   param = gcry_pk_get_param (GCRY_PK_ECDSA, sample_key_2_curve);
   if (!param)
index 10b18ab..5ee829e 100644 (file)
@@ -434,6 +434,14 @@ check_dsa_gen_186_2 (void)
 }
 
 
+static void
+check_dsa_gen_186_3 (void)
+{
+  /* FIXME: Needs to be implemented.  */
+  if (verbose)
+    info ("generating FIPS 186-3 test keys - skipped\n");
+}
+
 
 int
 main (int argc, char **argv)
@@ -449,7 +457,7 @@ main (int argc, char **argv)
     }
 
   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
-  if (!gcry_check_version ("1.4.4"))
+  if (!gcry_check_version (GCRYPT_VERSION))
     die ("version mismatch\n");
   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
   if (debug)
@@ -459,6 +467,7 @@ main (int argc, char **argv)
 
 
   check_dsa_gen_186_2 ();
+  check_dsa_gen_186_3 ();
 
 
   return error_count ? 1 : 0;
index eef2ddd..49253cb 100644 (file)
@@ -41,7 +41,7 @@
 # define PACKAGE_BUGREPORT "devnull@example.org"
 # define PACKAGE_VERSION "[build on " __DATE__ " " __TIME__ "]"
 #endif
-
+#include "../src/gcrypt-testapi.h"
 
 #define PGM "fipsdrv"
 
 #define DIMof(type,member)   DIM(((type *)0)->member)
 
 
-#define PRIV_CTL_INIT_EXTRNG_TEST   58
-#define PRIV_CTL_RUN_EXTRNG_TEST    59
-#define PRIV_CTL_DEINIT_EXTRNG_TEST 60
-#define PRIV_CTL_DISABLE_WEAK_KEY   61
-#define PRIV_CTL_GET_INPUT_VECTOR   62
-
 
 /* Verbose mode flag.  */
 static int verbose;
@@ -1069,7 +1063,7 @@ run_encrypt_decrypt (int encrypt_mode,
   blocklen = gcry_cipher_get_algo_blklen (cipher_algo);
   assert (blocklen);
 
-  gcry_cipher_ctl (hd, PRIV_CTL_DISABLE_WEAK_KEY, NULL, 0);
+  gcry_cipher_ctl (hd, PRIV_CIPHERCTL_DISABLE_WEAK_KEY, NULL, 0);
 
   err = gcry_cipher_setkey (hd, key_buffer, key_buflen);
   if (err)
@@ -1124,7 +1118,7 @@ get_current_iv (gcry_cipher_hd_t hd, void *buffer, size_t buflen)
 {
   unsigned char tmp[17];
 
-  if (gcry_cipher_ctl (hd, PRIV_CTL_GET_INPUT_VECTOR, tmp, sizeof tmp))
+  if (gcry_cipher_ctl (hd, PRIV_CIPHERCTL_GET_INPUT_VECTOR, tmp, sizeof tmp))
     die ("error getting current input vector\n");
   if (buflen > *tmp)
     die ("buffer too short to store the current input vector\n");
@@ -1159,7 +1153,7 @@ run_cipher_mct_loop (int encrypt_mode, int cipher_algo, int cipher_mode,
     die ("invalid block length %d\n", blocklen);
 
 
-  gcry_cipher_ctl (hd, PRIV_CTL_DISABLE_WEAK_KEY, NULL, 0);
+  gcry_cipher_ctl (hd, PRIV_CIPHERCTL_DISABLE_WEAK_KEY, NULL, 0);
 
   err = gcry_cipher_setkey (hd, key_buffer, key_buflen);
   if (err)
@@ -1346,6 +1340,69 @@ run_rsa_derive (const void *data, size_t datalen)
 }
 
 
+/* Generate RSA key using the S-expression in (DATA,DATALEN).  This
+   S-expression is used directly as input to gcry_pk_genkey.  The
+   result is printed to stdout with one parameter per line in hex
+   format and in this order: e, p, q, n, d.  */
+static void
+run_rsa_keygen (const void *data, size_t datalen, int test)
+{
+  gpg_error_t err;
+  gcry_sexp_t s_keyspec, s_key, s_top, l1;
+  gcry_mpi_t mpi;
+  const char *parmlist;
+  int idx;
+
+  if (!datalen)
+    err = gpg_error (GPG_ERR_NO_DATA);
+  else
+    err = gcry_sexp_new (&s_keyspec, data, datalen, 1);
+  if (err)
+    die ("gcry_sexp_new failed for RSA key generation: %s\n",
+         gpg_strerror (err));
+
+  err = gcry_pk_genkey (&s_key, s_keyspec);
+
+  gcry_sexp_release (s_keyspec);
+
+  if (test) {
+       if (err)
+               printf("F\n");
+       else {
+               gcry_sexp_release (s_key);
+               printf("P\n");
+       }
+       return;
+  }
+
+  if (err)
+    die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err));
+
+  parmlist = "epqnd";
+
+  /* Parse and print the parameters.  */
+  l1 = gcry_sexp_find_token (s_key, "private-key", 0);
+  s_top = gcry_sexp_find_token (l1, "rsa", 0);
+  gcry_sexp_release (l1);
+  if (!s_top)
+    die ("private-key part not found in result\n");
+
+  for (idx=0; parmlist[idx]; idx++)
+    {
+      l1 = gcry_sexp_find_token (s_top, parmlist+idx, 1);
+      mpi = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+      gcry_sexp_release (l1);
+      if (!mpi)
+        die ("parameter %c missing in private-key\n", parmlist[idx]);
+      print_mpi_line (mpi, 1);
+      gcry_mpi_release (mpi);
+    }
+
+  gcry_sexp_release (s_top);
+  gcry_sexp_release (s_key);
+}
+
+
 \f
 static size_t
 compute_tag_length (size_t n)
@@ -1526,7 +1583,7 @@ run_rsa_gen (int keysize, int pubexp)
    encoded KEYFILE and the hash algorithm HASHALGO.  */
 static void
 run_rsa_sign (const void *data, size_t datalen,
-              int hashalgo, int pkcs1, const char *keyfile)
+              int hashalgo, int pkcs1, int pss, const char *keyfile)
 
 {
   gpg_error_t err;
@@ -1550,6 +1607,20 @@ run_rsa_sign (const void *data, size_t datalen,
                              gcry_md_algo_name (hashalgo),
                              (int)hashsize, hash);
     }
+  else if (pss)
+    {
+      unsigned char hash[64];
+      unsigned int hashsize;
+
+      hashsize = gcry_md_get_algo_dlen (hashalgo);
+      if (!hashsize || hashsize > sizeof hash)
+        die ("digest too long for buffer or unknown hash algorithm\n");
+      gcry_md_hash_buffer (hashalgo, hash, data, datalen);
+      err = gcry_sexp_build (&s_data, NULL,
+                             "(data (flags pss)(salt-length #00#)(hash %s %b))",
+                             gcry_md_algo_name (hashalgo),
+                             (int)hashsize, hash);
+    }
   else
     {
       gcry_mpi_t tmp;
@@ -1617,7 +1688,7 @@ run_rsa_sign (const void *data, size_t datalen,
    binary signature in SIGFILE.  */
 static void
 run_rsa_verify (const void *data, size_t datalen, int hashalgo, int pkcs1,
-                const char *keyfile, const char *sigfile)
+                int pss, const char *keyfile, const char *sigfile)
 
 {
   gpg_error_t err;
@@ -1637,6 +1708,20 @@ run_rsa_verify (const void *data, size_t datalen, int hashalgo, int pkcs1,
                              gcry_md_algo_name (hashalgo),
                              (int)hashsize, hash);
     }
+  else if (pss)
+    {
+      unsigned char hash[64];
+      unsigned int hashsize;
+
+      hashsize = gcry_md_get_algo_dlen (hashalgo);
+      if (!hashsize || hashsize > sizeof hash)
+        die ("digest too long for buffer or unknown hash algorithm\n");
+      gcry_md_hash_buffer (hashalgo, hash, data, datalen);
+      err = gcry_sexp_build (&s_data, NULL,
+                             "(data (flags pss)(salt-length #00#)(hash %s %b))",
+                             gcry_md_algo_name (hashalgo),
+                             (int)hashsize, hash);
+    }
   else
     {
       gcry_mpi_t tmp;
@@ -1727,6 +1812,33 @@ dsa_gen_with_seed (int keysize, const void *seed, size_t seedlen)
 }
 
 
+/* Generate an ECDSA key on the specified curve and return the complete
+   S-expression. */
+static gcry_sexp_t
+ecdsa_gen_key (const char *curve)
+{
+  gpg_error_t err;
+  gcry_sexp_t keyspec, key;
+
+  err = gcry_sexp_build (&keyspec, NULL,
+                         "(genkey"
+                         "  (ecc"
+                         "    (use-fips186)"
+                         "    (curve %s)))",
+                         curve);
+  if (err)
+    die ("gcry_sexp_build failed for ECDSA key generation: %s\n",
+         gpg_strerror (err));
+  err = gcry_pk_genkey (&key, keyspec);
+  if (err)
+    die ("gcry_pk_genkey failed for ECDSA: %s\n", gpg_strerror (err));
+
+  gcry_sexp_release (keyspec);
+
+  return key;
+}
+
+
 /* Print the domain parameter as well as the derive information.  KEY
    is the complete key as returned by dsa_gen.  We print to stdout
    with one parameter per line in hex format using this order: p, q,
@@ -1819,6 +1931,46 @@ print_dsa_domain_parameters (gcry_sexp_t key)
 }
 
 
+/* Print public key Q (in octet-string format) and private key d.
+   KEY is the complete key as returned by ecdsa_gen_key.
+   with one parameter per line in hex format using this order: d, Q. */
+static void
+print_ecdsa_dq (gcry_sexp_t key)
+{
+  gcry_sexp_t l1, l2;
+  gcry_mpi_t mpi;
+  int idx;
+
+  l1 = gcry_sexp_find_token (key, "private-key", 0);
+  if (!l1)
+    die ("private key not found in genkey result\n");
+
+  l2 = gcry_sexp_find_token (l1, "ecc", 0);
+  if (!l2)
+    die ("returned private key not formed as expected\n");
+  gcry_sexp_release (l1);
+  l1 = l2;
+
+  /* Extract the parameters from the S-expression and print them to stdout.  */
+  for (idx=0; "dq"[idx]; idx++)
+    {
+      l2 = gcry_sexp_find_token (l1, "dq"+idx, 1);
+      if (!l2)
+        die ("no %c parameter in returned public key\n", "dq"[idx]);
+      mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
+      if (!mpi)
+        die ("no value for %c parameter in returned private key\n","dq"[idx]);
+      gcry_sexp_release (l2);
+      if (standalone_mode)
+        printf ("%c = ", "dQ"[idx]);
+      print_mpi_line (mpi, 1);
+      gcry_mpi_release (mpi);
+    }
+
+  gcry_sexp_release (l1);
+}
+
+
 /* Generate DSA domain parameters for a modulus size of KEYSIZE.  The
    result is printed to stdout with one parameter per line in hex
    format and in this order: p, q, g, seed, counter, h.  If SEED is
@@ -1998,6 +2150,138 @@ run_dsa_verify (const void *data, size_t datalen,
 }
 
 
+\f
+/* Sign DATA of length DATALEN using the key taken from the S-expression
+   encoded KEYFILE. */
+static void
+run_ecdsa_sign (const void *data, size_t datalen,
+                const char *keyfile, const int algo)
+
+{
+  gpg_error_t err;
+  gcry_sexp_t s_data, s_key, s_sig, s_tmp;
+  char hash[128];
+  gcry_mpi_t tmpmpi;
+
+  s_key = read_sexp_from_file (keyfile);
+
+  gcry_md_hash_buffer (algo, hash, data, datalen);
+  err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash,
+                       gcry_md_get_algo_dlen(algo), NULL);
+  if (!err)
+    {
+      err = gcry_sexp_build (&s_data, NULL,
+                             "(data (flags raw)(hash %s %M))",
+                             gcry_md_algo_name(algo), tmpmpi);
+      gcry_mpi_release (tmpmpi);
+    }
+  if (err)
+    die ("gcry_sexp_build failed for ECDSA data input: %s\n",
+         gpg_strerror (err));
+
+  err = gcry_pk_sign (&s_sig, s_data, s_key);
+  if (err)
+    {
+      die ("gcry_pk_signed failed: %s\n", gpg_strerror (err));
+    }
+  gcry_sexp_release (s_data);
+  gcry_sexp_release (s_key);
+
+  /* Now return the actual signature.  */
+  s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0);
+  if (!s_tmp)
+    die ("no sig-val element in returned S-expression\n");
+
+  gcry_sexp_release (s_sig);
+  s_sig = s_tmp;
+  s_tmp = gcry_sexp_find_token (s_sig, "ecdsa", 0);
+  if (!s_tmp)
+    die ("no ecdsa element in returned S-expression\n");
+
+  gcry_sexp_release (s_sig);
+  s_sig = s_tmp;
+
+  s_tmp = gcry_sexp_find_token (s_sig, "r", 0);
+  tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG);
+  if (!tmpmpi)
+    die ("no r parameter in returned S-expression\n");
+  print_mpi_line (tmpmpi, 1);
+  gcry_mpi_release (tmpmpi);
+  gcry_sexp_release (s_tmp);
+
+  s_tmp = gcry_sexp_find_token (s_sig, "s", 0);
+  tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG);
+  if (!tmpmpi)
+    die ("no s parameter in returned S-expression\n");
+  print_mpi_line (tmpmpi, 1);
+  gcry_mpi_release (tmpmpi);
+  gcry_sexp_release (s_tmp);
+
+  gcry_sexp_release (s_sig);
+}
+
+
+\f
+/* Verify DATA of length DATALEN using the public key taken from the
+   S-expression in KEYFILE against the S-expression formatted
+   signature in SIGFILE.  */
+static void
+run_ecdsa_verify (const void *data, size_t datalen,
+                const char *keyfile, const int algo, const char *sigfile)
+
+{
+  gpg_error_t err;
+  gcry_sexp_t s_data, s_key, s_sig;
+  char hash[128];
+  gcry_mpi_t tmpmpi;
+
+  s_key = read_sexp_from_file (keyfile);
+
+  gcry_md_hash_buffer (algo, hash, data, datalen);
+  /* Note that we can't simply use %b with HASH to build the
+     S-expression, because that might yield a negative value.  */
+  err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash,
+                       gcry_md_get_algo_dlen(algo), NULL);
+  if (!err)
+    {
+      err = gcry_sexp_build (&s_data, NULL,
+                             "(data (flags raw)(hash %s %M))",
+                             gcry_md_algo_name(algo), tmpmpi);
+      gcry_mpi_release (tmpmpi);
+    }
+  if (err)
+    die ("gcry_sexp_build failed for DSA data input: %s\n",
+         gpg_strerror (err));
+
+  s_sig = read_sexp_from_file (sigfile);
+
+  err = gcry_pk_verify (s_sig, s_data, s_key);
+  if (!err)
+    puts ("GOOD signature");
+  else if (gpg_err_code (err) == GPG_ERR_BAD_SIGNATURE)
+    puts ("BAD signature");
+  else
+    printf ("ERROR (%s)\n", gpg_strerror (err));
+
+  gcry_sexp_release (s_sig);
+  gcry_sexp_release (s_key);
+  gcry_sexp_release (s_data);
+}
+
+
+/* Generate an ECDSA key with specified domain parameters
+   and print the d and Q values, in the standard octet-string format. */
+static void
+run_ecdsa_gen_key (const char *curve)
+{
+  gcry_sexp_t key;
+
+  key = ecdsa_gen_key (curve);
+  print_ecdsa_dq (key);
+
+  gcry_sexp_release (key);
+}
+
 
 \f
 static void
@@ -2014,7 +2298,8 @@ usage (int show_help)
      "Run a crypto operation using hex encoded input and output.\n"
      "MODE:\n"
      "  encrypt, decrypt, digest, random, hmac-sha,\n"
-     "  rsa-{derive,gen,sign,verify}, dsa-{pqg-gen,gen,sign,verify}\n"
+     "  rsa-{derive,gen,sign,verify},\n"
+     "  dsa-{pqg-gen,gen,sign,verify}, ecdsa-{gen-key,sign,verify}\n"
      "OPTIONS:\n"
      "  --verbose        Print additional information\n"
      "  --binary         Input and output is in binary form\n"
@@ -2023,10 +2308,12 @@ usage (int show_help)
      "  --iv IV          Use the hex encoded IV\n"
      "  --dt DT          Use the hex encoded DT for the RNG\n"
      "  --algo NAME      Use algorithm NAME\n"
+     "  --curve NAME     Select ECC curve spec NAME\n"
      "  --keysize N      Use a keysize of N bits\n"
      "  --signature NAME Take signature from file NAME\n"
      "  --chunk N        Read in chunks of N bytes (implies --binary)\n"
      "  --pkcs1          Use PKCS#1 encoding\n"
+     "  --pss            Use PSS encoding with a zero length salt\n"
      "  --mct-server     Run a monte carlo test server\n"
      "  --loop           Enable random loop mode\n"
      "  --progress       Print pogress indicators\n"
@@ -2044,7 +2331,9 @@ main (int argc, char **argv)
   int no_fips = 0;
   int progress = 0;
   int use_pkcs1 = 0;
+  int use_pss = 0;
   const char *mode_string;
+  const char *curve_string = NULL;
   const char *key_string = NULL;
   const char *iv_string = NULL;
   const char *dt_string = NULL;
@@ -2160,11 +2449,24 @@ main (int argc, char **argv)
           binary_input = binary_output = 1;
           argc--; argv++;
         }
+      else if (!strcmp (*argv, "--curve"))
+        {
+          argc--; argv++;
+          if (!argc)
+            usage (0);
+          curve_string = *argv;
+          argc--; argv++;
+        }
       else if (!strcmp (*argv, "--pkcs1"))
         {
           use_pkcs1 = 1;
           argc--; argv++;
         }
+      else if (!strcmp (*argv, "--pss"))
+        {
+          use_pss = 1;
+          argc--; argv++;
+        }
       else if (!strcmp (*argv, "--mct-server"))
         {
           mct_server = 1;
@@ -2179,8 +2481,12 @@ main (int argc, char **argv)
 
   if (!argc || argc > 2)
     usage (0);
+
   mode_string = *argv;
 
+  if (use_pkcs1 && use_pss)
+    die ("Only one of --pkcs or --pss may be given\n");
+
   if (!strcmp (mode_string, "rsa-derive"))
     binary_input = 1;
 
@@ -2217,7 +2523,10 @@ main (int argc, char **argv)
       && !mct_server
       && strcmp (mode_string, "random")
       && strcmp (mode_string, "rsa-gen")
-      && strcmp (mode_string, "dsa-gen") )
+      && strcmp (mode_string, "rsa-keygen")
+      && strcmp (mode_string, "rsa-keygen-kat")
+      && strcmp (mode_string, "dsa-gen")
+      && strcmp (mode_string, "ecdsa-gen-key") )
     {
       data = read_file (input, !binary_input, &datalen);
       if (!data)
@@ -2358,14 +2667,14 @@ main (int argc, char **argv)
             {
               if (!(++count % 1000))
                 fprintf (stderr, PGM ": %lu random bytes so far\n",
-                         (unsigned long int)count * sizeof buffer);
+                         (unsigned long int)(count * sizeof buffer));
             }
         }
       while (loop_mode);
 
       if (progress)
         fprintf (stderr, PGM ": %lu random bytes\n",
-                         (unsigned long int)count * sizeof buffer);
+                 (unsigned long int)(count * sizeof buffer));
 
       deinit_external_rng_test (context);
     }
@@ -2406,6 +2715,20 @@ main (int argc, char **argv)
         die ("no data available (do not use --chunk)\n");
       run_rsa_derive (data, datalen);
     }
+  else if (!strcmp (mode_string, "rsa-keygen"))
+    {
+      data = read_file (input, 0, &datalen);
+      if (!data)
+        die ("no data available (do not use --chunk)\n");
+      run_rsa_keygen (data, datalen, 0);
+    }
+  else if (!strcmp (mode_string, "rsa-keygen-kat"))
+    {
+      data = read_file (input, 0, &datalen);
+      if (!data)
+        die ("no data available (do not use --chunk)\n");
+      run_rsa_keygen (data, datalen, 1);
+    }
   else if (!strcmp (mode_string, "rsa-gen"))
     {
       int keysize;
@@ -2434,7 +2757,7 @@ main (int argc, char **argv)
       if (!data)
         die ("no data available (do not use --chunk)\n");
 
-      run_rsa_sign (data, datalen, algo, use_pkcs1, key_string);
+      run_rsa_sign (data, datalen, algo, use_pkcs1, use_pss, key_string);
 
     }
   else if (!strcmp (mode_string, "rsa-verify"))
@@ -2457,7 +2780,7 @@ main (int argc, char **argv)
       if (access (signature_string, R_OK))
         die ("option --signature needs to specify an existing file\n");
 
-      run_rsa_verify (data, datalen, algo, use_pkcs1, key_string,
+      run_rsa_verify (data, datalen, algo, use_pkcs1, use_pss, key_string,
                       signature_string);
 
     }
@@ -2507,6 +2830,53 @@ main (int argc, char **argv)
 
       run_dsa_verify (data, datalen, key_string, signature_string);
     }
+  else if (!strcmp (mode_string, "ecdsa-gen-key"))
+    {
+      if (!curve_string)
+        die ("option --curve containing name of the specified curve is required in this mode\n");
+      run_ecdsa_gen_key (curve_string);
+    }
+  else if (!strcmp (mode_string, "ecdsa-sign"))
+    {
+      int algo;
+
+      if (!key_string)
+        die ("option --key is required in this mode\n");
+      if (access (key_string, R_OK))
+        die ("option --key needs to specify an existing keyfile\n");
+      if (!algo_string)
+        die ("use --algo to specify the digest algorithm\n");
+      algo = gcry_md_map_name (algo_string);
+      if (!algo)
+        die ("digest algorithm `%s' is not supported\n", algo_string);
+
+      if (!data)
+        die ("no data available (do not use --chunk)\n");
+
+      run_ecdsa_sign (data, datalen, key_string, algo);
+    }
+  else if (!strcmp (mode_string, "ecdsa-verify"))
+    {
+      int algo;
+
+      if (!key_string)
+        die ("option --key is required in this mode\n");
+      if (access (key_string, R_OK))
+        die ("option --key needs to specify an existing keyfile\n");
+      if (!algo_string)
+        die ("use --algo to specify the digest algorithm\n");
+      algo = gcry_md_map_name (algo_string);
+      if (!algo)
+        die ("digest algorithm `%s' is not supported\n", algo_string);
+      if (!data)
+        die ("no data available (do not use --chunk)\n");
+      if (!signature_string)
+        die ("option --signature is required in this mode\n");
+      if (access (signature_string, R_OK))
+        die ("option --signature needs to specify an existing file\n");
+
+      run_ecdsa_verify (data, datalen, key_string, algo, signature_string);
+    }
   else
     usage (0);
 
diff --git a/tests/gchash.c b/tests/gchash.c
new file mode 100644 (file)
index 0000000..7ff99e0
--- /dev/null
@@ -0,0 +1,120 @@
+/* gchash.c - Calculate hash values
+ * Copyright (C) 2013 Dmitry Eremin-Solenikov
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#ifdef _GCRYPT_IN_LIBGCRYPT
+# undef _GCRYPT_IN_LIBGCRYPT
+# include "gcrypt.h"
+#else
+# include <gcrypt.h>
+#endif
+
+
+void
+init_gcrypt (void)
+{
+  if (!gcry_check_version (GCRYPT_VERSION)) {
+    fputs ("libgcrypt version mismatch\n", stderr);
+    exit (2);
+  }
+
+  gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
+
+  /* Allocate a pool of 16k secure memory.  This make the secure memory
+   * available and also drops privileges where needed.  */
+  gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
+
+  gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
+
+  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+}
+
+int
+main (int argc, char **argv)
+{
+  gcry_md_hd_t hd;
+  gcry_error_t err;
+  int algo;
+
+  init_gcrypt();
+
+  if (argc < 2 || (argv[1] && !strcmp(argv[1], "--help")))
+    {
+      fprintf (stderr, "Usage: %s <digest> <file>...\n", argv[0]);
+      return 1;
+    }
+
+  algo = gcry_md_map_name (argv[1]);
+  if (algo == GCRY_MD_NONE)
+    {
+      fprintf (stderr, "Unknown algorithm '%s'\n", argv[1]);
+      return 1;
+    }
+
+  err = gcry_md_open(&hd, algo, 0);
+  if (err)
+    {
+      fprintf (stderr, "LibGCrypt error %s/%s\n",
+          gcry_strsource (err),
+          gcry_strerror (err));
+      exit (1);
+    }
+
+  for (argv += 2; *argv; argv++)
+    {
+      FILE *fp;
+      unsigned char buf[1024];
+      size_t size;
+      int i;
+      unsigned char *h;
+      if (!strcmp (*argv, "-"))
+        fp = stdin;
+      else
+        fp = fopen (*argv, "r");
+
+      if (fp == NULL)
+        {
+          perror ("fopen");
+          return 1;
+        }
+
+      while (!feof (fp))
+        {
+          size = fread (buf, 1, sizeof(buf), fp);
+          gcry_md_write (hd, buf, size);
+        }
+
+      h  = gcry_md_read(hd, 0);
+
+      for (i = 0; i < gcry_md_get_algo_dlen (algo); i++)
+        printf("%02x", h[i]);
+      printf("  %s\n", *argv);
+
+      gcry_md_reset(hd);
+    }
+
+  gcry_md_close(hd);
+  return 0;
+}
index 6fbce0c..33907fb 100644 (file)
@@ -102,6 +102,22 @@ static struct {
     "49920704ea9d6ee19f0742d6c868110fa3eda8ac09f026e9ef22cc731af53020"
     "de40eedef66cb1afd94c61e285fa9327e01336e804903740a9145ab1f065c2d5" },
 
+  { GCRY_MD_SHA3_512, 256, -64,
+    "c6e082b3db996dbe5f2c5709818a7f325ef4febd883d7e9c545c06bfa7225198"
+    "1ecf40103788913cd5a5bdf13246b952ded6651043684b24197eb23544882a97" },
+  { GCRY_MD_SHA3_512, 256,  -1,
+    "d7bf28e8216bf7d3d0d3969e34078e94b98598e17b6f21f256379389e4eba8ee"
+    "74eb288774797263fec00bdfd357d132cea9e408be36b982f5a60ab56ad01613" },
+  { GCRY_MD_SHA3_512, 256,  +0,
+    "c1270852ba7b1e1a3eaa777969b8a65be28c3894537c61eb8cd22b1df6af703d"
+    "b59939f6adadeb64317faece8167d4817e73daf73e28a5ccd26bebee0a35c322" },
+  { GCRY_MD_SHA3_512, 256,  +1,
+    "8bdfeb3a1a9a1cdcef21172cbc5bb3b87c0d8f7111df0aaf7f1bc03ad4775bd6"
+    "a03e0a875c4e7d02d2230c213562c6a57be28d92eaf6e4bea4bc24690454c8ef" },
+  { GCRY_MD_SHA3_512, 256, +64,
+    "0c91b91665ceaf7af5102e0ed31aa4f050668ab3c57b1f4763946d567efe66b3"
+    "ab9a2016cf238dee5b44eae9f0cdfbf7b7a6eb1e759986273243dc35894706b6" },
+
   { 0 }
 };
 
@@ -484,6 +500,6 @@ main (int argc, char **argv)
 
   if (verbose)
     show ("All tests completed in %s.  Errors: %d\n",
-          elapsed_time (), error_count);
+          elapsed_time (1), error_count);
   return !!error_count;
 }
index 4aff9c9..c4520e9 100644 (file)
@@ -1,5 +1,6 @@
 /* keygen.c  -  key generation regression tests
  * Copyright (C) 2003, 2005, 2012 Free Software Foundation, Inc.
+ * Copyright (C) 2013, 2015 g10 Code GmbH
  *
  * This file is part of Libgcrypt.
  *
@@ -14,8 +15,7 @@
  * GNU Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifdef HAVE_CONFIG_H
@@ -40,6 +40,7 @@
 static int verbose;
 static int debug;
 static int error_count;
+static int in_fips_mode;
 
 
 static void
@@ -196,6 +197,20 @@ check_rsa_keys (void)
   int rc;
 
   if (verbose)
+    show ("creating 2048 bit RSA key\n");
+  rc = gcry_sexp_new (&keyparm,
+                      "(genkey\n"
+                      " (rsa\n"
+                      "  (nbits 4:2048)\n"
+                      " ))", 0, 1);
+  if (rc)
+    die ("error creating S-expression: %s\n", gpg_strerror (rc));
+  rc = gcry_pk_genkey (&key, keyparm);
+  gcry_sexp_release (keyparm);
+  if (rc)
+    die ("error generating RSA key: %s\n", gpg_strerror (rc));
+
+  if (verbose)
     show ("creating 1024 bit RSA key\n");
   rc = gcry_sexp_new (&keyparm,
                       "(genkey\n"
@@ -204,13 +219,40 @@ check_rsa_keys (void)
                       " ))", 0, 1);
   if (rc)
     die ("error creating S-expression: %s\n", gpg_strerror (rc));
+
+  gcry_sexp_release (key);
+  rc = gcry_pk_genkey (&key, keyparm);
+  gcry_sexp_release (keyparm);
+  if (rc && !in_fips_mode)
+    fail ("error generating RSA key: %s\n", gpg_strerror (rc));
+  else if (!rc && in_fips_mode)
+    fail ("generating 1024 bit RSA key must not work!");
+
+  if (!rc)
+    {
+      if (verbose > 1)
+        show_sexp ("1024 bit RSA key:\n", key);
+      check_generated_rsa_key (key, 65537);
+    }
+  gcry_sexp_release (key);
+
+  if (verbose)
+    show ("creating 2048 bit RSA key with e=65539\n");
+  rc = gcry_sexp_new (&keyparm,
+                      "(genkey\n"
+                      " (rsa\n"
+                      "  (nbits 4:2048)\n"
+                      "  (rsa-use-e 5:65539)\n"
+                      " ))", 0, 1);
+  if (rc)
+    die ("error creating S-expression: %s\n", gpg_strerror (rc));
   rc = gcry_pk_genkey (&key, keyparm);
   gcry_sexp_release (keyparm);
   if (rc)
-    die ("error generating RSA key: %s\n", gpg_strerror (rc));
-  if (verbose > 1)
-    show_sexp ("1024 bit RSA key:\n", key);
-  check_generated_rsa_key (key, 65537);
+    fail ("error generating RSA key: %s\n", gpg_strerror (rc));
+
+  if (!rc)
+    check_generated_rsa_key (key, 65539);
   gcry_sexp_release (key);
 
 
@@ -226,10 +268,17 @@ check_rsa_keys (void)
     die ("error creating S-expression: %s\n", gpg_strerror (rc));
   rc = gcry_pk_genkey (&key, keyparm);
   gcry_sexp_release (keyparm);
-  if (rc)
-    die ("error generating RSA key: %s\n", gpg_strerror (rc));
+  if (rc && !in_fips_mode)
+    fail ("error generating RSA key: %s\n", gpg_strerror (rc));
+  else if (!rc && in_fips_mode)
+    fail ("generating 512 bit RSA key must not work!");
+
+  if (verbose && rc && in_fips_mode)
+    show ("... correctly rejected key creation in FIPS mode (%s)\n",
+          gpg_strerror (rc));
 
-  check_generated_rsa_key (key, 257);
+  if (!rc)
+    check_generated_rsa_key (key, 257);
   gcry_sexp_release (key);
 
   if (verbose)
@@ -244,10 +293,18 @@ check_rsa_keys (void)
     die ("error creating S-expression: %s\n", gpg_strerror (rc));
   rc = gcry_pk_genkey (&key, keyparm);
   gcry_sexp_release (keyparm);
-  if (rc)
-    die ("error generating RSA key: %s\n", gpg_strerror (rc));
+  if (rc && !in_fips_mode)
+    fail ("error generating RSA key: %s\n", gpg_strerror (rc));
+  else if (!rc && in_fips_mode)
+    fail ("generating 512 bit RSA key must not work!");
 
-  check_generated_rsa_key (key, 0); /* We don't expect a constant exponent. */
+  if (verbose && rc && in_fips_mode)
+    show ("... correctly rejected key creation in FIPS mode (%s)\n",
+          gpg_strerror (rc));
+
+
+  if (!rc)
+    check_generated_rsa_key (key, 0); /* We don't expect a constant exponent. */
   gcry_sexp_release (key);
 }
 
@@ -299,8 +356,10 @@ check_dsa_keys (void)
         die ("error creating S-expression: %s\n", gpg_strerror (rc));
       rc = gcry_pk_genkey (&key, keyparm);
       gcry_sexp_release (keyparm);
-      if (rc)
+      if (rc && !in_fips_mode)
         die ("error generating DSA key: %s\n", gpg_strerror (rc));
+      else if (!rc && in_fips_mode)
+        die ("generating 1024 bit DSA key must not work!");
       if (!i && verbose > 1)
         show_sexp ("1024 bit DSA key:\n", key);
       gcry_sexp_release (key);
@@ -318,11 +377,67 @@ check_dsa_keys (void)
     die ("error creating S-expression: %s\n", gpg_strerror (rc));
   rc = gcry_pk_genkey (&key, keyparm);
   gcry_sexp_release (keyparm);
-  if (rc)
+  if (rc && !in_fips_mode)
     die ("error generating DSA key: %s\n", gpg_strerror (rc));
+  else if (!rc && in_fips_mode)
+    die ("generating 1536 bit DSA key must not work!");
   if (verbose > 1)
     show_sexp ("1536 bit DSA key:\n", key);
   gcry_sexp_release (key);
+
+  if (verbose)
+    show ("creating 3072 bit DSA key\n");
+  rc = gcry_sexp_new (&keyparm,
+                      "(genkey\n"
+                      " (dsa\n"
+                      "  (nbits 4:3072)\n"
+                      "  (qbits 3:256)\n"
+                      " ))", 0, 1);
+  if (rc)
+    die ("error creating S-expression: %s\n", gpg_strerror (rc));
+  rc = gcry_pk_genkey (&key, keyparm);
+  gcry_sexp_release (keyparm);
+  if (rc)
+    die ("error generating DSA key: %s\n", gpg_strerror (rc));
+  if (verbose > 1)
+    show_sexp ("3072 bit DSA key:\n", key);
+  gcry_sexp_release (key);
+
+  if (verbose)
+    show ("creating 2048/256 bit DSA key\n");
+  rc = gcry_sexp_new (&keyparm,
+                      "(genkey\n"
+                      " (dsa\n"
+                      "  (nbits 4:2048)\n"
+                      "  (qbits 3:256)\n"
+                      " ))", 0, 1);
+  if (rc)
+    die ("error creating S-expression: %s\n", gpg_strerror (rc));
+  rc = gcry_pk_genkey (&key, keyparm);
+  gcry_sexp_release (keyparm);
+  if (rc)
+    die ("error generating DSA key: %s\n", gpg_strerror (rc));
+  if (verbose > 1)
+    show_sexp ("2048 bit DSA key:\n", key);
+  gcry_sexp_release (key);
+
+  if (verbose)
+    show ("creating 2048/224 bit DSA key\n");
+  rc = gcry_sexp_new (&keyparm,
+                      "(genkey\n"
+                      " (dsa\n"
+                      "  (nbits 4:2048)\n"
+                      "  (qbits 3:224)\n"
+                      " ))", 0, 1);
+  if (rc)
+    die ("error creating S-expression: %s\n", gpg_strerror (rc));
+  rc = gcry_pk_genkey (&key, keyparm);
+  gcry_sexp_release (keyparm);
+  if (rc)
+    die ("error generating DSA key: %s\n", gpg_strerror (rc));
+  if (verbose > 1)
+    show_sexp ("2048 bit DSA key:\n", key);
+  gcry_sexp_release (key);
 }
 
 
@@ -375,9 +490,14 @@ check_ecc_keys (void)
       if (verbose)
         show ("creating ECC key using curve %s\n", curves[testno]);
       if (!strcmp (curves[testno], "Ed25519"))
-        rc = gcry_sexp_build (&keyparm, NULL,
-                              "(genkey(ecc(curve %s)(flags param eddsa)))",
-                              curves[testno]);
+        {
+          /* Ed25519 isn't allowed in fips mode */
+          if (in_fips_mode)
+            continue;
+          rc = gcry_sexp_build (&keyparm, NULL,
+                                "(genkey(ecc(curve %s)(flags param eddsa)))",
+                                curves[testno]);
+        }
       else
         rc = gcry_sexp_build (&keyparm, NULL,
                               "(genkey(ecc(curve %s)(flags param)))",
@@ -405,9 +525,59 @@ check_ecc_keys (void)
     die ("error creating S-expression: %s\n", gpg_strerror (rc));
   rc = gcry_pk_genkey (&key, keyparm);
   gcry_sexp_release (keyparm);
-  if (rc)
+  if (rc && !in_fips_mode)
     die ("error generating ECC key using curve Ed25519 for ECDSA: %s\n",
          gpg_strerror (rc));
+  else if (!rc && in_fips_mode)
+    fail ("generating Ed25519 key must not work!");
+
+  if (verbose && rc && in_fips_mode)
+    show ("... correctly rejected key creation in FIPS mode (%s)\n",
+          gpg_strerror (rc));
+
+  if (!rc)
+    {
+      if (verbose > 1)
+        show_sexp ("ECC key:\n", key);
+
+      check_generated_ecc_key (key);
+    }
+  gcry_sexp_release (key);
+
+  if (verbose)
+    show ("creating ECC key using curve Ed25519 for ECDSA (nocomp)\n");
+  rc = gcry_sexp_build (&keyparm, NULL,
+                        "(genkey(ecc(curve Ed25519)(flags nocomp)))");
+  if (rc)
+    die ("error creating S-expression: %s\n", gpg_strerror (rc));
+  rc = gcry_pk_genkey (&key, keyparm);
+  gcry_sexp_release (keyparm);
+  if (rc && !in_fips_mode)
+    die ("error generating ECC key using curve Ed25519 for ECDSA"
+         " (nocomp): %s\n",
+         gpg_strerror (rc));
+  else if (!rc && in_fips_mode)
+    fail ("generating Ed25519 key must not work in FIPS mode!");
+
+  if (verbose && rc && in_fips_mode)
+    show ("... correctly rejected key creation in FIPS mode (%s)\n",
+          gpg_strerror (rc));
+  gcry_sexp_release (key);
+
+  if (verbose)
+    show ("creating ECC key using curve NIST P-384 for ECDSA\n");
+
+  /* Must be specified as nistp384 (one word), because ecc_generate
+   * uses _gcry_sexp_nth_string which takes the first word of the name
+   * and thus libgcrypt can't find it later in its curves table.  */
+  rc = gcry_sexp_build (&keyparm, NULL, "(genkey(ecc(curve nistp384)))");
+  if (rc)
+    die ("error creating S-expression: %s\n", gpg_strerror (rc));
+  rc = gcry_pk_genkey (&key, keyparm);
+  gcry_sexp_release (keyparm);
+  if (rc)
+    die ("error generating ECC key using curve NIST P-384 for ECDSA: %s\n",
+         gpg_strerror (rc));
 
   if (verbose > 1)
     show_sexp ("ECC key:\n", key);
@@ -416,15 +586,15 @@ check_ecc_keys (void)
   gcry_sexp_release (key);
 
   if (verbose)
-    show ("creating ECC key using curve Ed25519 for ECDSA (nocomp)\n");
+    show ("creating ECC key using curve NIST P-384 for ECDSA (nocomp)\n");
   rc = gcry_sexp_build (&keyparm, NULL,
-                        "(genkey(ecc(curve Ed25519)(flags nocomp)))");
+                        "(genkey(ecc(curve nistp384)(flags nocomp)))");
   if (rc)
     die ("error creating S-expression: %s\n", gpg_strerror (rc));
   rc = gcry_pk_genkey (&key, keyparm);
   gcry_sexp_release (keyparm);
   if (rc)
-    die ("error generating ECC key using curve Ed25519 for ECDSA"
+    die ("error generating ECC key using curve NIST P-384 for ECDSA"
          " (nocomp): %s\n",
          gpg_strerror (rc));
 
@@ -432,7 +602,63 @@ check_ecc_keys (void)
     show_sexp ("ECC key:\n", key);
 
   check_generated_ecc_key (key);
+  gcry_sexp_release (key);
 
+
+  if (verbose)
+    show ("creating ECC key using curve Ed25519 for ECDSA (transient-key)\n");
+  rc = gcry_sexp_build (&keyparm, NULL,
+                        "(genkey(ecc(curve Ed25519)(flags transient-key)))");
+  if (rc)
+    die ("error creating S-expression: %s\n", gpg_strerror (rc));
+  rc = gcry_pk_genkey (&key, keyparm);
+  gcry_sexp_release (keyparm);
+  if (rc && !in_fips_mode)
+    die ("error generating ECC key using curve Ed25519 for ECDSA"
+         " (transient-key): %s\n",
+         gpg_strerror (rc));
+  else if (!rc && in_fips_mode)
+    fail ("generating Ed25519 key must not work in FIPS mode!");
+
+  if (verbose && rc && in_fips_mode)
+    show ("... correctly rejected key creation in FIPS mode (%s)\n",
+          gpg_strerror (rc));
+
+  if (!rc)
+    {
+      if (verbose > 1)
+        show_sexp ("ECC key:\n", key);
+      check_generated_ecc_key (key);
+    }
+  gcry_sexp_release (key);
+
+  if (verbose)
+    show ("creating ECC key using curve Ed25519 for ECDSA "
+          "(transient-key no-keytest)\n");
+  rc = gcry_sexp_build (&keyparm, NULL,
+                        "(genkey(ecc(curve Ed25519)"
+                        "(flags transient-key no-keytest)))");
+  if (rc)
+    die ("error creating S-expression: %s\n", gpg_strerror (rc));
+  rc = gcry_pk_genkey (&key, keyparm);
+  gcry_sexp_release (keyparm);
+  if (rc && !in_fips_mode)
+    die ("error generating ECC key using curve Ed25519 for ECDSA"
+         " (transient-key no-keytest): %s\n",
+         gpg_strerror (rc));
+  else if (!rc && in_fips_mode)
+    fail ("generating Ed25519 key must not work in FIPS mode!");
+
+  if (verbose && rc && in_fips_mode)
+    show ("... correctly rejected key creation in FIPS mode (%s)\n",
+          gpg_strerror (rc));
+
+  if (!rc)
+    {
+      if (verbose > 1)
+        show_sexp ("ECC key:\n", key);
+      check_generated_ecc_key (key);
+    }
   gcry_sexp_release (key);
 }
 
@@ -500,6 +726,7 @@ usage (int mode)
          "Options:\n"
          "  --verbose       be verbose\n"
          "  --debug         flyswatter\n"
+         "  --fips          run in FIPS mode\n"
          "  --progress      print progress indicators\n",
          mode? stderr : stdout);
   if (mode)
@@ -510,6 +737,7 @@ int
 main (int argc, char **argv)
 {
   int last_argc = -1;
+  int opt_fips = 0;
   int with_progress = 0;
 
   if (argc)
@@ -539,6 +767,11 @@ main (int argc, char **argv)
           debug++;
           argc--; argv++;
         }
+      else if (!strcmp (*argv, "--fips"))
+        {
+          argc--; argv++;
+          opt_fips = 1;
+        }
       else if (!strcmp (*argv, "--progress"))
         {
           argc--; argv++;
@@ -550,9 +783,16 @@ main (int argc, char **argv)
         break;
     }
 
+  gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose);
+  if (opt_fips)
+    gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0);
+
   if (!gcry_check_version (GCRYPT_VERSION))
     die ("version mismatch\n");
-  gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+
+  if (!opt_fips)
+    gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+
   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
   if (debug)
     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
@@ -561,6 +801,12 @@ main (int argc, char **argv)
   if (with_progress)
     gcry_set_progress_handler (progress_cb, NULL);
 
+  if ( gcry_fips_mode_active () )
+    in_fips_mode = 1;
+
+  if (opt_fips && !in_fips_mode)
+    die ("failed to switch into FIPS mode\n");
+
   if (!argc)
     {
       check_rsa_keys ();
index 72960ea..3ef1de1 100644 (file)
@@ -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"
     },
index d75aca9..b663029 100644 (file)
@@ -237,6 +237,42 @@ test_opaque (void)
 
 
 static void
+test_maxsize (void)
+{
+  gpg_error_t err;
+  gcry_mpi_t a;
+  char buffer[2+2048]; /* For PGP: 2 length bytes and 16384 bits.  */
+
+  memset (buffer, 0x55, sizeof buffer);
+
+  /* We use a short buffer but a give a too large length to simulate a
+   * programming error.  In case this test fails (i.e. die() is
+   * called) the scan function may have access data outside of BUFFER
+   * which may result in a segv but we ignore that to avoid actually
+   * allocating such a long buffer.  */
+  err = gcry_mpi_scan (&a, GCRYMPI_FMT_USG, buffer, 16*1024*1024 +1, NULL);
+  if (gpg_err_code (err) != GPG_ERR_INV_OBJ)
+    die ("gcry_mpi_scan does not detect its generic input limit\n");
+
+  /* Now test the PGP limit.  The scan code check the two length bytes
+   * from the buffer and thus it is sufficient to fake them.  */
+  buffer[0] = (16385 >> 8);
+  buffer[1] = (16385 & 0xff);
+  err = gcry_mpi_scan (&a, GCRYMPI_FMT_PGP, buffer, sizeof buffer, NULL);
+  if (gpg_err_code (err) != GPG_ERR_INV_OBJ)
+    die ("gcry_mpi_scan does not detect the PGP input limit\n");
+
+  buffer[0] = (16384 >> 8);
+  buffer[1] = (16384 & 0xff);
+
+  err = gcry_mpi_scan (&a, GCRYMPI_FMT_PGP, buffer, sizeof buffer, NULL);
+  if (err)
+    die ("gcry_mpi_scan did not parse a large PGP: %s\n", gpg_strerror (err));
+  gcry_mpi_release (a);
+}
+
+
+static void
 test_cmp (void)
 {
   gpg_error_t rc;
@@ -426,7 +462,7 @@ test_mul (void)
 
 
 /* What we test here is that we don't overwrite our args and that
-   using thne same mpi for several args works.  */
+   using the same mpi for several args works.  */
 static int
 test_powm (void)
 {
@@ -569,6 +605,7 @@ main (int argc, char* argv[])
 
   test_const_and_immutable ();
   test_opaque ();
+  test_maxsize ();
   test_cmp ();
   test_add ();
   test_sub ();
index ae5eea2..b691913 100644 (file)
@@ -165,6 +165,33 @@ show_sexp (const char *prefix, gcry_sexp_t a)
   gcry_free (buf);
 }
 
+/* from ../cipher/pubkey-util.c */
+gpg_err_code_t
+_gcry_pk_util_get_nbits (gcry_sexp_t list, unsigned int *r_nbits)
+{
+  char buf[50];
+  const char *s;
+  size_t n;
+
+  *r_nbits = 0;
+
+  list = gcry_sexp_find_token (list, "nbits", 0);
+  if (!list)
+    return 0; /* No NBITS found.  */
+
+  s = gcry_sexp_nth_data (list, 1, &n);
+  if (!s || n >= DIM (buf) - 1 )
+    {
+      /* NBITS given without a cdr.  */
+      gcry_sexp_release (list);
+      return GPG_ERR_INV_OBJ;
+    }
+  memcpy (buf, s, n);
+  buf[n] = 0;
+  *r_nbits = (unsigned int)strtoul (buf, NULL, 0);
+  gcry_sexp_release (list);
+  return 0;
+}
 
 /* Convert STRING consisting of hex characters into its binary
    representation and return it as an allocated buffer. The valid
@@ -354,7 +381,7 @@ get_keys_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
   int rc;
 
   rc = gcry_sexp_new (&key_spec,
-                     "(genkey (rsa (nbits 4:1024)))", 0, 1);
+                     "(genkey (rsa (nbits 4:2048)))", 0, 1);
   if (rc)
     die ("error creating S-expression: %s\n", gcry_strerror (rc));
   rc = gcry_pk_genkey (&key, key_spec);
@@ -386,7 +413,7 @@ get_keys_x931_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
   int rc;
 
   rc = gcry_sexp_new (&key_spec,
-                     "(genkey (rsa (nbits 4:1024)(use-x931)))", 0, 1);
+                     "(genkey (rsa (nbits 4:2048)(use-x931)))", 0, 1);
   if (rc)
     die ("error creating S-expression: %s\n", gcry_strerror (rc));
   rc = gcry_pk_genkey (&key, key_spec);
@@ -456,8 +483,8 @@ get_dsa_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey, int transient_key)
 
   rc = gcry_sexp_new (&key_spec,
                       transient_key
-                      ? "(genkey (dsa (nbits 4:1024)(transient-key)))"
-                      : "(genkey (dsa (nbits 4:1024)))",
+                      ? "(genkey (dsa (nbits 4:2048)(transient-key)))"
+                      : "(genkey (dsa (nbits 4:2048)))",
                       0, 1);
   if (rc)
     die ("error creating S-expression: %s\n", gcry_strerror (rc));
@@ -490,7 +517,7 @@ get_dsa_key_fips186_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
   int rc;
 
   rc = gcry_sexp_new
-    (&key_spec, "(genkey (dsa (nbits 4:1024)(use-fips186)))",  0, 1);
+    (&key_spec, "(genkey (dsa (nbits 4:2048)(use-fips186)))",  0, 1);
   if (rc)
     die ("error creating S-expression: %s\n", gcry_strerror (rc));
   rc = gcry_pk_genkey (&key, key_spec);
@@ -557,6 +584,7 @@ get_dsa_key_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
   *skey = sec_key;
 }
 
+#if 0
 static void
 get_dsa_key_fips186_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
 {
@@ -598,7 +626,7 @@ get_dsa_key_fips186_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
   *pkey = pub_key;
   *skey = sec_key;
 }
-
+#endif /*0*/
 
 static void
 get_dsa_key_fips186_with_seed_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
@@ -610,7 +638,7 @@ get_dsa_key_fips186_with_seed_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
     (&key_spec,
      "(genkey"
      "  (dsa"
-     "    (nbits 4:1024)"
+     "    (nbits 4:2048)"
      "    (use-fips186)"
      "    (transient-key)"
      "    (derive-parms"
@@ -722,12 +750,14 @@ check_run (void)
   gcry_sexp_release (pkey);
   gcry_sexp_release (skey);
 
+  /* We need new test vectors for get_dsa_key_fips186_with_domain_new.  */
   if (verbose)
-    fprintf (stderr, "Generating DSA key with given domain (FIPS 186).\n");
-  get_dsa_key_fips186_with_domain_new (&pkey, &skey);
-  /* Fixme:  Add a check function for DSA keys.  */
-  gcry_sexp_release (pkey);
-  gcry_sexp_release (skey);
+    fprintf (stderr, "Generating DSA key with given domain (FIPS 186)"
+             " - skipped.\n");
+  /* get_dsa_key_fips186_with_domain_new (&pkey, &skey); */
+  /* /\* Fixme:  Add a check function for DSA keys.  *\/ */
+  /* gcry_sexp_release (pkey); */
+  /* gcry_sexp_release (skey); */
 
   if (verbose)
     fprintf (stderr, "Generating DSA key with given seed (FIPS 186).\n");
@@ -903,8 +933,8 @@ check_x931_derived_key (int what)
     }
   };
   gpg_error_t err;
-  gcry_sexp_t key_spec, key, pub_key, sec_key;
-  gcry_mpi_t d_expected, d_have;
+  gcry_sexp_t key_spec = NULL, key = NULL, pub_key = NULL, sec_key = NULL;
+  gcry_mpi_t d_expected = NULL, d_have = NULL;
 
   if (what < 0 && what >= sizeof testtable)
     die ("invalid WHAT value\n");
@@ -913,10 +943,25 @@ check_x931_derived_key (int what)
   if (err)
     die ("error creating S-expression [%d]: %s\n", what, gpg_strerror (err));
 
+  {
+    unsigned nbits;
+    err = _gcry_pk_util_get_nbits(key_spec, &nbits);
+    if (err)
+      die ("nbits not found\n");
+    if (gcry_fips_mode_active() && nbits < 2048)
+      {
+        info("RSA key test with %d bits skipped in fips mode\n", nbits);
+        goto leave;
+      }
+  }
+
   err = gcry_pk_genkey (&key, key_spec);
   gcry_sexp_release (key_spec);
   if (err)
-    die ("error generating RSA key [%d]: %s\n", what, gpg_strerror (err));
+    {
+      fail ("error generating RSA key [%d]: %s\n", what, gpg_strerror (err));
+      goto leave;
+    }
 
   pub_key = gcry_sexp_find_token (key, "public-key", 0);
   if (!pub_key)
@@ -942,6 +987,7 @@ check_x931_derived_key (int what)
       show_sexp (NULL, sec_key);
       die ("parameter d does match expected value [%d]\n", what);
     }
+leave:
   gcry_mpi_release (d_expected);
   gcry_mpi_release (d_have);
 
@@ -1197,7 +1243,8 @@ main (int argc, char **argv)
     check_x931_derived_key (i);
 
   check_ecc_sample_key ();
-  check_ed25519ecdsa_sample_key ();
+  if (!gcry_fips_mode_active ())
+    check_ed25519ecdsa_sample_key ();
 
   return !!error_count;
 }
index 10bf646..3c08726 100644 (file)
 
 #define PGM "random"
 
+#ifndef DIM
+# define DIM(v)                     (sizeof(v)/sizeof((v)[0]))
+#endif
+
 
 static int verbose;
 static int debug;
@@ -87,7 +91,7 @@ progress_cb (void *cb_data, const char *what, int printchar,
 }
 
 
-
+#ifndef HAVE_W32_SYSTEM
 static int
 writen (int fd, const void *buf, size_t nbytes)
 {
@@ -110,7 +114,10 @@ writen (int fd, const void *buf, size_t nbytes)
 
   return 0;
 }
+#endif /*!HAVE_W32_SYSTEM*/
 
+
+#ifndef HAVE_W32_SYSTEM
 static int
 readn (int fd, void *buf, size_t buflen, size_t *ret_nread)
 {
@@ -136,7 +143,7 @@ readn (int fd, void *buf, size_t buflen, size_t *ret_nread)
     *ret_nread = buflen - nleft;
   return 0;
 }
-
+#endif /*!HAVE_W32_SYSTEM*/
 
 
 /* Check that forking won't return the same random. */
@@ -427,6 +434,86 @@ check_early_rng_type_switching (void)
 }
 
 
+static void
+check_drbg_reinit (void)
+{
+  static struct { const char *flags; } tv[] = {
+    { NULL },
+    { "" },
+    { "sha1" },
+    { "sha1 pr" },
+    { "sha256" },
+    { "sha256 pr" },
+    { "sha512" },
+    { "sha512 pr" },
+    { "hmac sha1" },
+    { "hmac sha1 pr" },
+    { "hmac sha256" },
+    { "hmac sha256 pr" },
+    { "hmac sha512" },
+    { "hmac sha512 pr" },
+    { "aes sym128" },
+    { "aes sym128 pr" },
+    { "aes sym192" },
+    { "aes sym192 pr" },
+    { "aes sym256" },
+    { "aes sym256 pr" }
+  };
+  int tidx;
+  gpg_error_t err;
+  char pers_string[] = "I'm a doctor, not an engineer.";
+  gcry_buffer_t pers[1];
+
+  if (verbose)
+    inf ("checking DRBG_REINIT\n");
+
+  memset (pers, 0, sizeof pers);
+  pers[0].data = pers_string;
+  pers[0].len = strlen (pers_string);
+
+  err = gcry_control (GCRYCTL_DRBG_REINIT, "", NULL, 0, &err);
+  if (gpg_err_code (err) != GPG_ERR_INV_ARG)
+    die ("gcry_control(DRBG_REINIT) guard value did not work\n");
+
+  err = gcry_control (GCRYCTL_DRBG_REINIT, "", NULL, -1, NULL);
+  if (gpg_err_code (err) != GPG_ERR_INV_ARG)
+    die ("gcry_control(DRBG_REINIT) npers negative detection failed\n");
+
+  if (rng_type () != GCRY_RNG_TYPE_FIPS)
+    {
+      err = gcry_control (GCRYCTL_DRBG_REINIT, "", NULL, 0, NULL);
+      if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED)
+        die ("DRBG_REINIT worked despite that DRBG is not active\n");
+      return;
+    }
+
+  err = gcry_control (GCRYCTL_DRBG_REINIT, "", NULL, 1, NULL);
+  if (gpg_err_code (err) != GPG_ERR_INV_ARG)
+    die ("_gcry_rngdrbg_reinit failed to detact: (!pers && npers)\n");
+  err = gcry_control (GCRYCTL_DRBG_REINIT, "", pers, 2, NULL);
+  if (gpg_err_code (err) != GPG_ERR_INV_ARG)
+    die ("_gcry_rngdrbg_reinit failed to detect: (pers && npers != 1)\n");
+
+  err = gcry_control (GCRYCTL_DRBG_REINIT, "aes sym128 bad pr ", pers, 1, NULL);
+  if (gpg_err_code (err) != GPG_ERR_INV_FLAG)
+    die ("_gcry_rngdrbg_reinit failed to detect a bad flag\n");
+
+  for (tidx=0; tidx < DIM(tv); tidx++)
+    {
+      err = gcry_control (GCRYCTL_DRBG_REINIT, tv[tidx].flags, NULL, 0, NULL);
+      if (err)
+        die ("_gcry_rngdrbg_reinit failed for \"%s\" w/o pers: %s\n",
+
+             tv[tidx].flags, gpg_strerror (err));
+      err = gcry_control (GCRYCTL_DRBG_REINIT, tv[tidx].flags, pers, 1, NULL);
+      if (err)
+        die ("_gcry_rngdrbg_reinit failed for \"%s\" with pers: %s\n",
+             tv[tidx].flags, gpg_strerror (err));
+      /* fixme: We should extract some random after each test.  */
+    }
+}
+
+
 /* Because we want to check initialization behaviour, we need to
    fork/exec this program with several command line arguments.  We use
    system, so that these tests work also on Windows.  */
@@ -560,7 +647,11 @@ main (int argc, char **argv)
 #endif
 
   if (early_rng)
-    check_early_rng_type_switching ();
+    {
+      /* Don't switch RNG in fips mode. */
+      if (!gcry_fips_mode_active())
+        check_early_rng_type_switching ();
+    }
 
   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
   if (!gcry_check_version (GCRYPT_VERSION))
@@ -579,7 +670,14 @@ main (int argc, char **argv)
       check_nonce_forking ();
       check_close_random_device ();
     }
-  check_rng_type_switching ();
+  /* For now we do not run the drgb_reinit check from "make check" due
+     to its high requirement for entropy.  */
+  if (!getenv ("GCRYPT_IN_REGRESSION_TEST"))
+    check_drbg_reinit ();
+
+  /* Don't switch RNG in fips mode.  */
+  if (!gcry_fips_mode_active())
+    check_rng_type_switching ();
 
   if (!in_recursion)
     run_all_rng_tests (program);
diff --git a/tests/sha3-224.h b/tests/sha3-224.h
new file mode 100644 (file)
index 0000000..46c1b05
--- /dev/null
@@ -0,0 +1,1025 @@
+/* Generated from https://raw.githubusercontent.com/gvanas/KeccakCodePackage/master/TestVectors/ShortMsgKAT_SHA3-224.txt */
+      { GCRY_MD_SHA3_224,
+       "",
+       "\x6b\x4e\x03\x42\x36\x67\xdb\xb7\x3b\x6e\x15\x45\x4f\x0e\xb1\xab\xd4\x59\x7f\x9a\x1b\x07\x8e\x3f\x5b\x5a\x6b\xc7",
+       0 },
+      { GCRY_MD_SHA3_224,
+       "\xcc",
+       "\xdf\x70\xad\xc4\x9b\x2e\x76\xee\xe3\xa6\x93\x1b\x93\xfa\x41\x84\x1c\x3a\xf2\xcd\xf5\xb3\x2a\x18\xb5\x47\x8c\x39",
+       1 },
+      { GCRY_MD_SHA3_224,
+       "\x41\xfb",
+       "\xbf\xf2\x95\x86\x1d\xae\xdf\x33\xe7\x05\x19\xb1\xe2\xbc\xb4\xc2\xe9\xfe\x33\x64\xd7\x89\xbc\x3b\x17\x30\x1c\x15",
+       2 },
+      { GCRY_MD_SHA3_224,
+       "\x1f\x87\x7c",
+       "\x14\x88\x9d\xf4\x9c\x07\x6a\x9a\xf2\xf4\xbc\xb1\x63\x39\xbc\xc4\x5a\x24\xeb\xf9\xce\x4d\xcd\xce\x7e\xc1\x72\x17",
+       3 },
+      { GCRY_MD_SHA3_224,
+       "\xc1\xec\xfd\xfc",
+       "\xa3\x3c\x58\xdf\x8a\x80\x26\xf0\xf9\x59\x19\x66\xbd\x6d\x00\xee\xd3\xb1\xe8\x29\x58\x0a\xb9\xbe\x26\x8c\xaf\x39",
+       4 },
+      { GCRY_MD_SHA3_224,
+       "\x21\xf1\x34\xac\x57",
+       "\x10\xe5\x80\xa3\x21\x99\x59\x61\x69\x33\x1a\xd4\x3c\xfc\xf1\x02\x64\xf8\x15\x65\x03\x70\x40\x02\x8a\x06\xb4\x58",
+       5 },
+      { GCRY_MD_SHA3_224,
+       "\xc6\xf5\x0b\xb7\x4e\x29",
+       "\xfe\x52\xc3\x0c\x95\xc1\xe5\x19\x32\x07\xe9\x7d\x35\x5f\xde\x09\x45\x34\x82\x70\x8c\x08\x76\xaa\x96\x15\x08\xf0",
+       6 },
+      { GCRY_MD_SHA3_224,
+       "\x11\x97\x13\xcc\x83\xee\xef",
+       "\x8b\x44\x98\x49\xcb\x7c\x47\x76\xc5\x93\xde\x58\xfd\x5c\x2e\x32\x2c\xb5\x31\x6b\xe0\x8a\x75\x05\x7a\x01\xed\x6a",
+       7 },
+      { GCRY_MD_SHA3_224,
+       "\x4a\x4f\x20\x24\x84\x51\x25\x26",
+       "\x01\x38\x6c\xdd\x70\x58\x9b\x3b\x34\x94\x1e\xfe\x16\xb8\x50\x71\xe9\xba\x94\x81\x79\x92\x20\x44\xf6\x40\x86\x8e",
+       8 },
+      { GCRY_MD_SHA3_224,
+       "\x1f\x66\xab\x41\x85\xed\x9b\x63\x75",
+       "\x86\x95\x3d\x08\x64\x01\x9c\x81\xfd\x3a\x80\x53\x57\xa1\x62\xfd\x76\xa1\x3a\x7c\xbf\x6f\xf0\xd6\x35\x01\x5d\x0e",
+       9 },
+      { GCRY_MD_SHA3_224,
+       "\xee\xd7\x42\x22\x27\x61\x3b\x6f\x53\xc9",
+       "\xe5\x6f\xc2\xa5\xa5\x87\x09\x03\x1d\xf0\x2a\x2e\x46\xad\x95\xf9\x35\x83\xe2\x74\x56\x30\x54\x0d\x8d\x97\xf7\x03",
+       10 },
+      { GCRY_MD_SHA3_224,
+       "\xea\xee\xd5\xcd\xff\xd8\x9d\xec\xe4\x55\xf1",
+       "\x1d\x78\x3c\x37\xc3\x2a\x2b\x71\xb5\x04\xbc\xaa\x05\xfc\x00\xb6\x39\xf1\xfa\xe7\xe8\xd8\xe3\xf3\xbc\x49\xf0\x41",
+       11 },
+      { GCRY_MD_SHA3_224,
+       "\x5b\xe4\x3c\x90\xf2\x29\x02\xe4\xfe\x8e\xd2\xd3",
+       "\x54\xc7\xe4\xbf\x3c\x73\xe1\x92\xad\xe2\x23\xdf\xea\x86\xf2\xd0\x4a\xcf\x95\x36\x12\x73\x19\x58\xf8\x54\xc7\xbd",
+       12 },
+      { GCRY_MD_SHA3_224,
+       "\xa7\x46\x27\x32\x28\x12\x2f\x38\x1c\x3b\x46\xe4\xf1",
+       "\x77\xe5\x1c\xea\xda\x2a\xa1\xcb\xbf\x95\xac\xd8\x21\x00\x8b\x57\xe9\x46\xf7\x94\x02\x23\xb1\x9f\x0c\x53\xe6\x2e",
+       13 },
+      { GCRY_MD_SHA3_224,
+       "\x3c\x58\x71\xcd\x61\x9c\x69\xa6\x3b\x54\x0e\xb5\xa6\x25",
+       "\x9e\xd5\x9e\xd1\x55\xe9\x71\x54\xe0\x67\xfa\x0f\x5a\x13\x08\x39\xb5\x7b\xdb\xda\x6f\xeb\x82\xda\xbe\x00\x6f\x00",
+       14 },
+      { GCRY_MD_SHA3_224,
+       "\xfa\x22\x87\x4b\xcc\x06\x88\x79\xe8\xef\x11\xa6\x9f\x07\x22",
+       "\x81\xb3\xe5\x6c\xfe\xee\x8e\x91\x38\xd3\xbf\xe2\x4b\xb7\xcc\xdf\xd4\xb5\x0d\x0b\x8c\xa1\x1a\xe7\xd4\xb0\xc9\x60",
+       15 },
+      { GCRY_MD_SHA3_224,
+       "\x52\xa6\x08\xab\x21\xcc\xdd\x8a\x44\x57\xa5\x7e\xde\x78\x21\x76",
+       "\xb1\x57\x1b\xed\x52\xe5\x4e\xef\x37\x7d\x99\xdf\x7b\xe4\xbc\x66\x82\xc4\x33\x87\xf2\xbf\x9a\xcc\x92\xdf\x60\x8f",
+       16 },
+      { GCRY_MD_SHA3_224,
+       "\x82\xe1\x92\xe4\x04\x3d\xdc\xd1\x2e\xcf\x52\x96\x9d\x0f\x80\x7e\xed",
+       "\x08\x04\x5c\xf7\x8d\x23\x8d\x56\x97\x2f\x1c\x85\x04\x14\xbc\x40\x4f\xc6\xdc\xb1\x1f\x8d\x82\x10\xd0\x34\xc6\x10",
+       17 },
+      { GCRY_MD_SHA3_224,
+       "\x75\x68\x3d\xcb\x55\x61\x40\xc5\x22\x54\x3b\xb6\xe9\x09\x8b\x21\xa2\x1e",
+       "\x9f\xfd\x84\x0c\x55\x0a\xd2\x39\x71\xeb\x5c\xe8\x9a\xe2\xfd\x62\x22\xab\xfb\x7f\x0a\xaf\xd7\xeb\x00\x05\x71\x6b",
+       18 },
+      { GCRY_MD_SHA3_224,
+       "\x06\xe4\xef\xe4\x50\x35\xe6\x1f\xaa\xf4\x28\x7b\x4d\x8d\x1f\x12\xca\x97\xe5",
+       "\x72\xde\xcb\x5e\xa1\xb2\x5a\x2d\xaa\xeb\x23\x4a\x8d\x96\xe0\xf5\x72\x11\x42\x66\x66\xa2\xee\x76\xb2\x38\x5c\x62",
+       19 },
+      { GCRY_MD_SHA3_224,
+       "\xe2\x61\x93\x98\x9d\x06\x56\x8f\xe6\x88\xe7\x55\x40\xae\xa0\x67\x47\xd9\xf8\x51",
+       "\xa5\x89\x93\x63\x70\xa3\xd2\x00\x39\xc4\x69\xd4\x4a\x1c\x26\xe6\x28\x23\xab\x28\xcc\x50\x17\x5a\x98\x97\xf9\x8e",
+       20 },
+      { GCRY_MD_SHA3_224,
+       "\xd8\xdc\x8f\xde\xfb\xdc\xe9\xd4\x4e\x4c\xba\xfe\x78\x44\x7b\xae\x3b\x54\x36\x10\x2a",
+       "\x96\xf4\x34\x01\xad\x49\xc5\x8d\x88\x70\x20\xf3\x95\xbd\xd0\x1f\x6d\xad\x04\x12\x8a\x85\xb1\x77\x80\x40\x8c\x37",
+       21 },
+      { GCRY_MD_SHA3_224,
+       "\x57\x08\x5f\xd7\xe1\x42\x16\xab\x10\x2d\x83\x17\xb0\xcb\x33\x8a\x78\x6d\x5f\xc3\x2d\x8f",
+       "\xa3\xa0\xf0\xc5\x52\xe7\xcd\x27\x23\xfe\x22\xe1\xd5\x71\x9e\x21\x3d\x9a\x3d\xa1\xdb\x99\xe3\x2e\xff\xfd\x0f\x46",
+       22 },
+      { GCRY_MD_SHA3_224,
+       "\xa0\x54\x04\xdf\x5d\xbb\x57\x69\x7e\x2c\x16\xfa\x29\xde\xfa\xc8\xab\x35\x60\xd6\x12\x6f\xa0",
+       "\xe9\x91\xf4\xa1\x4b\x56\xdc\x6b\x22\x4e\xf3\x52\xae\x8b\xc8\xca\xe8\xb1\xaf\x1c\x25\xc6\x73\x3d\xfb\x7f\xfe\x1f",
+       23 },
+      { GCRY_MD_SHA3_224,
+       "\xae\xcb\xb0\x27\x59\xf7\x43\x3d\x6f\xcb\x06\x96\x3c\x74\x06\x1c\xd8\x3b\x5b\x3f\xfa\x6f\x13\xc6",
+       "\x71\x88\x66\xc2\x1c\xbe\x3f\x29\x13\x64\xc0\x7b\x36\x07\x8a\x6b\xf0\xb8\x25\x8b\x0e\xc1\x55\xe2\xe2\xb1\xaf\x23",
+       24 },
+      { GCRY_MD_SHA3_224,
+       "\xaa\xfd\xc9\x24\x3d\x3d\x4a\x09\x65\x58\xa3\x60\xcc\x27\xc8\xd8\x62\xf0\xbe\x73\xdb\x5e\x88\xaa\x55",
+       "\x23\x60\x6d\x06\xfd\x8f\x87\xc2\x20\x5a\xbb\x5f\xd0\x4c\x33\xeb\xa3\x05\x09\x95\x52\x00\x56\x6a\x0f\x77\x2b\x49",
+       25 },
+      { GCRY_MD_SHA3_224,
+       "\x7b\xc8\x48\x67\xf6\xf9\xe9\xfd\xc3\xe1\x04\x6c\xae\x3a\x52\xc7\x7e\xd4\x85\x86\x0e\xe2\x60\xe3\x0b\x15",
+       "\x05\x93\x5f\x0a\xd2\x26\x44\x75\xdf\x34\xfa\x96\xf6\xa9\x11\x8c\x32\xb2\x17\xe8\x61\x69\xeb\x7a\xde\x4e\x2f\xdb",
+       26 },
+      { GCRY_MD_SHA3_224,
+       "\xfa\xc5\x23\x57\x5a\x99\xec\x48\x27\x9a\x7a\x45\x9e\x98\xff\x90\x19\x18\xa4\x75\x03\x43\x27\xef\xb5\x58\x43",
+       "\xfb\xec\x83\xcb\xdb\x6d\x08\xc7\xbf\xdd\xc2\xe3\x7f\x73\xb1\x6d\xc9\x29\x26\xa5\xc2\x3d\xab\x41\xde\xeb\xfb\x1b",
+       27 },
+      { GCRY_MD_SHA3_224,
+       "\x0f\x8b\x2d\x8f\xcf\xd9\xd6\x8c\xff\xc1\x7c\xcf\xb1\x17\x70\x9b\x53\xd2\x64\x62\xa3\xf3\x46\xfb\x7c\x79\xb8\x5e",
+       "\x1e\x69\x3b\x0b\xce\x23\x72\x55\x0d\xae\xf3\x5b\x14\xf1\x3a\xb4\x34\x41\xed\x67\x42\xde\xe3\xe8\x6f\xd1\xd8\xef",
+       28 },
+      { GCRY_MD_SHA3_224,
+       "\xa9\x63\xc3\xe8\x95\xff\x5a\x0b\xe4\x82\x44\x00\x51\x8d\x81\x41\x2f\x87\x5f\xa5\x05\x21\xe2\x6e\x85\xea\xc9\x0c\x04",
+       "\x17\x81\xf1\x34\x4d\xc1\x7f\x67\x85\x71\xf4\xe5\xdf\x39\x98\xb1\xd3\x8b\x1d\x83\x60\x2b\x53\xb9\xb6\xf2\x83\xd6",
+       29 },
+      { GCRY_MD_SHA3_224,
+       "\x03\xa1\x86\x88\xb1\x0c\xc0\xed\xf8\x3a\xdf\x0a\x84\x80\x8a\x97\x18\x38\x3c\x40\x70\xc6\xc4\xf2\x95\x09\x86\x99\xac\x2c",
+       "\x03\xb7\x4b\x7d\x8f\xc1\xf2\x3f\x76\xba\xb2\xb6\xc3\x5f\x29\x2c\x15\x50\x6d\xe6\x49\x78\xfc\xf6\xd9\x97\x3f\xce",
+       30 },
+      { GCRY_MD_SHA3_224,
+       "\x84\xfb\x51\xb5\x17\xdf\x6c\x5a\xcc\xb5\xd0\x22\xf8\xf2\x8d\xa0\x9b\x10\x23\x2d\x42\x32\x0f\xfc\x32\xdb\xec\xc3\x83\x5b\x29",
+       "\x6a\x68\x57\xfb\xa9\x03\xb9\xda\x27\x53\x69\x0c\x39\xc5\x48\xbe\x00\x8e\x22\xeb\xb3\x72\xee\xaa\x16\xc8\x59\x18",
+       31 },
+      { GCRY_MD_SHA3_224,
+       "\x9f\x2f\xcc\x7c\x90\xde\x09\x0d\x6b\x87\xcd\x7e\x97\x18\xc1\xea\x6c\xb2\x11\x18\xfc\x2d\x5d\xe9\xf9\x7e\x5d\xb6\xac\x1e\x9c\x10",
+       "\x88\x79\x21\x84\x8a\xd9\x84\x58\xf3\xdb\x3e\x0e\xcd\x5a\xd5\xdb\x1f\x0b\xf9\xf2\xd0\xca\x08\x60\x10\x74\xd5\x97",
+       32 },
+      { GCRY_MD_SHA3_224,
+       "\xde\x8f\x1b\x3f\xaa\x4b\x70\x40\xed\x45\x63\xc3\xb8\xe5\x98\x25\x31\x78\xe8\x7e\x4d\x0d\xf7\x5e\x4f\xf2\xf2\xde\xdd\x5a\x0b\xe0\x46",
+       "\xe0\x57\x3a\xd7\x06\xb4\x4d\x8c\x4d\x20\x4f\x88\x4b\x95\xab\x18\x91\x3e\x76\xf4\x1c\xf2\x9a\x16\xdb\xe3\x47\x94",
+       33 },
+      { GCRY_MD_SHA3_224,
+       "\x62\xf1\x54\xec\x39\x4d\x0b\xc7\x57\xd0\x45\xc7\x98\xc8\xb8\x7a\x00\xe0\x65\x5d\x04\x81\xa7\xd2\xd9\xfb\x58\xd9\x3a\xed\xc6\x76\xb5\xa0",
+       "\xba\x31\x23\x30\x99\x05\x54\x83\xc9\x9f\x7a\xd8\x2d\x0d\x24\xaf\x48\x7e\xd4\xb5\x3f\xff\x1a\x89\x2a\x55\xdd\xb3",
+       34 },
+      { GCRY_MD_SHA3_224,
+       "\xb2\xdc\xfe\x9f\xf1\x9e\x2b\x23\xce\x7d\xa2\xa4\x20\x7d\x3e\x5e\xc7\xc6\x11\x2a\x8a\x22\xae\xc9\x67\x5a\x88\x63\x78\xe1\x4e\x5b\xfb\xad\x4e",
+       "\xbe\xfa\xa1\xcb\x47\xcf\x78\xdd\xd4\xe0\x96\xb8\x61\xbc\x34\x0b\x77\x6f\x52\xe3\x51\xeb\xe3\x78\xad\xe3\x05\xba",
+       35 },
+      { GCRY_MD_SHA3_224,
+       "\x47\xf5\x69\x7a\xc8\xc3\x14\x09\xc0\x86\x88\x27\x34\x7a\x61\x3a\x35\x62\x04\x1c\x63\x3c\xf1\xf1\xf8\x68\x65\xa5\x76\xe0\x28\x35\xed\x2c\x24\x92",
+       "\xf1\xe7\xa1\xb2\x8e\xa4\xd6\xfb\x86\x57\x0f\x66\x91\x1e\x32\x58\xc3\xf4\x9f\x89\x16\x54\xfb\xce\x9b\xc7\x9b\x8b",
+       36 },
+      { GCRY_MD_SHA3_224,
+       "\x51\x2a\x6d\x29\x2e\x67\xec\xb2\xfe\x48\x6b\xfe\x92\x66\x09\x53\xa7\x54\x84\xff\x4c\x4f\x2e\xca\x2b\x0a\xf0\xed\xcd\xd4\x33\x9c\x6b\x2e\xe4\xe5\x42",
+       "\xc2\xb3\x17\x46\x44\x69\x34\xfe\x29\xe8\x4c\xfb\x5c\x25\xb0\x3b\xe3\x3e\x90\x04\xf7\x4e\x91\xc1\xaf\x0d\xb7\x89",
+       37 },
+      { GCRY_MD_SHA3_224,
+       "\x97\x3c\xf2\xb4\xdc\xf0\xbf\xa8\x72\xb4\x11\x94\xcb\x05\xbb\x4e\x16\x76\x0a\x18\x40\xd8\x34\x33\x01\x80\x25\x76\x19\x7e\xc1\x9e\x2a\x14\x93\xd8\xf4\xfb",
+       "\x3a\x80\x64\x5f\xe4\x27\x13\x46\xaa\xed\xc3\xae\x50\x11\xb7\x5d\xf1\x63\xfa\xd3\xee\x61\x28\xd8\x7f\x3d\x9d\xa3",
+       38 },
+      { GCRY_MD_SHA3_224,
+       "\x80\xbe\xeb\xcd\x2e\x3f\x8a\x94\x51\xd4\x49\x99\x61\xc9\x73\x1a\xe6\x67\xcd\xc2\x4e\xa0\x20\xce\x3b\x9a\xa4\xbb\xc0\xa7\xf7\x9e\x30\xa9\x34\x46\x7d\xa4\xb0",
+       "\x3c\x5e\xbe\x43\xa2\x57\x1b\xce\xf2\x5e\x4e\xa6\x7a\x4c\xa9\x83\x87\x70\xd2\x35\x99\x05\x99\x55\xaf\x93\xff\x83",
+       39 },
+      { GCRY_MD_SHA3_224,
+       "\x7a\xba\xa1\x2e\xc2\xa7\x34\x76\x74\xe4\x44\x14\x0a\xe0\xfb\x65\x9d\x08\xe1\xc6\x6d\xec\xd8\xd6\xea\xe9\x25\xfa\x45\x1d\x65\xf3\xc0\x30\x8e\x29\x44\x6b\x8e\xd3",
+       "\xaf\x71\xda\xb0\xf3\x3d\x3b\x48\x73\x3a\xd6\x33\x5c\xa6\x09\x39\x8d\x89\x4e\x6f\xa9\x6f\x55\x10\xae\x73\xe5\xd2",
+       40 },
+      { GCRY_MD_SHA3_224,
+       "\xc8\x8d\xee\x99\x27\x67\x9b\x8a\xf4\x22\xab\xcb\xac\xf2\x83\xb9\x04\xff\x31\xe1\xca\xc5\x8c\x78\x19\x80\x9f\x65\xd5\x80\x7d\x46\x72\x3b\x20\xf6\x7b\xa6\x10\xc2\xb7",
+       "\xdd\x75\x12\xda\xa0\xc6\x34\xcc\x15\x88\x87\x0b\x84\x69\x1d\x7d\xe2\xc1\x82\xe5\x57\x0d\x57\x86\x8e\x7d\xda\x5d",
+       41 },
+      { GCRY_MD_SHA3_224,
+       "\x01\xe4\x3f\xe3\x50\xfc\xec\x45\x0e\xc9\xb1\x02\x05\x3e\x6b\x5d\x56\xe0\x98\x96\xe0\xdd\xd9\x07\x4f\xe1\x38\xe6\x03\x82\x10\x27\x0c\x83\x4c\xe6\xea\xdc\x2b\xb8\x6b\xf6",
+       "\x6c\xb4\xf9\x29\x2b\xa3\x3c\xa8\xd2\x93\xb7\xa7\xef\x76\x61\x9e\x77\x30\x9b\xa2\x17\x8c\xd4\xa1\x30\xbf\x92\x18",
+       42 },
+      { GCRY_MD_SHA3_224,
+       "\x33\x70\x23\x37\x0a\x48\xb6\x2e\xe4\x35\x46\xf1\x7c\x4e\xf2\xbf\x8d\x7e\xcd\x1d\x49\xf9\x0b\xab\x60\x4b\x83\x9c\x2e\x6e\x5b\xd2\x15\x40\xd2\x9b\xa2\x7a\xb8\xe3\x09\xa4\xb7",
+       "\xa9\xb8\x43\x5e\x55\xfc\x50\xfe\x93\x5e\xc9\x67\x98\xa6\x29\xc1\x3e\x85\x6c\x3c\x5c\xfd\x24\x81\x26\x97\x6e\x0d",
+       43 },
+      { GCRY_MD_SHA3_224,
+       "\x68\x92\x54\x0f\x96\x4c\x8c\x74\xbd\x2d\xb0\x2c\x0a\xd8\x84\x51\x0c\xb3\x8a\xfd\x44\x38\xaf\x31\xfc\x91\x27\x56\xf3\xef\xec\x6b\x32\xb5\x8e\xbc\x38\xfc\x2a\x6b\x91\x35\x96\xa8",
+       "\x93\xe7\x98\x50\x62\x2b\x91\xf7\x29\xab\x05\x6e\xa4\x02\xe2\x7f\x01\xb5\x32\x31\x58\x11\x1b\x29\x36\x2a\x96\xd5",
+       44 },
+      { GCRY_MD_SHA3_224,
+       "\xf5\x96\x1d\xfd\x2b\x1f\xff\xfd\xa4\xff\xbf\x30\x56\x0c\x16\x5b\xfe\xda\xb8\xce\x0b\xe5\x25\x84\x5d\xeb\x8d\xc6\x10\x04\xb7\xdb\x38\x46\x72\x05\xf5\xdc\xfb\x34\xa2\xac\xfe\x96\xc0",
+       "\x7e\x51\xd5\x53\x13\x82\x49\x06\x70\x11\x5d\xe1\x31\x37\xcb\x3a\xdb\x6e\x76\x21\xb7\xd9\xec\xa8\x17\x0f\xaa\x96",
+       45 },
+      { GCRY_MD_SHA3_224,
+       "\xca\x06\x1a\x2e\xb6\xce\xed\x88\x81\xce\x20\x57\x17\x2d\x86\x9d\x73\xa1\x95\x1e\x63\xd5\x72\x61\x38\x4b\x80\xce\xb5\x45\x1e\x77\xb0\x6c\xf0\xf5\xa0\xea\x15\xca\x90\x7e\xe1\xc2\x7e\xba",
+       "\x95\xc3\x50\x37\xa8\x07\x69\x26\xfc\x5c\x42\x1c\x35\x16\x0a\xc5\xfe\x53\x3a\x27\x82\xf2\x0f\x2d\x3f\x4b\x1b\x7d",
+       46 },
+      { GCRY_MD_SHA3_224,
+       "\x17\x43\xa7\x72\x51\xd6\x92\x42\x75\x0c\x4f\x11\x40\x53\x2c\xd3\xc3\x3f\x9b\x5c\xcd\xf7\x51\x4e\x85\x84\xd4\xa5\xf9\xfb\xd7\x30\xbc\xf8\x4d\x0d\x47\x26\x36\x4b\x9b\xf9\x5a\xb2\x51\xd9\xbb",
+       "\xbf\x02\x4a\x4f\xe4\x80\x63\x61\x18\xfc\xc8\x5b\x80\x77\x04\xd5\x9b\x64\xd1\x6a\x15\x0a\xa5\x3c\xde\x41\xf0\x30",
+       47 },
+      { GCRY_MD_SHA3_224,
+       "\xd8\xfa\xba\x1f\x51\x94\xc4\xdb\x5f\x17\x6f\xab\xff\xf8\x56\x92\x4e\xf6\x27\xa3\x7c\xd0\x8c\xf5\x56\x08\xbb\xa8\xf1\xe3\x24\xd7\xc7\xf1\x57\x29\x8e\xab\xc4\xdc\xe7\xd8\x9c\xe5\x16\x24\x99\xf9",
+       "\xb7\xa5\x1f\xbb\x08\x4d\xee\xb5\x51\x36\xef\xd7\x26\x0e\x5b\x11\x2e\x3c\x40\xd1\xa2\xd1\x4b\x14\x2d\xf9\x30\xdf",
+       48 },
+      { GCRY_MD_SHA3_224,
+       "\xbe\x96\x84\xbe\x70\x34\x08\x60\x37\x3c\x9c\x48\x2b\xa5\x17\xe8\x99\xfc\x81\xba\xaa\x12\xe5\xc6\xd7\x72\x79\x75\xd1\xd4\x1b\xa8\xbe\xf7\x88\xcd\xb5\xcf\x46\x06\xc9\xc1\xc7\xf6\x1a\xed\x59\xf9\x7d",
+       "\x61\xcf\x83\x0a\x2c\x4f\x8f\x48\xbc\x64\x3f\x97\xa2\x5f\x82\x2c\x01\x3f\x73\xbd\xf4\xcb\x41\x94\xbc\x8d\x55\xdf",
+       49 },
+      { GCRY_MD_SHA3_224,
+       "\x7e\x15\xd2\xb9\xea\x74\xca\x60\xf6\x6c\x8d\xfa\xb3\x77\xd9\x19\x8b\x7b\x16\xde\xb6\xa1\xba\x0e\xa3\xc7\xee\x20\x42\xf8\x9d\x37\x86\xe7\x79\xcf\x05\x3c\x77\x78\x5a\xa9\xe6\x92\xf8\x21\xf1\x4a\x7f\x51",
+       "\xd8\x7f\x62\xea\x81\x1a\x2f\x6b\xf3\xc5\xfd\xe1\x34\x75\xb9\xc6\x76\x62\x0c\x01\x84\xf8\x71\x49\xdc\x86\x86\xc8",
+       50 },
+      { GCRY_MD_SHA3_224,
+       "\x9a\x21\x9b\xe4\x37\x13\xbd\x57\x80\x15\xe9\xfd\xa6\x6c\x0f\x2d\x83\xca\xc5\x63\xb7\x76\xab\x9f\x38\xf3\xe4\xf7\xef\x22\x9c\xb4\x43\x30\x4f\xba\x40\x1e\xfb\x2b\xdb\xd7\xec\xe9\x39\x10\x22\x98\x65\x1c\x86",
+       "\x02\x8a\x63\x9c\x7e\xc0\xba\x1d\xce\xc0\xb6\x89\xaa\x26\xe2\xc0\x16\x76\x22\x46\x26\x69\xa5\xc5\x20\x31\x60\x2b",
+       51 },
+      { GCRY_MD_SHA3_224,
+       "\xc8\xf2\xb6\x93\xbd\x0d\x75\xef\x99\xca\xeb\xdc\x22\xad\xf4\x08\x8a\x95\xa3\x54\x2f\x63\x72\x03\xe2\x83\xbb\xc3\x26\x87\x80\xe7\x87\xd6\x8d\x28\xcc\x38\x97\x45\x2f\x6a\x22\xaa\x85\x73\xcc\xeb\xf2\x45\x97\x2a",
+       "\x90\x8e\xf2\x8a\xb2\xb6\xcb\xb4\x49\xb9\xaf\x7f\xa7\x8b\x3d\x90\xe0\x19\xc3\x91\x65\x62\xeb\x48\x19\xa0\xc8\x7f",
+       52 },
+      { GCRY_MD_SHA3_224,
+       "\xec\x0f\x99\x71\x10\x16\xc6\xa2\xa0\x7a\xd8\x0d\x16\x42\x75\x06\xce\x6f\x44\x10\x59\xfd\x26\x94\x42\xba\xaa\x28\xc6\xca\x03\x7b\x22\xee\xac\x49\xd5\xd8\x94\xc0\xbf\x66\x21\x9f\x2c\x08\xe9\xd0\xe8\xab\x21\xde\x52",
+       "\x6a\xc8\x41\x49\xf8\x90\xe1\x35\x2c\x6d\x73\x97\xda\xc3\xb3\x77\x39\x47\xb3\x75\x7e\x8e\xd4\xec\x05\x9e\xf8\x99",
+       53 },
+      { GCRY_MD_SHA3_224,
+       "\x0d\xc4\x51\x81\x33\x7c\xa3\x2a\x82\x22\xfe\x7a\x3b\xf4\x2f\xc9\xf8\x97\x44\x25\x9c\xff\x65\x35\x04\xd6\x05\x1f\xe8\x4b\x1a\x7f\xfd\x20\xcb\x47\xd4\x69\x6c\xe2\x12\xa6\x86\xbb\x9b\xe9\xa8\xab\x1c\x69\x7b\x6d\x6a\x33",
+       "\x45\xda\x27\x71\x5c\xd7\x5f\x58\x75\xbe\xb7\xd9\x14\xcf\x74\x88\x24\x0d\x1b\x1f\x97\x5d\x43\x0d\x2f\x49\xe9\xbf",
+       54 },
+      { GCRY_MD_SHA3_224,
+       "\xde\x28\x6b\xa4\x20\x6e\x8b\x00\x57\x14\xf8\x0f\xb1\xcd\xfa\xeb\xde\x91\xd2\x9f\x84\x60\x3e\x4a\x3e\xbc\x04\x68\x6f\x99\xa4\x6c\x9e\x88\x0b\x96\xc5\x74\x82\x55\x82\xe8\x81\x2a\x26\xe5\xa8\x57\xff\xc6\x57\x9f\x63\x74\x2f",
+       "\x63\xaf\xba\xbb\xec\x07\x21\x40\xdf\xce\xfe\x64\xcf\x7b\xc9\x53\x4d\xca\x10\x95\x60\x42\xe3\x1d\xbe\x58\xd0\xa5",
+       55 },
+      { GCRY_MD_SHA3_224,
+       "\xee\xbc\xc1\x80\x57\x25\x2c\xbf\x3f\x9c\x07\x0f\x1a\x73\x21\x33\x56\xd5\xd4\xbc\x19\xac\x2a\x41\x1e\xc8\xcd\xee\xe7\xa5\x71\xe2\xe2\x0e\xaf\x61\xfd\x0c\x33\xa0\xff\xeb\x29\x7d\xdb\x77\xa9\x7f\x0a\x41\x53\x47\xdb\x66\xbc\xaf",
+       "\x64\x87\x19\x3d\x9c\xbe\x59\x3b\x3d\xaa\x50\xd4\xdf\xdf\x7d\xd2\x61\x23\x00\xbb\x93\xcb\x39\xe3\xee\xfa\x1a\xfa",
+       56 },
+      { GCRY_MD_SHA3_224,
+       "\x41\x6b\x5c\xdc\x9f\xe9\x51\xbd\x36\x1b\xd7\xab\xfc\x12\x0a\x50\x54\x75\x8e\xba\x88\xfd\xd6\x8f\xd8\x4e\x39\xd3\xb0\x9a\xc2\x54\x97\xd3\x6b\x43\xcb\xe7\xb8\x5a\x6a\x3c\xeb\xda\x8d\xb4\xe5\x54\x9c\x3e\xe5\x1b\xb6\xfc\xb6\xac\x1e",
+       "\x0d\xec\x25\xbe\x32\x77\xe2\x7d\x4f\x78\x4a\xd5\xff\x8f\x79\xd6\x1d\x9a\x30\x9b\xd6\x93\x51\x3a\xcb\xee\xd1\x2f",
+       57 },
+      { GCRY_MD_SHA3_224,
+       "\x5c\x5f\xaf\x66\xf3\x2e\x0f\x83\x11\xc3\x2e\x8d\xa8\x28\x4a\x4e\xd6\x08\x91\xa5\xa7\xe5\x0f\xb2\x95\x6b\x3c\xba\xa7\x9f\xc6\x6c\xa3\x76\x46\x0e\x10\x04\x15\x40\x1f\xc2\xb8\x51\x8c\x64\x50\x2f\x18\x7e\xa1\x4b\xfc\x95\x03\x75\x97\x05",
+       "\x13\x0b\x67\xc6\xd1\xa5\x61\x62\x27\xab\xd7\x3a\xbf\x6f\xeb\x70\xfc\xe1\xd5\xa4\xbf\x33\x38\xc6\xdc\xcb\x39\xd5",
+       58 },
+      { GCRY_MD_SHA3_224,
+       "\x71\x67\xe1\xe0\x2b\xe1\xa7\xca\x69\xd7\x88\x66\x6f\x82\x3a\xe4\xee\xf3\x92\x71\xf3\xc2\x6a\x5c\xf7\xce\xe0\x5b\xca\x83\x16\x10\x66\xdc\x2e\x21\x7b\x33\x0d\xf8\x21\x10\x37\x99\xdf\x6d\x74\x81\x0e\xed\x36\x3a\xdc\x4a\xb9\x9f\x36\x04\x6a",
+       "\x3a\xbb\x5a\xcb\x84\x85\xe2\x0b\xb6\x20\xd4\xa0\x30\xb9\xc2\x5d\x31\x56\xa9\xb2\x68\x93\xae\x00\x7c\x79\xf3\x05",
+       59 },
+      { GCRY_MD_SHA3_224,
+       "\x2f\xda\x31\x1d\xbb\xa2\x73\x21\xc5\x32\x95\x10\xfa\xe6\x94\x8f\x03\x21\x0b\x76\xd4\x3e\x74\x48\xd1\x68\x9a\x06\x38\x77\xb6\xd1\x4c\x4f\x6d\x0e\xaa\x96\xc1\x50\x05\x13\x71\xf7\xdd\x8a\x41\x19\xf7\xda\x5c\x48\x3c\xc3\xe6\x72\x3c\x01\xfb\x7d",
+       "\x92\x2e\x21\x65\x29\xa9\x53\x05\x30\x7e\x90\x8c\x69\x36\x7e\xbb\x9a\xd9\x31\xec\xa3\x14\x56\x3a\xc3\x6a\xab\x80",
+       60 },
+      { GCRY_MD_SHA3_224,
+       "\x95\xd1\x47\x4a\x5a\xab\x5d\x24\x22\xac\xa6\xe4\x81\x18\x78\x33\xa6\x21\x2b\xd2\xd0\xf9\x14\x51\xa6\x7d\xd7\x86\xdf\xc9\x1d\xfe\xd5\x1b\x35\xf4\x7e\x1d\xeb\x8a\x8a\xb4\xb9\xcb\x67\xb7\x01\x79\xcc\x26\xf5\x53\xae\x7b\x56\x99\x69\xce\x15\x1b\x8d",
+       "\xc7\x2e\x93\xa2\xc3\x9a\xbc\xd9\x0a\xb1\x1c\xd3\xf1\x5d\x59\xda\x3c\x23\xc0\xf1\x7c\x4e\x26\xc9\xc5\x89\x08\x87",
+       61 },
+      { GCRY_MD_SHA3_224,
+       "\xc7\x1b\xd7\x94\x1f\x41\xdf\x04\x4a\x29\x27\xa8\xff\x55\xb4\xb4\x67\xc3\x3d\x08\x9f\x09\x88\xaa\x25\x3d\x29\x4a\xdd\xbd\xb3\x25\x30\xc0\xd4\x20\x8b\x10\xd9\x95\x98\x23\xf0\xc0\xf0\x73\x46\x84\x00\x6d\xf7\x9f\x70\x99\x87\x0f\x6b\xf5\x32\x11\xa8\x8d",
+       "\xcc\xcc\x3b\x59\xf2\x8c\x3f\xc4\x62\xdc\x0a\x69\x61\x50\xf5\xae\xa6\x2d\xa0\xab\xa9\x7c\x47\x6b\xd0\xd8\x66\xc1",
+       62 },
+      { GCRY_MD_SHA3_224,
+       "\xf5\x7c\x64\x00\x6d\x9e\xa7\x61\x89\x2e\x14\x5c\x99\xdf\x1b\x24\x64\x08\x83\xda\x79\xd9\xed\x52\x62\x85\x9d\xcd\xa8\xc3\xc3\x2e\x05\xb0\x3d\x98\x4f\x1a\xb4\xa2\x30\x24\x2a\xb6\xb7\x8d\x36\x8d\xc5\xaa\xa1\xe6\xd3\x49\x8d\x53\x37\x1e\x84\xb0\xc1\xd4\xba",
+       "\x28\xcf\xd0\xc6\xf0\x20\x8d\x24\xaa\xa6\x9e\x6c\x39\xf5\x25\x7c\x13\x30\x3e\x91\xc2\xd6\x83\xa9\xaf\x29\xb9\x73",
+       63 },
+      { GCRY_MD_SHA3_224,
+       "\xe9\x26\xae\x8b\x0a\xf6\xe5\x31\x76\xdb\xff\xcc\x2a\x6b\x88\xc6\xbd\x76\x5f\x93\x9d\x3d\x17\x8a\x9b\xde\x9e\xf3\xaa\x13\x1c\x61\xe3\x1c\x1e\x42\xcd\xfa\xf4\xb4\xdc\xde\x57\x9a\x37\xe1\x50\xef\xbe\xf5\x55\x5b\x4c\x1c\xb4\x04\x39\xd8\x35\xa7\x24\xe2\xfa\xe7",
+       "\xc1\x54\x60\x7f\x98\x6f\x9b\xf9\x02\xd8\x31\x29\x3c\x83\x86\xd3\x6b\x20\x1e\xab\xa6\xf6\xfb\x0b\x67\x8b\x4b\x81",
+       64 },
+      { GCRY_MD_SHA3_224,
+       "\x16\xe8\xb3\xd8\xf9\x88\xe9\xbb\x04\xde\x9c\x96\xf2\x62\x78\x11\xc9\x73\xce\x4a\x52\x96\xb4\x77\x2c\xa3\xee\xfe\xb8\x0a\x65\x2b\xdf\x21\xf5\x0d\xf7\x9f\x32\xdb\x23\xf9\xf7\x3d\x39\x3b\x2d\x57\xd9\xa0\x29\x7f\x7a\x2f\x2e\x79\xcf\xda\x39\xfa\x39\x3d\xf1\xac\x00",
+       "\x95\xe8\x7a\xc9\x0f\x54\x1a\xb9\x0c\xbc\xf7\xfd\x7e\x0e\x0c\x15\x2c\xef\x78\xd5\xee\x18\x30\xe9\xed\x8a\x1e\xd7",
+       65 },
+      { GCRY_MD_SHA3_224,
+       "\xfc\x42\x4e\xeb\x27\xc1\x8a\x11\xc0\x1f\x39\xc5\x55\xd8\xb7\x8a\x80\x5b\x88\xdb\xa1\xdc\x2a\x42\xed\x5e\x2c\x0e\xc7\x37\xff\x68\xb2\x45\x6d\x80\xeb\x85\xe1\x17\x14\xfa\x3f\x8e\xab\xfb\x90\x6d\x3c\x17\x96\x4c\xb4\xf5\xe7\x6b\x29\xc1\x76\x5d\xb0\x3d\x91\xbe\x37\xfc",
+       "\x35\xbd\x7d\x02\x54\x1d\x6d\x4b\x10\xac\xe6\x02\x9a\x24\xc0\x7a\x38\xfd\x56\x3a\xba\x22\x7f\x0f\x77\x6e\xa5\xe2",
+       66 },
+      { GCRY_MD_SHA3_224,
+       "\xab\xe3\x47\x2b\x54\xe7\x27\x34\xbd\xba\x7d\x91\x58\x73\x64\x64\x25\x1c\x4f\x21\xb3\x3f\xbb\xc9\x2d\x7f\xac\x9a\x35\xc4\xe3\x32\x2f\xf0\x1d\x23\x80\xcb\xaa\x4e\xf8\xfb\x07\xd2\x1a\x21\x28\xb7\xb9\xf5\xb6\xd9\xf3\x4e\x13\xf3\x9c\x7f\xfc\x2e\x72\xe4\x78\x88\x59\x9b\xa5",
+       "\x99\xde\xcb\x8c\xf1\xd4\x74\x97\x0b\x3c\xfa\x87\xfa\x46\x2b\x75\xe3\x28\x7b\x98\xb4\xbe\x40\x93\x42\x9e\x22\xd6",
+       67 },
+      { GCRY_MD_SHA3_224,
+       "\x36\xf9\xf0\xa6\x5f\x2c\xa4\x98\xd7\x39\xb9\x44\xd6\xef\xf3\xda\x5e\xbb\xa5\x7e\x7d\x9c\x41\x59\x8a\x2b\x0e\x43\x80\xf3\xcf\x4b\x47\x9e\xc2\x34\x8d\x01\x5f\xfe\x62\x56\x27\x35\x11\x15\x4a\xfc\xf3\xb4\xb4\xbf\x09\xd6\xc4\x74\x4f\xdd\x0f\x62\xd7\x50\x79\xd4\x40\x70\x6b\x05",
+       "\x8c\x20\xfd\x3d\x8e\x08\x23\x5b\x01\x72\x7a\x4d\xf4\x4d\x86\xe7\x1e\x82\x4f\x14\xb0\xc2\xfe\x4e\x8d\xa7\xf1\xbb",
+       68 },
+      { GCRY_MD_SHA3_224,
+       "\xab\xc8\x77\x63\xca\xe1\xca\x98\xbd\x8c\x5b\x82\xca\xba\x54\xac\x83\x28\x6f\x87\xe9\x61\x01\x28\xae\x4d\xe6\x8a\xc9\x5d\xf5\xe3\x29\xc3\x60\x71\x7b\xd3\x49\xf2\x6b\x87\x25\x28\x49\x2c\xa7\xc9\x4c\x2c\x1e\x1e\xf5\x6b\x74\xdb\xb6\x5c\x2a\xc3\x51\x98\x1f\xdb\x31\xd0\x6c\x77\xa4",
+       "\xe2\x9e\x68\x43\x9a\xec\xde\x56\xf5\x29\x7f\xb9\x35\xdc\x7d\xbe\x63\xd6\x1c\xe3\x60\xa1\x96\x29\x19\x5b\xd8\xaa",
+       69 },
+      { GCRY_MD_SHA3_224,
+       "\x94\xf7\xca\x8e\x1a\x54\x23\x4c\x6d\x53\xcc\x73\x4b\xb3\xd3\x15\x0c\x8b\xa8\xc5\xf8\x80\xea\xb8\xd2\x5f\xed\x13\x79\x3a\x97\x01\xeb\xe3\x20\x50\x92\x86\xfd\x8e\x42\x2e\x93\x1d\x99\xc9\x8d\xa4\xdf\x7e\x70\xae\x44\x7b\xab\x8c\xff\xd9\x23\x82\xd8\xa7\x77\x60\xa2\x59\xfc\x4f\xbd\x72",
+       "\x5d\x21\x64\xda\x84\xe7\x70\x7c\xd1\xe7\x89\x71\x1a\x66\x4a\xb2\xeb\xcf\x66\xeb\xa8\x99\xa9\x09\xa1\xd0\xcb\xec",
+       70 },
+      { GCRY_MD_SHA3_224,
+       "\x13\xbd\x28\x11\xf6\xed\x2b\x6f\x04\xff\x38\x95\xac\xee\xd7\xbe\xf8\xdc\xd4\x5e\xb1\x21\x79\x1b\xc1\x94\xa0\xf8\x06\x20\x6b\xff\xc3\xb9\x28\x1c\x2b\x30\x8b\x1a\x72\x9c\xe0\x08\x11\x9d\xd3\x06\x6e\x93\x78\xac\xdc\xc5\x0a\x98\xa8\x2e\x20\x73\x88\x00\xb6\xcd\xdb\xe5\xfe\x96\x94\xad\x6d",
+       "\xfa\x26\x3b\x09\x3e\xa3\xf9\x6b\x52\xdb\x62\x51\xea\x25\xa5\x25\x4a\xda\x5b\x54\xd4\x76\xcb\x07\x94\xd3\x88\x89",
+       71 },
+      { GCRY_MD_SHA3_224,
+       "\x1e\xed\x9c\xba\x17\x9a\x00\x9e\xc2\xec\x55\x08\x77\x3d\xd3\x05\x47\x7c\xa1\x17\xe6\xd5\x69\xe6\x6b\x5f\x64\xc6\xbc\x64\x80\x1c\xe2\x5a\x84\x24\xce\x4a\x26\xd5\x75\xb8\xa6\xfb\x10\xea\xd3\xfd\x19\x92\xed\xdd\xee\xc2\xeb\xe7\x15\x0d\xc9\x8f\x63\xad\xc3\x23\x7e\xf5\x7b\x91\x39\x7a\xa8\xa7",
+       "\xd8\x03\xe3\x20\xa9\x86\x5e\xbf\x35\x55\xe8\xa3\xe3\x13\x47\x68\xa2\xee\x1b\x3e\x59\xfa\x15\xf3\x5c\x2e\xc5\x50",
+       72 },
+      { GCRY_MD_SHA3_224,
+       "\xba\x5b\x67\xb5\xec\x3a\x3f\xfa\xe2\xc1\x9d\xd8\x17\x6a\x2e\xf7\x5c\x0c\xd9\x03\x72\x5d\x45\xc9\xcb\x70\x09\xa9\x00\xc0\xb0\xca\x7a\x29\x67\xa9\x5a\xe6\x82\x69\xa6\xdb\xf8\x46\x6c\x7b\x68\x44\xa1\xd6\x08\xac\x66\x1f\x7e\xff\x00\x53\x8e\x32\x3d\xb5\xf2\xc6\x44\xb7\x8b\x2d\x48\xde\x1a\x08\xaa",
+       "\x10\x29\x25\xb6\x3b\x3e\x93\x95\xf8\x81\x24\xc3\xbf\xa7\x77\xf2\x9a\x5b\x41\xc1\x3b\x62\xad\xd7\xc2\x71\xcd\x6e",
+       73 },
+      { GCRY_MD_SHA3_224,
+       "\x0e\xfa\x26\xac\x56\x73\x16\x7d\xca\xca\xb8\x60\x93\x2e\xd6\x12\xf6\x5f\xf4\x9b\x80\xfa\x9a\xe6\x54\x65\xe5\x54\x2c\xb6\x20\x75\xdf\x1c\x5a\xe5\x4f\xba\x4d\xb8\x07\xbe\x25\xb0\x70\x03\x3e\xfa\x22\x3b\xdd\x5b\x1d\x3c\x94\xc6\xe1\x90\x9c\x02\xb6\x20\xd4\xb1\xb3\xa6\xc9\xfe\xd2\x4d\x70\x74\x96\x04",
+       "\x6c\x4e\x83\xcd\x92\x58\x20\x5f\x3c\x2b\xcf\x64\x14\x9f\x4a\xcd\xce\xe7\x74\x2c\xb2\xd3\x60\x38\x53\x71\x71\xbd",
+       74 },
+      { GCRY_MD_SHA3_224,
+       "\xbb\xfd\x93\x3d\x1f\xd7\xbf\x59\x4a\xc7\xf4\x35\x27\x7d\xc1\x7d\x8d\x5a\x5b\x8e\x4d\x13\xd9\x6d\x2f\x64\xe7\x71\xab\xbd\x51\xa5\xa8\xae\xa7\x41\xbe\xcc\xbd\xdb\x17\x7b\xce\xa0\x52\x43\xeb\xd0\x03\xcf\xde\xae\x87\x7c\xca\x4d\xa9\x46\x05\xb6\x76\x91\x91\x9d\x8b\x03\x3f\x77\xd3\x84\xca\x01\x59\x3c\x1b",
+       "\xc7\x4c\x9e\xbb\x2e\xf9\xa9\x82\x2a\x62\x28\xbd\x11\x86\xdc\xc4\x41\x1b\xc5\x9e\xc9\x38\xdf\x27\xe5\x4b\x08\x15",
+       75 },
+      { GCRY_MD_SHA3_224,
+       "\x90\x07\x89\x99\xfd\x3c\x35\xb8\xaf\xbf\x40\x66\xcb\xde\x33\x58\x91\x36\x5f\x0f\xc7\x5c\x12\x86\xcd\xd8\x8f\xa5\x1f\xab\x94\xf9\xb8\xde\xf7\xc9\xac\x58\x2a\x5d\xbc\xd9\x58\x17\xaf\xb7\xd1\xb4\x8f\x63\x70\x4e\x19\xc2\xba\xa4\xdf\x34\x7f\x48\xd4\xa6\xd6\x03\x01\x3c\x23\xf1\xe9\x61\x1d\x59\x5e\xba\xc3\x7c",
+       "\xd2\x34\x20\xf9\x98\x5d\x66\xf0\x97\xd4\x3a\x0f\xb2\x43\x41\x49\xd2\xb3\x3f\x21\xb5\xba\xd6\xcf\xc2\x50\xe0\x72",
+       76 },
+      { GCRY_MD_SHA3_224,
+       "\x64\x10\x5e\xca\x86\x35\x15\xc2\x0e\x7c\xfb\xaa\x0a\x0b\x88\x09\x04\x61\x64\xf3\x74\xd6\x91\xcd\xbd\x65\x08\xaa\xab\xc1\x81\x9f\x9a\xc8\x4b\x52\xba\xfc\x1b\x0f\xe7\xcd\xdb\xc5\x54\xb6\x08\xc0\x1c\x89\x04\xc6\x69\xd8\xdb\x31\x6a\x09\x53\xa4\xc6\x8e\xce\x32\x4e\xc5\xa4\x9f\xfd\xb5\x9a\x1b\xd6\xa2\x92\xaa\x0e",
+       "\x10\x2e\xdd\x2e\x94\x6f\x33\xdd\x7a\xa5\x53\xea\x4c\xe4\xe6\x59\xc7\xb2\x40\xe1\xe2\x8b\xc6\x62\x00\x84\x5d\x87",
+       77 },
+      { GCRY_MD_SHA3_224,
+       "\xd4\x65\x4b\xe2\x88\xb9\xf3\xb7\x11\xc2\xd0\x20\x15\x97\x8a\x8c\xc5\x74\x71\xd5\x68\x0a\x09\x2a\xa5\x34\xf7\x37\x2c\x71\xce\xaa\xb7\x25\xa3\x83\xc4\xfc\xf4\xd8\xde\xaa\x57\xfc\xa3\xce\x05\x6f\x31\x29\x61\xec\xcf\x9b\x86\xf1\x49\x81\xba\x5b\xed\x6a\xb5\xb4\x49\x8e\x1f\x6c\x82\xc6\xca\xe6\xfc\x14\x84\x5b\x3c\x8a",
+       "\x7c\x8e\xb9\x8b\x73\x38\x40\x3c\x01\x3d\x65\xc0\xb5\xbb\x4b\x5d\x2c\xbf\x53\x9c\xb1\x10\x9c\xf4\x47\xfa\x66\x50",
+       78 },
+      { GCRY_MD_SHA3_224,
+       "\x12\xd9\x39\x48\x88\x30\x5a\xc9\x6e\x65\xf2\xbf\x0e\x1b\x18\xc2\x9c\x90\xfe\x9d\x71\x4d\xd5\x9f\x65\x1f\x52\xb8\x8b\x30\x08\xc5\x88\x43\x55\x48\x06\x6e\xa2\xfc\x4c\x10\x11\x18\xc9\x1f\x32\x55\x62\x24\xa5\x40\xde\x6e\xfd\xdb\xca\x29\x6e\xf1\xfb\x00\x34\x1f\x5b\x01\xfe\xcf\xc1\x46\xbd\xb2\x51\xb3\xbd\xad\x55\x6c\xd2",
+       "\xc7\xb0\x7d\xe9\x1e\xfc\xe4\x2d\xab\x78\x19\x9e\xe2\xeb\x30\x14\xa4\x94\x99\x42\x36\xa1\x2b\x3d\xe2\x33\x0c\x25",
+       79 },
+      { GCRY_MD_SHA3_224,
+       "\x87\x1a\x0d\x7a\x5f\x36\xc3\xda\x1d\xfc\xe5\x7a\xcd\x8a\xb8\x48\x7c\x27\x4f\xad\x33\x6b\xc1\x37\xeb\xd6\xff\x46\x58\xb5\x47\xc1\xdc\xfa\xb6\x5f\x03\x7a\xa5\x8f\x35\xef\x16\xaf\xf4\xab\xe7\x7b\xa6\x1f\x65\x82\x6f\x7b\xe6\x81\xb5\xb6\xd5\xa1\xea\x80\x85\xe2\xae\x9c\xd5\xcf\x09\x91\x87\x8a\x31\x1b\x54\x9a\x6d\x6a\xf2\x30",
+       "\x2f\xce\xf2\x59\x4a\xe8\x55\xde\x4f\xc6\x6d\xcc\xc5\x17\xa6\x59\x11\x8b\x3a\x9f\x2e\x5f\xe6\x38\x98\x0a\xdb\xfb",
+       80 },
+      { GCRY_MD_SHA3_224,
+       "\xe9\x0b\x4f\xfe\xf4\xd4\x57\xbc\x77\x11\xff\x4a\xa7\x22\x31\xca\x25\xaf\x6b\x2e\x20\x6f\x8b\xf8\x59\xd8\x75\x8b\x89\xa7\xcd\x36\x10\x5d\xb2\x53\x8d\x06\xda\x83\xba\xd5\xf6\x63\xba\x11\xa5\xf6\xf6\x1f\x23\x6f\xd5\xf8\xd5\x3c\x5e\x89\xf1\x83\xa3\xce\xc6\x15\xb5\x0c\x7c\x68\x1e\x77\x3d\x10\x9f\xf7\x49\x1b\x5c\xc2\x22\x96\xc5",
+       "\xd4\x58\x73\xf0\x45\x3c\xbf\x38\x15\x6a\x13\x84\xe3\x3e\x5c\x76\x58\x8b\x7b\xfb\x48\xa7\x09\xb3\x94\x3d\x91\x86",
+       81 },
+      { GCRY_MD_SHA3_224,
+       "\xe7\x28\xde\x62\xd7\x58\x56\x50\x0c\x4c\x77\xa4\x28\x61\x2c\xd8\x04\xf3\x0c\x3f\x10\xd3\x6f\xb2\x19\xc5\xca\x0a\xa3\x07\x26\xab\x19\x0e\x5f\x3f\x27\x9e\x07\x33\xd7\x7e\x72\x67\xc1\x7b\xe2\x7d\x21\x65\x0a\x9a\x4d\x1e\x32\xf6\x49\x62\x76\x38\xdb\xad\xa9\x70\x2c\x7c\xa3\x03\x26\x9e\xd1\x40\x14\xb2\xf3\xcf\x8b\x89\x4e\xac\x85\x54",
+       "\x35\x43\xad\xd5\xb7\xed\xfc\x83\xaf\xe7\xc1\xf2\xd5\x51\x40\xae\xdb\x85\x83\x04\x62\x81\x09\xfd\x07\x7b\x38\x60",
+       82 },
+      { GCRY_MD_SHA3_224,
+       "\x63\x48\xf2\x29\xe7\xb1\xdf\x3b\x77\x0c\x77\x54\x4e\x51\x66\xe0\x81\x85\x0f\xa1\xc6\xc8\x81\x69\xdb\x74\xc7\x6e\x42\xeb\x98\x3f\xac\xb2\x76\xad\x6a\x0d\x1f\xa7\xb5\x0d\x3e\x3b\x6f\xcd\x79\x9e\xc9\x74\x70\x92\x0a\x7a\xbe\xd4\x7d\x28\x8f\xf8\x83\xe2\x4c\xa2\x1c\x7f\x80\x16\xb9\x3b\xb9\xb9\xe0\x78\xbd\xb9\x70\x3d\x2b\x78\x1b\x61\x6e",
+       "\x36\x78\x4f\x11\x49\x58\xd8\xb5\xb6\x25\xdd\x89\xa4\xe3\x97\x3a\x11\x3e\x5d\x16\x10\xdf\xa5\x5b\x4f\xb4\x5a\xec",
+       83 },
+      { GCRY_MD_SHA3_224,
+       "\x4b\x12\x7f\xde\x5d\xe7\x33\xa1\x68\x0c\x27\x90\x36\x36\x27\xe6\x3a\xc8\xa3\xf1\xb4\x70\x7d\x98\x2c\xae\xa2\x58\x65\x5d\x9b\xf1\x8f\x89\xaf\xe5\x41\x27\x48\x2b\xa0\x1e\x08\x84\x55\x94\xb6\x71\x30\x6a\x02\x5c\x9a\x5c\x5b\x6f\x93\xb0\xa3\x95\x22\xdc\x87\x74\x37\xbe\x5c\x24\x36\xcb\xf3\x00\xce\x7a\xb6\x74\x79\x34\xfc\xfc\x30\xae\xaa\xf6",
+       "\x41\x87\xfe\xae\xd4\xfb\xd3\xd5\x05\xa9\x6a\x8d\x60\x66\x8a\x88\x17\x2e\x4f\x7c\x84\x51\xa4\xa6\x80\x2c\x57\x47",
+       84 },
+      { GCRY_MD_SHA3_224,
+       "\x08\x46\x1f\x00\x6c\xff\x4c\xc6\x4b\x75\x2c\x95\x72\x87\xe5\xa0\xfa\xab\xc0\x5c\x9b\xff\x89\xd2\x3f\xd9\x02\xd3\x24\xc7\x99\x03\xb4\x8f\xcb\x8f\x8f\x4b\x01\xf3\xe4\xdd\xb4\x83\x59\x3d\x25\xf0\x00\x38\x66\x98\xf5\xad\xe7\xfa\xad\xe9\x61\x5f\xdc\x50\xd3\x27\x85\xea\x51\xd4\x98\x94\xe4\x5b\xaa\x3d\xc7\x07\xe2\x24\x68\x8c\x64\x08\xb6\x8b\x11",
+       "\x6e\x47\x66\xdb\x4e\x9d\x11\x02\xce\xe6\xdf\xe0\xae\x22\x21\x32\x1b\x9c\x0f\xe7\x07\xf0\xa7\x82\x5d\x75\x57\xec",
+       85 },
+      { GCRY_MD_SHA3_224,
+       "\x68\xc8\xf8\x84\x9b\x12\x0e\x6e\x0c\x99\x69\xa5\x86\x6a\xf5\x91\xa8\x29\xb9\x2f\x33\xcd\x9a\x4a\x31\x96\x95\x7a\x14\x8c\x49\x13\x8e\x1e\x2f\x5c\x76\x19\xa6\xd5\xed\xeb\xe9\x95\xac\xd8\x1e\xc8\xbb\x9c\x7b\x9c\xfc\xa6\x78\xd0\x81\xea\x9e\x25\xa7\x5d\x39\xdb\x04\xe1\x8d\x47\x59\x20\xce\x82\x8b\x94\xe7\x22\x41\xf2\x4d\xb7\x25\x46\xb3\x52\xa0\xe4",
+       "\xe1\xfc\x97\x2b\xfb\x29\x41\x85\xf1\x98\x0c\xa2\x93\x86\x55\xfb\x58\x3e\x81\x2a\xd3\xd6\x4f\xa5\xa4\xcf\x70\x3e",
+       86 },
+      { GCRY_MD_SHA3_224,
+       "\xb8\xd5\x64\x72\x95\x4e\x31\xfb\x54\xe2\x8f\xca\x74\x3f\x84\xd8\xdc\x34\x89\x1c\xb5\x64\xc6\x4b\x08\xf7\xb7\x16\x36\xde\xbd\x64\xca\x1e\xdb\xdb\xa7\xfc\x5c\x3e\x40\x04\x9c\xe9\x82\xbb\xa8\xc7\xe0\x70\x30\x34\xe3\x31\x38\x46\x95\xe9\xde\x76\xb5\x10\x4f\x2f\xbc\x45\x35\xec\xbe\xeb\xc3\x3b\xc2\x7f\x29\xf1\x8f\x6f\x27\xe8\x02\x3b\x0f\xbb\x6f\x56\x3c",
+       "\xf6\xf2\x8e\x3b\x65\xb6\x84\xc9\xd9\x50\x60\x61\x98\x00\x46\x06\x13\x90\xcc\xde\x24\x58\xa2\x0f\x9b\x08\x6b\xe5",
+       87 },
+      { GCRY_MD_SHA3_224,
+       "\x0d\x58\xac\x66\x5f\xa8\x43\x42\xe6\x0c\xef\xee\x31\xb1\xa4\xea\xcd\xb0\x92\xf1\x22\xdf\xc6\x83\x09\x07\x7a\xed\x1f\x3e\x52\x8f\x57\x88\x59\xee\x9e\x4c\xef\xb4\xa7\x28\xe9\x46\x32\x49\x27\xb6\x75\xcd\x4f\x4a\xc8\x4f\x64\xdb\x3d\xac\xfe\x85\x0c\x1d\xd1\x87\x44\xc7\x4c\xec\xcd\x9f\xe4\xdc\x21\x40\x85\x10\x8f\x40\x4e\xab\x6d\x8f\x45\x2b\x54\x42\xa4\x7d",
+       "\xf6\x86\xd2\xb1\x38\x6b\x02\xb0\x8f\x6b\x02\xbd\x5d\x50\x20\x6d\x5e\x13\x84\x40\xcb\x0d\x93\xeb\xcc\x3b\x32\xa7",
+       88 },
+      { GCRY_MD_SHA3_224,
+       "\x17\x55\xe2\xd2\xe5\xd1\xc1\xb0\x15\x64\x56\xb5\x39\x75\x3f\xf4\x16\x65\x1d\x44\x69\x8e\x87\x00\x2d\xcf\x61\xdc\xfa\x2b\x4e\x72\xf2\x64\xd9\xad\x59\x1d\xf1\xfd\xee\x7b\x41\xb2\xeb\x00\x28\x3c\x5a\xeb\xb3\x41\x13\x23\xb6\x72\xea\xa1\x45\xc5\x12\x51\x85\x10\x4f\x20\xf3\x35\x80\x4b\x02\x32\x5b\x6d\xea\x65\x60\x3f\x34\x9f\x4d\x5d\x8b\x78\x2d\xd3\x46\x9c\xcd",
+       "\x46\x48\x33\x75\xd1\x12\xfc\x2b\xe7\xf6\x11\xbe\x4b\x98\xdf\xad\xa3\x88\x92\xc4\x3c\xef\xa5\x86\x72\x6b\x48\xbb",
+       89 },
+      { GCRY_MD_SHA3_224,
+       "\xb1\x80\xde\x1a\x61\x11\x11\xee\x75\x84\xba\x2c\x4b\x02\x05\x98\xcd\x57\x4a\xc7\x7e\x40\x4e\x85\x3d\x15\xa1\x01\xc6\xf5\xa2\xe5\xc8\x01\xd7\xd8\x5d\xc9\x52\x86\xa1\x80\x4c\x87\x0b\xb9\xf0\x0f\xd4\xdc\xb0\x3a\xa8\x32\x82\x75\x15\x88\x19\xdc\xad\x72\x53\xf3\xe3\xd2\x37\xae\xaa\x79\x79\x26\x8a\x5d\xb1\xc6\xce\x08\xa9\xec\x7c\x25\x79\x78\x3c\x8a\xfc\x1f\x91\xa7",
+       "\xe1\xe9\xad\x56\x8a\xe5\xb0\xd9\x73\x14\x00\xba\x4f\xc7\xdf\x03\x21\xa0\x4e\xa4\x13\x93\xba\x69\x79\xc7\x17\x9c",
+       90 },
+      { GCRY_MD_SHA3_224,
+       "\xcf\x35\x83\xcb\xdf\xd4\xcb\xc1\x70\x63\xb1\xe7\xd9\x0b\x02\xf0\xe6\xe2\xee\x05\xf9\x9d\x77\xe2\x4e\x56\x03\x92\x53\x5e\x47\xe0\x50\x77\x15\x7f\x96\x81\x35\x44\xa1\x70\x46\x91\x4f\x9e\xfb\x64\x76\x2a\x23\xcf\x7a\x49\xfe\x52\xa0\xa4\xc0\x1c\x63\x0c\xfe\x87\x27\xb8\x1f\xb9\x9a\x89\xff\x7c\xc1\x1d\xca\x51\x73\x05\x7e\x04\x17\xb8\xfe\x7a\x9e\xfb\xa6\xd9\x5c\x55\x5f",
+       "\x13\x3f\x31\xd9\xfb\xc1\xb2\xa3\x3f\x1c\x98\xbf\xe2\x1e\x12\x9e\x07\x16\xa6\x9e\xe2\x74\x08\x74\x3f\xff\x17\xac",
+       91 },
+      { GCRY_MD_SHA3_224,
+       "\x07\x2f\xc0\x23\x40\xef\x99\x11\x5b\xad\x72\xf9\x2c\x01\xe4\xc0\x93\xb9\x59\x9f\x6c\xfc\x45\xcb\x38\x0e\xe6\x86\xcb\x5e\xb0\x19\xe8\x06\xab\x9b\xd5\x5e\x63\x4a\xb1\x0a\xa6\x2a\x95\x10\xcc\x06\x72\xcd\x3e\xdd\xb5\x89\xc7\xdf\x2b\x67\xfc\xd3\x32\x9f\x61\xb1\xa4\x44\x1e\xca\x87\xa3\x3c\x8f\x55\xda\x4f\xbb\xad\x5c\xf2\xb2\x52\x7b\x8e\x98\x3b\xb3\x1a\x2f\xad\xec\x75\x23",
+       "\x31\x32\x8f\x04\xca\x64\xe8\x52\x1a\x36\xa8\x94\x3c\x33\xce\xb9\x5b\xe1\xb9\x08\x0f\x45\x33\xd6\xda\x07\x60\x6d",
+       92 },
+      { GCRY_MD_SHA3_224,
+       "\x76\xee\xcf\x95\x6a\x52\x64\x9f\x87\x75\x28\x14\x6d\xe3\x3d\xf2\x49\xcd\x80\x0e\x21\x83\x0f\x65\xe9\x0f\x0f\x25\xca\x9d\x65\x40\xfd\xe4\x06\x03\x23\x0e\xca\x67\x60\xf1\x13\x9c\x7f\x26\x8d\xeb\xa2\x06\x06\x31\xee\xa9\x2b\x1f\xff\x05\xf9\x3f\xd5\x57\x2f\xbe\x29\x57\x9e\xcd\x48\xbc\x3a\x8d\x6c\x2e\xb4\xa6\xb2\x6e\x38\xd6\xc5\xfb\xf2\xc0\x80\x44\xae\xea\x47\x0a\x8f\x2f\x26",
+       "\xad\xd3\x74\xb1\xd2\x79\x46\x9c\x08\xe7\xb2\x7a\xe3\xff\x1b\x04\xc3\xd0\xfb\x3e\xf6\xe5\x9a\xa3\xaf\x86\x66\x0b",
+       93 },
+      { GCRY_MD_SHA3_224,
+       "\x7a\xdc\x0b\x66\x93\xe6\x1c\x26\x9f\x27\x8e\x69\x44\xa5\xa2\xd8\x30\x09\x81\xe4\x00\x22\xf8\x39\xac\x64\x43\x87\xbf\xac\x90\x86\x65\x00\x85\xc2\xcd\xc5\x85\xfe\xa4\x7b\x9d\x2e\x52\xd6\x5a\x2b\x29\xa7\xdc\x37\x04\x01\xef\x5d\x60\xdd\x0d\x21\xf9\xe2\xb9\x0f\xae\x91\x93\x19\xb1\x4b\x8c\x55\x65\xb0\x42\x3c\xef\xb8\x27\xd5\xf1\x20\x33\x02\xa9\xd0\x15\x23\x49\x8a\x4d\xb1\x03\x74",
+       "\xfe\xd7\xfd\xe8\x94\xd9\x2c\xc3\xbb\x68\xfc\xc3\x96\xb5\xeb\x00\xc4\x15\x6f\x04\xfc\x9c\xed\x99\xd1\x2c\xfa\x5b",
+       94 },
+      { GCRY_MD_SHA3_224,
+       "\xe1\xff\xfa\x98\x26\xcc\xe8\xb8\x6b\xcc\xef\xb8\x79\x4e\x48\xc4\x6c\xdf\x37\x20\x13\xf7\x82\xec\xed\x1e\x37\x82\x69\xb7\xbe\x2b\x7b\xf5\x13\x74\x09\x22\x61\xae\x12\x0e\x82\x2b\xe6\x85\xf2\xe7\xa8\x36\x64\xbc\xfb\xe3\x8f\xe8\x63\x3f\x24\xe6\x33\xff\xe1\x98\x8e\x1b\xc5\xac\xf5\x9a\x58\x70\x79\xa5\x7a\x91\x0b\xda\x60\x06\x0e\x85\xb5\xf5\xb6\xf7\x76\xf0\x52\x96\x39\xd9\xcc\xe4\xbd",
+       "\x17\xfc\x03\x27\xde\x47\x4c\x78\xf5\x38\xb4\xf3\x98\x16\x74\xff\x47\x0a\xa4\x2e\xf3\xb8\x2c\x0c\xc3\x4d\xe6\xda",
+       95 },
+      { GCRY_MD_SHA3_224,
+       "\x69\xf9\xab\xba\x65\x59\x2e\xe0\x1d\xb4\xdc\xe5\x2d\xba\xb9\x0b\x08\xfc\x04\x19\x36\x02\x79\x2e\xe4\xda\xa2\x63\x03\x3d\x59\x08\x15\x87\xb0\x9b\xbe\x49\xd0\xb4\x9c\x98\x25\xd2\x28\x40\xb2\xff\x5d\x9c\x51\x55\xf9\x75\xf8\xf2\xc2\xe7\xa9\x0c\x75\xd2\xe4\xa8\x04\x0f\xe3\x9f\x63\xbb\xaf\xb4\x03\xd9\xe2\x8c\xc3\xb8\x6e\x04\xe3\x94\xa9\xc9\xe8\x06\x5b\xd3\xc8\x5f\xa9\xf0\xc7\x89\x16\x00",
+       "\x88\xfe\xfb\xe8\x99\x5e\x29\x6a\x9d\xee\x4d\xa2\xb4\x14\xd5\xa7\xe1\x34\x04\x56\x39\xa6\xb1\x76\xc2\xd7\x36\xed",
+       96 },
+      { GCRY_MD_SHA3_224,
+       "\x38\xa1\x0a\x35\x2c\xa5\xae\xdf\xa8\xe1\x9c\x64\x78\x7d\x8e\x9c\x3a\x75\xdb\xf3\xb8\x67\x4b\xfa\xb2\x9b\x5d\xbf\xc1\x5a\x63\xd1\x0f\xae\x66\xcd\x1a\x6e\x6d\x24\x52\xd5\x57\x96\x7e\xaa\xd8\x9a\x4c\x98\x44\x97\x87\xb0\xb3\x16\x4c\xa5\xb7\x17\xa9\x3f\x24\xeb\x0b\x50\x6c\xeb\x70\xcb\xbc\xb8\xd7\x2b\x2a\x72\x99\x3f\x90\x9a\xad\x92\xf0\x44\xe0\xb5\xa2\xc9\xac\x9c\xb1\x6a\x0c\xa2\xf8\x1f\x49",
+       "\xc0\x02\x73\x2f\x6f\x38\xab\x83\x82\x89\x21\xf5\xfc\xb4\xa8\xce\x1f\xc5\x61\xb0\xe9\xfa\x21\x4c\x5f\xf0\x21\x92",
+       97 },
+      { GCRY_MD_SHA3_224,
+       "\x6d\x8c\x6e\x44\x9b\xc1\x36\x34\xf1\x15\x74\x9c\x24\x8c\x17\xcd\x14\x8b\x72\x15\x7a\x2c\x37\xbf\x89\x69\xea\x83\xb4\xd6\xba\x8c\x0e\xe2\x71\x1c\x28\xee\x11\x49\x5f\x43\x04\x95\x96\x52\x0c\xe4\x36\x00\x4b\x02\x6b\x6c\x1f\x72\x92\xb9\xc4\x36\xb0\x55\xcb\xb7\x2d\x53\x0d\x86\x0d\x12\x76\xa1\x50\x2a\x51\x40\xe3\xc3\xf5\x4a\x93\x66\x3e\x4d\x20\xed\xec\x32\xd2\x84\xe2\x55\x64\xf6\x24\x95\x5b\x52",
+       "\x44\xe9\x00\x2f\x9d\x97\xd9\x8b\xb4\x39\xaf\xc3\x61\xf9\x3b\xb9\x59\x52\x3e\x73\x13\x6a\x2c\x65\xb2\xe2\xb0\x66",
+       98 },
+      { GCRY_MD_SHA3_224,
+       "\x6e\xfc\xbc\xaf\x45\x1c\x12\x9d\xbe\x00\xb9\xce\xf0\xc3\x74\x9d\x3e\xe9\xd4\x1c\x7b\xd5\x00\xad\xe4\x0c\xdc\x65\xde\xdb\xbb\xad\xb8\x85\xa5\xb1\x4b\x32\xa0\xc0\xd0\x87\x82\x52\x01\xe3\x03\x28\x8a\x73\x38\x42\xfa\x7e\x59\x9c\x0c\x51\x4e\x07\x8f\x05\xc8\x21\xc7\xa4\x49\x8b\x01\xc4\x00\x32\xe9\xf1\x87\x2a\x1c\x92\x5f\xa1\x7c\xe2\x53\xe8\x93\x5e\x4c\x3c\x71\x28\x22\x42\xcb\x71\x6b\x20\x89\xcc\xc1",
+       "\x2b\xff\x16\xcb\xa9\xe5\x07\x62\xd2\x28\x8e\xb7\x80\x07\x84\x62\xc0\x86\xf4\xcb\xf5\x94\x79\xf5\x38\x7a\x0b\x27",
+       99 },
+      { GCRY_MD_SHA3_224,
+       "\x43\x3c\x53\x03\x13\x16\x24\xc0\x02\x1d\x86\x8a\x30\x82\x54\x75\xe8\xd0\xbd\x30\x52\xa0\x22\x18\x03\x98\xf4\xca\x44\x23\xb9\x82\x14\xb6\xbe\xaa\xc2\x1c\x88\x07\xa2\xc3\x3f\x8c\x93\xbd\x42\xb0\x92\xcc\x1b\x06\xce\xdf\x32\x24\xd5\xed\x1e\xc2\x97\x84\x44\x4f\x22\xe0\x8a\x55\xaa\x58\x54\x2b\x52\x4b\x02\xcd\x3d\x5d\x5f\x69\x07\xaf\xe7\x1c\x5d\x74\x62\x22\x4a\x3f\x9d\x9e\x53\xe7\xe0\x84\x6d\xcb\xb4\xce",
+       "\x5e\xfd\xc3\xca\xa2\x2e\xe2\xc2\xeb\x63\x2d\x4c\x66\x45\xce\x3e\xc6\x39\x60\xdf\xd6\x9a\x04\xbb\xe0\x11\x56\xc5",
+       100 },
+      { GCRY_MD_SHA3_224,
+       "\xa8\x73\xe0\xc6\x7c\xa6\x39\x02\x6b\x66\x83\x00\x8f\x7a\xa6\x32\x4d\x49\x79\x55\x0e\x9b\xce\x06\x4c\xa1\xe1\xfb\x97\xa3\x0b\x14\x7a\x24\xf3\xf6\x66\xc0\xa7\x2d\x71\x34\x8e\xde\x70\x1c\xf2\xd1\x7e\x22\x53\xc3\x4d\x1e\xc3\xb6\x47\xdb\xce\xf2\xf8\x79\xf4\xeb\x88\x1c\x48\x30\xb7\x91\x37\x8c\x90\x1e\xb7\x25\xea\x5c\x17\x23\x16\xc6\xd6\x06\xe0\xaf\x7d\xf4\xdf\x7f\x76\xe4\x90\xcd\x30\xb2\xba\xdf\x45\x68\x5f",
+       "\xe8\xfb\x64\xa7\x43\x87\xc9\xa3\xe1\xac\x4a\xbc\x82\xd3\x59\x1b\x6b\x34\x9f\x2e\x5c\xde\x65\x84\xd8\xd7\xc3\x71",
+       101 },
+      { GCRY_MD_SHA3_224,
+       "\x00\x69\x17\xb6\x4f\x9d\xcd\xf1\xd2\xd8\x7c\x8a\x61\x73\xb6\x4f\x65\x87\x16\x8e\x80\xfa\xa8\x0f\x82\xd8\x4f\x60\x30\x1e\x56\x1e\x31\x2d\x9f\xbc\xe6\x2f\x39\xa6\xfb\x47\x6e\x01\xe9\x25\xf2\x6b\xcc\x91\xde\x62\x14\x49\xbe\x65\x04\xc5\x04\x83\x0a\xae\x39\x40\x96\xc8\xfc\x76\x94\x65\x10\x51\x36\x5d\x4e\xe9\x07\x01\x01\xec\x9b\x68\x08\x6f\x2e\xa8\xf8\xab\x7b\x81\x1e\xa8\xad\x93\x4d\x5c\x9b\x62\xc6\x0a\x47\x71",
+       "\xdb\x22\x4b\xcc\xf5\xca\x86\xdf\xba\x3e\xa3\x72\xe2\x26\x97\x50\xb5\x32\x40\x9e\xa0\x04\xe8\x2d\x4b\x58\x35\xe8",
+       102 },
+      { GCRY_MD_SHA3_224,
+       "\xf1\x3c\x97\x2c\x52\xcb\x3c\xc4\xa4\xdf\x28\xc9\x7f\x2d\xf1\x1c\xe0\x89\xb8\x15\x46\x6b\xe8\x88\x63\x24\x3e\xb3\x18\xc2\xad\xb1\xa4\x17\xcb\x10\x41\x30\x85\x98\x54\x17\x20\x19\x7b\x9b\x1c\xb5\xba\x23\x18\xbd\x55\x74\xd1\xdf\x21\x74\xaf\x14\x88\x41\x49\xba\x9b\x2f\x44\x6d\x60\x9d\xf2\x40\xce\x33\x55\x99\x95\x7b\x8e\xc8\x08\x76\xd9\xa0\x85\xae\x08\x49\x07\xbc\x59\x61\xb2\x0b\xf5\xf6\xca\x58\xd5\xda\xb3\x8a\xdb",
+       "\x4e\x28\x86\x7d\xce\xf3\xa7\xb7\x59\xca\x24\xd8\x10\x7b\xeb\x0c\xbf\x9d\xb0\xf1\x0a\x3c\x41\x0a\x9b\x4b\xa8\xc8",
+       103 },
+      { GCRY_MD_SHA3_224,
+       "\xe3\x57\x80\xeb\x97\x99\xad\x4c\x77\x53\x5d\x4d\xdb\x68\x3c\xf3\x3e\xf3\x67\x71\x53\x27\xcf\x4c\x4a\x58\xed\x9c\xbd\xcd\xd4\x86\xf6\x69\xf8\x01\x89\xd5\x49\xa9\x36\x4f\xa8\x2a\x51\xa5\x26\x54\xec\x72\x1b\xb3\xaa\xb9\x5d\xce\xb4\xa8\x6a\x6a\xfa\x93\x82\x6d\xb9\x23\x51\x7e\x92\x8f\x33\xe3\xfb\xa8\x50\xd4\x56\x60\xef\x83\xb9\x87\x6a\xcc\xaf\xa2\xa9\x98\x7a\x25\x4b\x13\x7c\x6e\x14\x0a\x21\x69\x1e\x10\x69\x41\x38\x48",
+       "\x5c\x0c\x2d\xf1\x3a\x1f\xd6\x76\x2b\x6e\x50\xfb\x3e\x08\x0e\x64\x9c\x3a\x7a\x8d\xda\x41\x5c\x42\xfb\x63\x71\x36",
+       104 },
+      { GCRY_MD_SHA3_224,
+       "\x64\xec\x02\x1c\x95\x85\xe0\x1f\xfe\x6d\x31\xbb\x50\xd4\x4c\x79\xb6\x99\x3d\x72\x67\x81\x63\xdb\x47\x49\x47\xa0\x53\x67\x46\x19\xd1\x58\x01\x6a\xdb\x24\x3f\x5c\x8d\x50\xaa\x92\xf5\x0a\xb3\x6e\x57\x9f\xf2\xda\xbb\x78\x0a\x2b\x52\x93\x70\xda\xa2\x99\x20\x7c\xfb\xcd\xd3\xa9\xa2\x50\x06\xd1\x9c\x4f\x1f\xe3\x3e\x4b\x1e\xae\xc3\x15\xd8\xc6\xee\x1e\x73\x06\x23\xfd\x19\x41\x87\x5b\x92\x4e\xb5\x7d\x6d\x0c\x2e\xdc\x4e\x78\xd6",
+       "\x36\xf5\x63\x0e\xc2\x82\x9b\x0f\xba\xd8\x4f\x15\x09\x32\xe4\x66\x47\xed\xcc\x45\x4e\x06\xb2\x31\x66\x66\x1d\x60",
+       105 },
+      { GCRY_MD_SHA3_224,
+       "\x59\x54\xba\xb5\x12\xcf\x32\x7d\x66\xb5\xd9\xf2\x96\x18\x00\x80\x40\x26\x24\xad\x76\x28\x50\x6b\x55\x5e\xea\x83\x82\x56\x23\x24\xcf\x45\x2f\xba\x4a\x21\x30\xde\x3e\x16\x5d\x11\x83\x1a\x27\x0d\x9c\xb9\x7c\xe8\xc2\xd3\x2a\x96\xf5\x0d\x71\x60\x0b\xb4\xca\x26\x8c\xf9\x8e\x90\xd6\x49\x6b\x0a\x66\x19\xa5\xa8\xc6\x3d\xb6\xd8\xa0\x63\x4d\xfc\x6c\x7e\xc8\xea\x9c\x00\x6b\x6c\x45\x6f\x1b\x20\xcd\x19\xe7\x81\xaf\x20\x45\x4a\xc8\x80",
+       "\xda\xc2\x59\x4b\xcd\x35\x7e\x63\x92\x8a\x21\xe9\x83\x48\xf2\x7d\x0f\xa2\xc7\x0e\xb0\x7c\x7e\x8e\x93\xd6\xd8\x4e",
+       106 },
+      { GCRY_MD_SHA3_224,
+       "\x03\xd9\xf9\x2b\x2c\x56\x57\x09\xa5\x68\x72\x4a\x0a\xff\x90\xf8\xf3\x47\xf4\x3b\x02\x33\x8f\x94\xa0\x3e\xd3\x2e\x6f\x33\x66\x6f\xf5\x80\x2d\xa4\xc8\x1b\xdc\xe0\xd0\xe8\x6c\x04\xaf\xd4\xed\xc2\xfc\x8b\x41\x41\xc2\x97\x5b\x6f\x07\x63\x9b\x19\x94\xc9\x73\xd9\xa9\xaf\xce\x3d\x9d\x36\x58\x62\x00\x34\x98\x51\x3b\xfa\x16\x6d\x26\x29\xe3\x14\xd9\x74\x41\x66\x7b\x00\x74\x14\xe7\x39\xd7\xfe\xbf\x0f\xe3\xc3\x2c\x17\xaa\x18\x8a\x86\x83",
+       "\x24\x97\x0d\xf3\xcf\x8c\x9e\x30\xdc\xbe\x66\x18\x17\xff\x74\x53\x8a\xd4\x3b\xc9\x0b\x14\x9e\xd7\xca\xb7\x81\x1b",
+       107 },
+      { GCRY_MD_SHA3_224,
+       "\xf3\x1e\x8b\x4f\x9e\x06\x21\xd5\x31\xd2\x2a\x38\x0b\xe5\xd9\xab\xd5\x6f\xae\xc5\x3c\xbd\x39\xb1\xfa\xb2\x30\xea\x67\x18\x44\x40\xe5\xb1\xd1\x54\x57\xbd\x25\xf5\x62\x04\xfa\x91\x7f\xa4\x8e\x66\x90\x16\xcb\x48\xc1\xff\xc1\xe1\xe4\x52\x74\xb3\xb4\x73\x79\xe0\x0a\x43\x84\x3c\xf8\x60\x1a\x55\x51\x41\x1e\xc1\x25\x03\xe5\xaa\xc4\x3d\x86\x76\xa1\xb2\x29\x7e\xc7\xa0\x80\x0d\xbf\xee\x04\x29\x2e\x93\x7f\x21\xc0\x05\xf1\x74\x11\x47\x30\x41",
+       "\xad\x9b\xf4\x20\xd2\xb5\x70\xeb\xe7\x92\x3a\x76\xb2\x53\xf1\x56\xf3\x51\x37\x12\x95\x5b\xcb\xb9\xa8\x73\x94\xdb",
+       108 },
+      { GCRY_MD_SHA3_224,
+       "\x75\x8e\xa3\xfe\xa7\x38\x97\x3d\xb0\xb8\xbe\x7e\x59\x9b\xbe\xf4\x51\x93\x73\xd6\xe6\xdc\xd7\x19\x5e\xa8\x85\xfc\x99\x1d\x89\x67\x62\x99\x27\x59\xc2\xa0\x90\x02\x91\x2f\xb0\x8e\x0c\xb5\xb7\x6f\x49\x16\x2a\xeb\x8c\xf8\x7b\x17\x2c\xf3\xad\x19\x02\x53\xdf\x61\x2f\x77\xb1\xf0\xc5\x32\xe3\xb5\xfc\x99\xc2\xd3\x1f\x8f\x65\x01\x16\x95\xa0\x87\xa3\x5e\xe4\xee\xe5\xe3\x34\xc3\x69\xd8\xee\x5d\x29\xf6\x95\x81\x5d\x86\x6d\xa9\x9d\xf3\xf7\x94\x03",
+       "\x2f\x60\x92\x82\x63\xfe\x1d\x5f\xa5\x13\x6d\xa8\xde\x1d\x2c\x3b\x60\xbd\x4b\x70\x0a\x3e\x2c\x25\x6e\x95\x36\xef",
+       109 },
+      { GCRY_MD_SHA3_224,
+       "\x47\xc6\xe0\xc2\xb7\x49\x48\x46\x59\x21\x86\x88\x04\xf0\xf7\xbd\x50\xdd\x32\x35\x83\xdc\x78\x4f\x99\x8a\x93\xcd\x1c\xa4\xc6\xef\x84\xd4\x1d\xc8\x1c\x2c\x40\xf3\x4b\x5b\xee\x6a\x93\x86\x7b\x3b\xdb\xa0\x05\x2c\x5f\x59\xe6\xf3\x65\x79\x18\xc3\x82\xe7\x71\xd3\x31\x09\x12\x2c\xc8\xbb\x0e\x1e\x53\xc4\xe3\xd1\x3b\x43\xce\x44\x97\x0f\x5e\x0c\x07\x9d\x2a\xd7\xd7\xa3\x54\x9c\xd7\x57\x60\xc2\x1b\xb1\x5b\x44\x75\x89\xe8\x6e\x8d\x76\xb1\xe9\xce\xd2",
+       "\xbf\xb4\x0f\x7e\x7f\x81\xf2\xfe\xc7\x64\x4e\x08\xfb\xc9\x9c\x76\x8a\xdc\x63\x14\xb8\xcc\xd8\x33\x33\x2f\x1b\xf8",
+       110 },
+      { GCRY_MD_SHA3_224,
+       "\xf6\x90\xa1\x32\xab\x46\xb2\x8e\xdf\xa6\x47\x92\x83\xd6\x44\x4e\x37\x1c\x64\x59\x10\x8a\xfd\x9c\x35\xdb\xd2\x35\xe0\xb6\xb6\xff\x4c\x4e\xa5\x8e\x75\x54\xbd\x00\x24\x60\x43\x3b\x21\x64\xca\x51\xe8\x68\xf7\x94\x7d\x7d\x7a\x0d\x79\x2e\x4a\xbf\x0b\xe5\xf4\x50\x85\x3c\xc4\x0d\x85\x48\x5b\x2b\x88\x57\xea\x31\xb5\xea\x6e\x4c\xcf\xa2\xf3\xa7\xef\x33\x80\x06\x6d\x7d\x89\x79\xfd\xac\x61\x8a\xad\x3d\x7e\x88\x6d\xea\x4f\x00\x5a\xe4\xad\x05\xe5\x06\x5f",
+       "\x19\x0e\x9f\xda\x8a\x7d\x78\x34\x3f\xf2\x4a\xde\x9f\xee\x69\x65\x0c\x76\x31\xad\x63\x29\xd1\x7d\x4b\xd5\x75\xdb",
+       111 },
+      { GCRY_MD_SHA3_224,
+       "\x58\xd6\xa9\x9b\xc6\x45\x88\x24\xb2\x56\x91\x67\x70\xa8\x41\x70\x40\x72\x1c\xcc\xfd\x4b\x79\xea\xcd\x8b\x65\xa3\x76\x7c\xe5\xba\x7e\x74\x10\x4c\x98\x5a\xc5\x6b\x8c\xc9\xae\xbd\x16\xfe\xbd\x4c\xda\x5a\xdb\x13\x0b\x0f\xf2\x32\x9c\xc8\xd6\x11\xeb\x14\xda\xc2\x68\xa2\xf9\xe6\x33\xc9\x9d\xe3\x39\x97\xfe\xa4\x1c\x52\xa7\xc5\xe1\x31\x7d\x5b\x5d\xae\xd3\x5e\xba\x7d\x5a\x60\xe4\x5d\x1f\xa7\xea\xab\xc3\x5f\x5c\x2b\x0a\x0f\x23\x79\x23\x19\x53\x32\x2c\x4e",
+       "\xe2\x6c\xd2\x0b\x87\x08\x3c\xb9\xf2\x46\xd2\x16\xe3\xda\x51\xef\x7c\x55\x19\xb4\x83\xdb\x43\x9d\x37\x25\x6d\xbe",
+       112 },
+      { GCRY_MD_SHA3_224,
+       "\xbe\xfa\xb5\x74\x39\x6d\x7f\x8b\x67\x05\xe2\xd5\xb5\x8b\x2c\x1c\x82\x0b\xb2\x4e\x3f\x4b\xae\x3e\x8f\xbc\xd3\x6d\xbf\x73\x4e\xe1\x4e\x5d\x6a\xb9\x72\xae\xdd\x35\x40\x23\x54\x66\xe8\x25\x85\x0e\xe4\xc5\x12\xea\x97\x95\xab\xfd\x33\xf3\x30\xd9\xfd\x7f\x79\xe6\x2b\xbb\x63\xa6\xea\x85\xde\x15\xbe\xae\xea\x6f\x8d\x20\x4a\x28\x95\x60\x59\xe2\x63\x2d\x11\x86\x1d\xfb\x0e\x65\xbc\x07\xac\x8a\x15\x93\x88\xd5\xc3\x27\x7e\x22\x72\x86\xf6\x5f\xf5\xe5\xb5\xae\xc1",
+       "\x6c\xaf\x80\x7f\x6a\xbc\x1a\x77\x21\xa5\xf2\x09\xfc\x09\xfd\x00\x47\x4b\x9e\x2a\x77\xef\x7b\x57\xe1\x32\x02\x71",
+       113 },
+      { GCRY_MD_SHA3_224,
+       "\x8e\x58\x14\x4f\xa9\x17\x9d\x68\x64\x78\x62\x2c\xe4\x50\xc7\x48\x26\x0c\x95\xd1\xba\x43\xb8\xf9\xb5\x9a\xbe\xca\x8d\x93\x48\x8d\xa7\x34\x63\xef\x40\x19\x8b\x4d\x16\xfb\x0b\x07\x07\x20\x13\x47\xe0\x50\x6f\xf1\x9d\x01\xbe\xa0\xf4\x2b\x8a\xf9\xe7\x1a\x1f\x1b\xd1\x68\x78\x10\x69\xd4\xd3\x38\xfd\xef\x00\xbf\x41\x9f\xbb\x00\x30\x31\xdf\x67\x1f\x4a\x37\x97\x95\x64\xf6\x92\x82\xde\x9c\x65\x40\x78\x47\xdd\x0d\xa5\x05\xab\x16\x41\xc0\x2d\xea\x4f\x0d\x83\x49\x86",
+       "\x64\xcd\x52\x91\xa1\xa0\x80\x7b\xa7\xc1\x41\x03\xa0\xf4\x6c\x63\x67\x95\xf8\xf8\xd3\xa1\x2e\x59\xe8\x8d\x9c\x51",
+       114 },
+      { GCRY_MD_SHA3_224,
+       "\xb5\x5c\x10\xea\xe0\xec\x68\x4c\x16\xd1\x34\x63\xf2\x92\x91\xbf\x26\xc8\x2e\x2f\xa0\x42\x2a\x99\xc7\x1d\xb4\xaf\x14\xdd\x9c\x7f\x33\xed\xa5\x2f\xd7\x3d\x01\x7c\xc0\xf2\xdb\xe7\x34\xd8\x31\xf0\xd8\x20\xd0\x6d\x5f\x89\xda\xcc\x48\x57\x39\x14\x4f\x8c\xfd\x47\x99\x22\x3b\x1a\xff\x90\x31\xa1\x05\xcb\x6a\x02\x9b\xa7\x1e\x6e\x58\x67\xd8\x5a\x55\x49\x91\xc3\x8d\xf3\xc9\xef\x8c\x1e\x1e\x9a\x76\x30\xbe\x61\xca\xab\xca\x69\x28\x0c\x39\x9c\x1f\xb7\xa1\x2d\x12\xae\xfc",
+       "\x29\x49\x12\x56\xa8\x0b\xf1\xa9\x32\x53\x48\xb5\x84\x1e\xdc\x72\x6f\xa8\xa5\x31\x17\x26\x8c\x47\xf7\x4b\x5e\x49",
+       115 },
+      { GCRY_MD_SHA3_224,
+       "\x2e\xee\xa6\x93\xf5\x85\xf4\xed\x6f\x6f\x88\x65\xbb\xae\x47\xa6\x90\x8a\xec\xd7\xc4\x29\xe4\xbe\xc4\xf0\xde\x1d\x0c\xa0\x18\x3f\xa2\x01\xa0\xcb\x14\xa5\x29\xb7\xd7\xac\x0e\x6f\xf6\x60\x7a\x32\x43\xee\x9f\xb1\x1b\xcf\x3e\x23\x04\xfe\x75\xff\xcd\xdd\x6c\x5c\x2e\x2a\x4c\xd4\x5f\x63\xc9\x62\xd0\x10\x64\x50\x58\xd3\x65\x71\x40\x4a\x6d\x2b\x4f\x44\x75\x54\x34\xd7\x69\x98\xe8\x34\x09\xc3\x20\x5a\xa1\x61\x5d\xb4\x40\x57\xdb\x99\x12\x31\xd2\xcb\x42\x62\x45\x74\xf5\x45",
+       "\xa5\x23\x44\x9b\x77\x0a\x8d\xe3\xb3\x9c\xd4\x46\x04\x61\x49\xfe\xae\xe3\x27\xd6\xd5\xb3\x99\x29\xb9\xaa\xc9\x15",
+       116 },
+      { GCRY_MD_SHA3_224,
+       "\xda\xb1\x1d\xc0\xb0\x47\xdb\x04\x20\xa5\x85\xf5\x6c\x42\xd9\x31\x75\x56\x28\x52\x42\x84\x99\xf6\x6a\x0d\xb8\x11\xfc\xdd\xda\xb2\xf7\xcd\xff\xed\x15\x43\xe5\xfb\x72\x11\x0b\x64\x68\x6b\xc7\xb6\x88\x7a\x53\x8a\xd4\x4c\x05\x0f\x1e\x42\x63\x1b\xc4\xec\x8a\x9f\x2a\x04\x71\x63\xd8\x22\xa3\x89\x89\xee\x4a\xab\x01\xb4\xc1\xf1\x61\xb0\x62\xd8\x73\xb1\xcf\xa3\x88\xfd\x30\x15\x14\xf6\x22\x24\x15\x7b\x9b\xef\x42\x3c\x77\x83\xb7\xaa\xc8\xd3\x0d\x65\xcd\x1b\xba\x8d\x68\x9c\x2d",
+       "\xab\xb2\xfc\xe2\x13\xce\x16\x4c\x94\xab\x7a\x76\x3c\x21\xf6\x38\xa3\xbb\x8d\x72\xf8\x02\xde\xad\xac\xc0\x23\xae",
+       117 },
+      { GCRY_MD_SHA3_224,
+       "\x42\xe9\x9a\x2f\x80\xae\xe0\xe0\x01\x27\x9a\x24\x34\xf7\x31\xe0\x1d\x34\xa4\x4b\x1a\x81\x01\x72\x69\x21\xc0\x59\x0c\x30\xf3\x12\x0e\xb8\x30\x59\xf3\x25\xe8\x94\xa5\xac\x95\x9d\xca\x71\xce\x22\x14\x79\x99\x16\x42\x4e\x85\x9d\x27\xd7\x89\x43\x7b\x9d\x27\x24\x0b\xf8\xc3\x5a\xdb\xaf\xce\xcc\x32\x2b\x48\xaa\x20\x5b\x29\x39\x62\xd8\x58\x65\x2a\xba\xcb\xd5\x88\xbc\xf6\xcb\xc3\x88\xd0\x99\x3b\xd6\x22\xf9\x6e\xd5\x46\x14\xc2\x5b\x6a\x9a\xa5\x27\x58\x9e\xaa\xff\xcf\x17\xdd\xf7",
+       "\xc4\x0d\x96\x9f\x72\x18\xd7\x1b\x90\x4c\x4e\x4e\xac\xeb\x04\x73\xba\x0a\x2e\x73\x39\x64\x9d\xa5\xdf\xeb\x89\x38",
+       118 },
+      { GCRY_MD_SHA3_224,
+       "\x3c\x9b\x46\x45\x0c\x0f\x2c\xae\x8e\x38\x23\xf8\xbd\xb4\x27\x7f\x31\xb7\x44\xce\x2e\xb1\x70\x54\xbd\xdc\x6d\xff\x36\xaf\x7f\x49\xfb\x8a\x23\x20\xcc\x3b\xdf\x8e\x0a\x2e\xa2\x9a\xd3\xa5\x5d\xe1\x16\x5d\x21\x9a\xde\xdd\xb5\x17\x52\x53\xe2\xd1\x48\x9e\x9b\x6f\xdd\x02\xe2\xc3\xd3\xa4\xb5\x4d\x60\xe3\xa4\x73\x34\xc3\x79\x13\xc5\x69\x53\x78\xa6\x69\xe9\xb7\x2d\xec\x32\xaf\x54\x34\xf9\x3f\x46\x17\x6e\xbf\x04\x4c\x47\x84\x46\x7c\x70\x04\x70\xd0\xc0\xb4\x0c\x8a\x08\x8c\x81\x58\x16",
+       "\x2e\xb2\x8f\xdf\x45\x8d\x4f\xec\xb5\xb4\x41\xd9\x10\xb5\x76\xf6\x30\xe6\x66\xbb\xf3\x0a\xac\x90\xab\x64\x42\x5b",
+       119 },
+      { GCRY_MD_SHA3_224,
+       "\xd1\xe6\x54\xb7\x7c\xb1\x55\xf5\xc7\x79\x71\xa6\x4d\xf9\xe5\xd3\x4c\x26\xa3\xca\xd6\xc7\xf6\xb3\x00\xd3\x9d\xeb\x19\x10\x09\x46\x91\xad\xaa\x09\x5b\xe4\xba\x5d\x86\x69\x0a\x97\x64\x28\x63\x5d\x55\x26\xf3\xe9\x46\xf7\xdc\x3b\xd4\xdb\xc7\x89\x99\xe6\x53\x44\x11\x87\xa8\x1f\x9a\xdc\xd5\xa3\xc5\xf2\x54\xbc\x82\x56\xb0\x15\x8f\x54\x67\x3d\xcc\x12\x32\xf6\xe9\x18\xeb\xfc\x6c\x51\xce\x67\xea\xeb\x04\x2d\x9f\x57\xee\xc4\xbf\xe9\x10\xe1\x69\xaf\x78\xb3\xde\x48\xd1\x37\xdf\x4f\x28\x40",
+       "\xa3\x38\x7b\x2f\xa2\x3a\x13\xbf\xae\x77\x89\x5f\x1f\x93\x93\x5a\x07\x10\xee\x3a\x02\x7f\xf0\xd6\x39\x9d\x8e\xcc",
+       120 },
+      { GCRY_MD_SHA3_224,
+       "\x62\x6f\x68\xc1\x8a\x69\xa6\x59\x01\x59\xa9\xc4\x6b\xe0\x3d\x59\x65\x69\x8f\x2d\xac\x3d\xe7\x79\xb8\x78\xb3\xd9\xc4\x21\xe0\xf2\x1b\x95\x5a\x16\xc7\x15\xc1\xec\x1e\x22\xce\x3e\xb6\x45\xb8\xb4\xf2\x63\xf6\x06\x60\xea\x30\x28\x98\x1e\xeb\xd6\xc8\xc3\xa3\x67\x28\x5b\x69\x1c\x8e\xe5\x69\x44\xa7\xcd\x12\x17\x99\x7e\x1d\x9c\x21\x62\x0b\x53\x6b\xdb\xd5\xde\x89\x25\xff\x71\xde\xc6\xfb\xc0\x66\x24\xab\x6b\x21\xe3\x29\x81\x3d\xe9\x0d\x1e\x57\x2d\xfb\x89\xa1\x81\x20\xc3\xf6\x06\x35\x5d\x25",
+       "\x75\x75\x5f\x46\xc2\xfc\x86\xbd\x4a\xae\x75\x91\x9c\x6c\xa5\xb1\xa7\x37\x5e\x46\x6c\xa3\x17\x0f\x70\xee\xe4\x90",
+       121 },
+      { GCRY_MD_SHA3_224,
+       "\x65\x1a\x6f\xb3\xc4\xb8\x0c\x7c\x68\xc6\x01\x16\x75\xe6\x09\x4e\xb5\x6a\xbf\x5f\xc3\x05\x73\x24\xeb\xc6\x47\x78\x25\x06\x1f\x9f\x27\xe7\xa9\x46\x33\xab\xd1\xfa\x59\x8a\x74\x6e\x4a\x57\x7c\xaf\x52\x4c\x52\xec\x17\x88\x47\x1f\x92\xb8\xc3\x7f\x23\x79\x5c\xa1\x9d\x55\x9d\x44\x6c\xab\x16\xcb\xcd\xce\x90\xb7\x9f\xa1\x02\x6c\xee\x77\xbf\x4a\xb1\xb5\x03\xc5\xb9\x4c\x22\x56\xad\x75\xb3\xea\xc6\xfd\x5d\xcb\x96\xac\xa4\xb0\x3a\x83\x4b\xfb\x4e\x9a\xf9\x88\xce\xcb\xf2\xae\x59\x7c\xb9\x09\x79\x40",
+       "\x71\x84\xc6\x9e\xe1\xc4\x3f\xd5\x64\x10\x2c\xd6\x8e\xf8\x98\xd5\xd0\xd8\x26\x4b\x9b\x0d\x04\x46\x91\xbc\x18\xaf",
+       122 },
+      { GCRY_MD_SHA3_224,
+       "\x8a\xaf\x07\x2f\xce\x8a\x2d\x96\xbc\x10\xb3\xc9\x1c\x80\x9e\xe9\x30\x72\xfb\x20\x5c\xa7\xf1\x0a\xbd\x82\xec\xd8\x2c\xf0\x40\xb1\xbc\x49\xea\x13\xd1\x85\x78\x15\xc0\xe9\x97\x81\xde\x3a\xdb\xb5\x44\x3c\xe1\xc8\x97\xe5\x51\x88\xce\xaf\x22\x1a\xa9\x68\x16\x38\xde\x05\xae\x1b\x32\x29\x38\xf4\x6b\xce\x51\x54\x3b\x57\xec\xdb\x4c\x26\x62\x72\x25\x9d\x17\x98\xde\x13\xbe\x90\xe1\x0e\xfe\xc2\xd0\x74\x84\xd9\xb2\x1a\x38\x70\xe2\xaa\x9e\x06\xc2\x1a\xa2\xd0\xc9\xcf\x42\x00\x80\xa8\x0a\x91\xde\xe1\x6f",
+       "\xf5\x0c\xf7\x8f\xf4\x65\x13\xc9\x05\x39\x9c\xc2\x51\x06\x81\xa9\x0c\xe0\x89\xfc\xed\x40\xfb\xc9\xcf\x21\x8c\xa4",
+       123 },
+      { GCRY_MD_SHA3_224,
+       "\x53\xf9\x18\xfd\x00\xb1\x70\x1b\xd5\x04\xf8\xcd\xea\x80\x3a\xcc\xa2\x1a\xc1\x8c\x56\x4a\xb9\x0c\x2a\x17\xda\x59\x2c\x7d\x69\x68\x8f\x65\x80\x57\x53\x95\x55\x1e\x8c\xd3\x3e\x0f\xef\x08\xca\x6e\xd4\x58\x8d\x4d\x14\x0b\x3e\x44\xc0\x32\x35\x5d\xf1\xc5\x31\x56\x4d\x7f\x48\x35\x75\x33\x44\x34\x5a\x67\x81\xe1\x1c\xd5\xe0\x95\xb7\x3d\xf5\xf8\x2c\x8a\xe3\xad\x00\x87\x79\x36\x89\x66\x71\xe9\x47\xcc\x52\xe2\xb2\x9d\xcd\x46\x3d\x90\xa0\xc9\x92\x91\x28\xda\x22\x2b\x5a\x21\x14\x50\xbb\xc0\xe0\x24\x48\xe2",
+       "\xf2\xaa\xbe\x18\xd7\xb4\xdd\x8e\x4d\xc0\xac\x8d\xcf\x4e\x90\x19\xc7\xc9\xaf\x33\xd4\xb9\x52\xda\x41\x21\x9f\xe5",
+       124 },
+      { GCRY_MD_SHA3_224,
+       "\xa6\x45\x99\xb8\xa6\x1b\x5c\xce\xc9\xe6\x7a\xed\x69\x44\x74\x59\xc8\xda\x3d\x1e\xc6\xc7\xc7\xc8\x2a\x74\x28\xb9\xb5\x84\xfa\x67\xe9\x0f\x68\xe2\xc0\x0f\xbb\xed\x46\x13\x66\x6e\x51\x68\xda\x4a\x16\xf3\x95\xf7\xa3\xc3\x83\x2b\x3b\x13\x4b\xfc\x9c\xba\xa9\x5d\x2a\x0f\xe2\x52\xf4\x4a\xc6\x68\x1e\xb6\xd4\x0a\xb9\x1c\x1d\x02\x82\xfe\xd6\x70\x1c\x57\x46\x3d\x3c\x5f\x2b\xb8\xc6\xa7\x30\x1f\xb4\x57\x6a\xa3\xb5\xf1\x55\x10\xdb\x89\x56\xff\x77\x47\x8c\x26\xa7\xc0\x9b\xea\x7b\x39\x8c\xfc\x83\x50\x3f\x53\x8e",
+       "\xac\x5d\x00\xd1\x77\xe7\x1d\x7b\x9a\x97\x27\x0e\x62\x00\xe4\xd3\xd0\x78\x51\xeb\x2e\x58\xb1\x2b\xe0\xbe\xed\x95",
+       125 },
+      { GCRY_MD_SHA3_224,
+       "\x0e\x3a\xb0\xe0\x54\x73\x9b\x00\xcd\xb6\xa8\x7b\xd1\x2c\xae\x02\x4b\x54\xcb\x5e\x55\x0e\x6c\x42\x53\x60\xc2\xe8\x7e\x59\x40\x1f\x5e\xc2\x4e\xf0\x31\x48\x55\xf0\xf5\x6c\x47\x69\x5d\x56\xa7\xfb\x14\x17\x69\x3a\xf2\xa1\xed\x52\x91\xf2\xfe\xe9\x5f\x75\xee\xd5\x4a\x1b\x1c\x2e\x81\x22\x6f\xbf\xf6\xf6\x3a\xde\x58\x49\x11\xc7\x19\x67\xa8\xeb\x70\x93\x3b\xc3\xf5\xd1\x5b\xc9\x1b\x5c\x26\x44\xd9\x51\x6d\x3c\x3a\x8c\x15\x4e\xe4\x8e\x11\x8b\xd1\x44\x2c\x04\x3c\x7a\x0d\xba\x5a\xc5\xb1\xd5\x36\x0a\xae\x5b\x90\x65",
+       "\xcb\x79\x79\xb4\xc6\xc2\x82\x6c\xde\xf7\xe1\xaa\xda\x85\xf8\xc4\x54\x6d\xd5\x9d\x29\xfc\x0a\xea\x44\x4f\x80\x77",
+       126 },
+      { GCRY_MD_SHA3_224,
+       "\xa6\x2f\xc5\x95\xb4\x09\x6e\x63\x36\xe5\x3f\xcd\xfc\x8d\x1c\xc1\x75\xd7\x1d\xac\x9d\x75\x0a\x61\x33\xd2\x31\x99\xea\xac\x28\x82\x07\x94\x4c\xea\x6b\x16\xd2\x76\x31\x91\x5b\x46\x19\xf7\x43\xda\x2e\x30\xa0\xc0\x0b\xbd\xb1\xbb\xb3\x5a\xb8\x52\xef\x3b\x9a\xec\x6b\x0a\x8d\xcc\x6e\x9e\x1a\xba\xa3\xad\x62\xac\x0a\x6c\x5d\xe7\x65\xde\x2c\x37\x11\xb7\x69\xe3\xfd\xe4\x4a\x74\x01\x6f\xff\x82\xac\x46\xfa\x8f\x17\x97\xd3\xb2\xa7\x26\xb6\x96\xe3\xde\xa5\x53\x04\x39\xac\xee\x3a\x45\xc2\xa5\x1b\xc3\x2d\xd0\x55\x65\x0b",
+       "\xf9\xd8\xcc\xf6\x68\x46\x93\xc4\x0c\x81\xeb\xbd\x00\x6c\x49\x98\x4f\xba\xf3\xa2\xb2\xe9\x05\xab\xe6\x07\x65\xdd",
+       127 },
+      { GCRY_MD_SHA3_224,
+       "\x2b\x6d\xb7\xce\xd8\x66\x5e\xbe\x9d\xeb\x08\x02\x95\x21\x84\x26\xbd\xaa\x7c\x6d\xa9\xad\xd2\x08\x89\x32\xcd\xff\xba\xa1\xc1\x41\x29\xbc\xcd\xd7\x0f\x36\x9e\xfb\x14\x92\x85\x85\x8d\x2b\x1d\x15\x5d\x14\xde\x2f\xdb\x68\x0a\x8b\x02\x72\x84\x05\x51\x82\xa0\xca\xe2\x75\x23\x4c\xc9\xc9\x28\x63\xc1\xb4\xab\x66\xf3\x04\xcf\x06\x21\xcd\x54\x56\x5f\x5b\xff\x46\x1d\x3b\x46\x1b\xd4\x0d\xf2\x81\x98\xe3\x73\x25\x01\xb4\x86\x0e\xad\xd5\x03\xd2\x6d\x6e\x69\x33\x8f\x4e\x04\x56\xe9\xe9\xba\xf3\xd8\x27\xae\x68\x5f\xb1\xd8\x17",
+       "\xed\x1f\x63\x87\xa7\xbe\x09\x02\x77\xb6\x5a\x5f\xcd\x70\x40\xc7\xbe\x0e\xea\xf0\xfd\x7f\x14\x96\x80\x97\x87\x3b",
+       128 },
+      { GCRY_MD_SHA3_224,
+       "\x10\xdb\x50\x9b\x2c\xdc\xab\xa6\xc0\x62\xae\x33\xbe\x48\x11\x6a\x29\xeb\x18\xe3\x90\xe1\xbb\xad\xa5\xca\x0a\x27\x18\xaf\xbc\xd2\x34\x31\x44\x01\x06\x59\x48\x93\x04\x3c\xc7\xf2\x62\x52\x81\xbf\x7d\xe2\x65\x58\x80\x96\x6a\x23\x70\x5f\x0c\x51\x55\xc2\xf5\xcc\xa9\xf2\xc2\x14\x2e\x96\xd0\xa2\xe7\x63\xb7\x06\x86\xcd\x42\x1b\x5d\xb8\x12\xda\xce\xd0\xc6\xd6\x50\x35\xfd\xe5\x58\xe9\x4f\x26\xb3\xe6\xdd\xe5\xbd\x13\x98\x0c\xc8\x02\x92\xb7\x23\x01\x3b\xd0\x33\x28\x45\x84\xbf\xf2\x76\x57\x87\x1b\x0c\xf0\x7a\x84\x9f\x4a\xe2",
+       "\x0a\x27\xce\x69\x73\xcb\x22\xa8\xb1\x00\x57\xa8\xe7\xa6\x54\x05\x8b\x71\xe6\xd8\xc6\x9c\x65\x34\x15\xff\x0c\x81",
+       129 },
+      { GCRY_MD_SHA3_224,
+       "\x93\x34\xde\x60\xc9\x97\xbd\xa6\x08\x61\x01\xa6\x31\x4f\x64\xe4\x45\x8f\x5f\xf9\x45\x0c\x50\x9d\xf0\x06\xe8\xc5\x47\x98\x3c\x65\x1c\xa9\x78\x79\x17\x5a\xab\xa0\xc5\x39\xe8\x2d\x05\xc1\xe0\x2c\x48\x09\x75\xcb\xb3\x01\x18\x12\x10\x61\xb1\xeb\xac\x4f\x8d\x9a\x37\x81\xe2\xdb\x6b\x18\x04\x2e\x01\xec\xf9\x01\x7a\x64\xa0\xe5\x74\x47\xec\x7f\xcb\xe6\xa7\xf8\x25\x85\xf7\x40\x3e\xe2\x22\x3d\x52\xd3\x7b\x4b\xf4\x26\x42\x86\x13\xd6\xb4\x25\x79\x80\x97\x2a\x0a\xca\xb5\x08\xa7\x62\x0c\x1c\xb2\x8e\xb4\xe9\xd3\x0f\xc4\x13\x61\xec",
+       "\xbe\x3b\xe4\x99\x80\xf4\x3f\xb6\x59\x8b\xe9\x21\xd7\xd8\xfd\xa1\xf3\x97\xf6\x05\xd9\x70\x8c\x5d\x12\x5c\x4e\x9f",
+       130 },
+      { GCRY_MD_SHA3_224,
+       "\xe8\x8a\xb0\x86\x89\x16\x93\xaa\x53\x5c\xeb\x20\xe6\x4c\x7a\xb9\x7c\x7d\xd3\x54\x8f\x37\x86\x33\x98\x97\xa5\xf0\xc3\x90\x31\x54\x9c\xa8\x70\x16\x6e\x47\x77\x43\xcc\xfb\xe0\x16\xb4\x42\x8d\x89\x73\x8e\x42\x6f\x5f\xfe\x81\x62\x61\x37\xf1\x7a\xec\xff\x61\xb7\x2d\xbe\xe2\xdc\x20\x96\x18\x80\xcf\xe2\x81\xdf\xab\x5e\xe3\x8b\x19\x21\x88\x14\x50\xe1\x60\x32\xde\x5e\x4d\x55\xad\x8d\x4f\xca\x60\x97\x21\xb0\x69\x2b\xac\x79\xbe\x5a\x06\xe1\x77\xfe\x8c\x80\xc0\xc8\x35\x19\xfb\x33\x47\xde\x9f\x43\xd5\x56\x1c\xb8\x10\x7b\x9b\x5e\xdc",
+       "\x93\x21\x37\xbf\x2c\xd3\x2d\xdf\xd3\xba\x80\xc5\x25\x26\x87\x30\xb6\xf7\x45\x86\x01\xb5\x29\x6a\xeb\x32\x51\x83",
+       131 },
+      { GCRY_MD_SHA3_224,
+       "\xfd\x19\xe0\x1a\x83\xeb\x6e\xc8\x10\xb9\x45\x82\xcb\x8f\xbf\xa2\xfc\xb9\x92\xb5\x36\x84\xfb\x74\x8d\x22\x64\xf0\x20\xd3\xb9\x60\xcb\x1d\x6b\x8c\x34\x8c\x2b\x54\xa9\xfc\xea\x72\x33\x0c\x2a\xaa\x9a\x24\xec\xdb\x00\xc4\x36\xab\xc7\x02\x36\x1a\x82\xbb\x88\x28\xb8\x53\x69\xb8\xc7\x2e\xce\x00\x82\xfe\x06\x55\x71\x63\x89\x9c\x2a\x0e\xfa\x46\x6c\x33\xc0\x43\x43\xa8\x39\x41\x70\x57\x39\x9a\x63\xa3\x92\x9b\xe1\xee\x48\x05\xd6\xce\x3e\x5d\x0d\x09\x67\xfe\x90\x04\x69\x6a\x56\x63\xf4\xca\xc9\x17\x90\x06\xa2\xce\xb7\x55\x42\xd7\x5d\x68",
+       "\x79\x66\x98\xce\x24\xef\xcd\xa8\x21\x4d\x16\x11\x38\xf3\xc7\xda\x6d\x76\x15\xe4\xcf\x1d\xac\x63\xb6\x99\x41\xf9",
+       132 },
+      { GCRY_MD_SHA3_224,
+       "\x59\xae\x20\xb6\xf7\xe0\xb3\xc7\xa9\x89\xaf\xb2\x83\x24\xa4\x0f\xca\x25\xd8\x65\x1c\xf1\xf4\x6a\xe3\x83\xef\x6d\x84\x41\x58\x7a\xa1\xc0\x4c\x3e\x3b\xf8\x8e\x81\x31\xce\x61\x45\xcf\xb8\x97\x3d\x96\x1e\x84\x32\xb2\x02\xfa\x5a\xf3\xe0\x9d\x62\x5f\xaa\xd8\x25\xbc\x19\xda\x9b\x5c\x6c\x20\xd0\x2a\xbd\xa2\xfc\xc5\x8b\x5b\xd3\xfe\x50\x7b\xf2\x01\x26\x3f\x30\x54\x38\x19\x51\x0c\x12\xbc\x23\xe2\xdd\xb4\xf7\x11\xd0\x87\xa8\x6e\xdb\x1b\x35\x53\x13\x36\x3a\x2d\xe9\x96\xb8\x91\x02\x5e\x14\x70\x36\x08\x74\x01\xcc\xf3\xca\x78\x15\xbf\x3c\x49",
+       "\xb2\x16\x93\x0e\x15\x8d\x65\xfb\x1f\xf4\x24\xf9\xea\xb6\xcd\x28\x99\x62\x31\xef\x5e\xe1\xd6\x5d\xbe\x29\xd3\x70",
+       133 },
+      { GCRY_MD_SHA3_224,
+       "\x77\xee\x80\x4b\x9f\x32\x95\xab\x23\x62\x79\x8b\x72\xb0\xa1\xb2\xd3\x29\x1d\xce\xb8\x13\x98\x96\x35\x58\x30\xf3\x4b\x3b\x32\x85\x61\x53\x1f\x80\x79\xb7\x9a\x6e\x99\x80\x70\x51\x50\x86\x64\x02\xfd\xc1\x76\xc0\x58\x97\xe3\x59\xa6\xcb\x1a\x7a\xb0\x67\x38\x3e\xb4\x97\x18\x2a\x7e\x5a\xef\x70\x38\xe4\xc9\x6d\x13\x3b\x27\x82\x91\x74\x17\xe3\x91\x53\x5b\x5e\x1b\x51\xf4\x7d\x8e\xd7\xe4\xd4\x02\x5f\xe9\x8d\xc8\x7b\x9c\x16\x22\x61\x4b\xff\x3d\x10\x29\xe6\x8e\x37\x2d\xe7\x19\x80\x38\x57\xca\x52\x06\x7c\xdd\xaa\xd9\x58\x95\x1c\xb2\x06\x8c\xc6",
+       "\xaf\x6c\x67\x6a\x62\x28\x8b\x2d\x25\xa8\x62\xf8\x86\x6b\x26\x2a\x74\xe3\xd2\xa0\xd4\x14\xb9\x66\xce\x60\x1e\x14",
+       134 },
+      { GCRY_MD_SHA3_224,
+       "\xb7\x71\xd5\xce\xf5\xd1\xa4\x1a\x93\xd1\x56\x43\xd7\x18\x1d\x2a\x2e\xf0\xa8\xe8\x4d\x91\x81\x2f\x20\xed\x21\xf1\x47\xbe\xf7\x32\xbf\x3a\x60\xef\x40\x67\xc3\x73\x4b\x85\xbc\x8c\xd4\x71\x78\x0f\x10\xdc\x9e\x82\x91\xb5\x83\x39\xa6\x77\xb9\x60\x21\x8f\x71\xe7\x93\xf2\x79\x7a\xea\x34\x94\x06\x51\x28\x29\x06\x5d\x37\xbb\x55\xea\x79\x6f\xa4\xf5\x6f\xd8\x89\x6b\x49\xb2\xcd\x19\xb4\x32\x15\xad\x96\x7c\x71\x2b\x24\xe5\x03\x2d\x06\x52\x32\xe0\x2c\x12\x74\x09\xd2\xed\x41\x46\xb9\xd7\x5d\x76\x3d\x52\xdb\x98\xd9\x49\xd3\xb0\xfe\xd6\xa8\x05\x2f\xbb",
+       "\x41\x8c\x83\xeb\x01\x88\x1b\x4f\x38\x54\x46\x65\x20\x1d\xd0\x5c\x93\x9c\xa0\x47\xd3\x18\x34\xf6\x37\x34\x23\x42",
+       135 },
+      { GCRY_MD_SHA3_224,
+       "\xb3\x2d\x95\xb0\xb9\xaa\xd2\xa8\x81\x6d\xe6\xd0\x6d\x1f\x86\x00\x85\x05\xbd\x8c\x14\x12\x4f\x6e\x9a\x16\x3b\x5a\x2a\xde\x55\xf8\x35\xd0\xec\x38\x80\xef\x50\x70\x0d\x3b\x25\xe4\x2c\xc0\xaf\x05\x0c\xcd\x1b\xe5\xe5\x55\xb2\x30\x87\xe0\x4d\x7b\xf9\x81\x36\x22\x78\x0c\x73\x13\xa1\x95\x4f\x87\x40\xb6\xee\x2d\x3f\x71\xf7\x68\xdd\x41\x7f\x52\x04\x82\xbd\x3a\x08\xd4\xf2\x22\xb4\xee\x9d\xbd\x01\x54\x47\xb3\x35\x07\xdd\x50\xf3\xab\x42\x47\xc5\xde\x9a\x8a\xbd\x62\xa8\xde\xce\xa0\x1e\x3b\x87\xc8\xb9\x27\xf5\xb0\x8b\xeb\x37\x67\x4c\x6f\x8e\x38\x0c\x04",
+       "\x64\xd7\x88\x17\x71\x4f\xe0\x52\x72\xd3\x80\x5e\x6e\x19\x05\x6b\x16\x49\x03\x6c\xdc\xd5\x09\x4f\xd1\xcc\x89\x0a",
+       136 },
+      { GCRY_MD_SHA3_224,
+       "\x04\x41\x0e\x31\x08\x2a\x47\x58\x4b\x40\x6f\x05\x13\x98\xa6\xab\xe7\x4e\x4d\xa5\x9b\xb6\xf8\x5e\x6b\x49\xe8\xa1\xf7\xf2\xca\x00\xdf\xba\x54\x62\xc2\xcd\x2b\xfd\xe8\xb6\x4f\xb2\x1d\x70\xc0\x83\xf1\x13\x18\xb5\x6a\x52\xd0\x3b\x81\xca\xc5\xee\xc2\x9e\xb3\x1b\xd0\x07\x8b\x61\x56\x78\x6d\xa3\xd6\xd8\xc3\x30\x98\xc5\xc4\x7b\xb6\x7a\xc6\x4d\xb1\x41\x65\xaf\x65\xb4\x45\x44\xd8\x06\xdd\xe5\xf4\x87\xd5\x37\x3c\x7f\x97\x92\xc2\x99\xe9\x68\x6b\x7e\x58\x21\xe7\xc8\xe2\x45\x83\x15\xb9\x96\xb5\x67\x7d\x92\x6d\xac\x57\xb3\xf2\x2d\xa8\x73\xc6\x01\x01\x6a\x0d",
+       "\x2c\x4e\x7c\x53\x7d\x0e\x2a\xf2\x26\x1a\x66\x9b\xc2\x4b\xd0\xdf\x16\xd2\xc7\x2a\x7f\x98\xd7\xa5\xef\x6a\x81\x50",
+       137 },
+      { GCRY_MD_SHA3_224,
+       "\x8b\x81\xe9\xba\xdd\xe0\x26\xf1\x4d\x95\xc0\x19\x97\x70\x24\xc9\xe1\x3d\xb7\xa5\xcd\x21\xf9\xe9\xfc\x49\x1d\x71\x61\x64\xbb\xac\xdc\x70\x60\xd8\x82\x61\x5d\x41\x14\x38\xae\xa0\x56\xc3\x40\xcd\xf9\x77\x78\x8f\x6e\x17\xd1\x18\xde\x55\x02\x68\x55\xf9\x32\x70\x47\x2d\x1f\xd1\x8b\x9e\x7e\x81\x2b\xae\x10\x7e\x0d\xfd\xe7\x06\x33\x01\xb7\x1f\x6c\xfe\x4e\x22\x5c\xab\x3b\x23\x29\x05\xa5\x6e\x99\x4f\x08\xee\x28\x91\xba\x92\x2d\x49\xc3\xda\xfe\xb7\x5f\x7c\x69\x75\x0c\xb6\x7d\x82\x2c\x96\x17\x6c\x46\xbd\x8a\x29\xf1\x70\x13\x73\xfb\x09\xa1\xa6\xe3\xc7\x15\x8f",
+       "\xdf\x1f\xcb\x80\xab\x38\x0c\xa3\x3b\xdb\x61\xf9\x6a\xda\xb3\x34\x93\x7e\x19\x0f\x03\xc1\xb7\x8b\x21\x9e\x50\xf8",
+       138 },
+      { GCRY_MD_SHA3_224,
+       "\xfa\x6e\xed\x24\xda\x66\x66\xa2\x22\x08\x14\x6b\x19\xa5\x32\xc2\xec\x9b\xa9\x4f\x09\xf1\xde\xf1\xe7\xfc\x13\xc3\x99\xa4\x8e\x41\xac\xc2\xa5\x89\xd0\x99\x27\x62\x96\x34\x8f\x39\x62\x53\xb5\x7c\xb0\xe4\x02\x91\xbd\x28\x27\x73\x65\x6b\x6e\x0d\x8b\xea\x1c\xda\x08\x4a\x37\x38\x81\x6a\x84\x04\x85\xfc\xf3\xfb\x30\x7f\x77\x7f\xa5\xfe\xac\x48\x69\x5c\x2a\xf4\x76\x97\x20\x25\x8c\x77\x94\x3f\xb4\x55\x6c\x36\x2d\x9c\xba\x8b\xf1\x03\xae\xb9\x03\x4b\xaa\x8e\xa8\xbf\xb9\xc4\xf8\xe6\x74\x2c\xe0\xd5\x2c\x49\xea\x8e\x97\x4f\x33\x96\x12\xe8\x30\xe9\xe7\xa9\xc2\x90\x65",
+       "\x0d\xd7\x7a\xda\x38\x4c\xab\x6a\x7a\xce\xd1\x9c\xfc\x80\x48\xc2\x56\x6d\x43\x03\xe2\x01\x0c\x98\xd1\x6a\x05\x16",
+       139 },
+      { GCRY_MD_SHA3_224,
+       "\x9b\xb4\xaf\x1b\x4f\x09\xc0\x71\xce\x3c\xaf\xa9\x2e\x4e\xb7\x3c\xe8\xa6\xf5\xd8\x2a\x85\x73\x34\x40\x36\x8d\xee\x4e\xb1\xcb\xc7\xb5\x5a\xc1\x50\x77\x3b\x6f\xe4\x7d\xbe\x03\x6c\x45\x58\x2e\xd6\x7e\x23\xf4\xc7\x45\x85\xda\xb5\x09\xdf\x1b\x83\x61\x05\x64\x54\x56\x42\xb2\xb1\xec\x46\x3e\x18\x04\x8f\xc2\x34\x77\xc6\xb2\xaa\x03\x55\x94\xec\xd3\x37\x91\xaf\x6a\xf4\xcb\xc2\xa1\x16\x6a\xba\x8d\x62\x8c\x57\xe7\x07\xf0\xb0\xe8\x70\x7c\xaf\x91\xcd\x44\xbd\xb9\x15\xe0\x29\x6e\x01\x90\xd5\x6d\x33\xd8\xdd\xe1\x0b\x5b\x60\x37\x78\x38\x97\x3c\x1d\x94\x3c\x22\xed\x33\x5e",
+       "\xb2\x56\xd0\xd6\xb6\xd6\xa7\x2e\x11\x3d\x10\x5a\xd9\x60\x1c\x91\x93\x3d\x53\xb2\x0a\x30\xd8\xe2\xcf\x33\xf9\x6d",
+       140 },
+      { GCRY_MD_SHA3_224,
+       "\x21\x67\xf0\x21\x18\xcc\x62\x04\x3e\x90\x91\xa6\x47\xca\xdb\xed\x95\x61\x1a\x52\x1f\xe0\xd6\x4e\x85\x18\xf1\x6c\x80\x8a\xb2\x97\x72\x55\x98\xae\x29\x68\x80\xa7\x73\x60\x7a\x79\x8f\x7c\x3c\xfc\xe8\x0d\x25\x1e\xbe\xc6\x88\x50\x15\xf9\xab\xf7\xea\xab\xae\x46\x79\x8f\x82\xcb\x59\x26\xde\x5c\x23\xf4\x4a\x3f\x9f\x95\x34\xb3\xc6\xf4\x05\xb5\x36\x4c\x2f\x8a\x8b\xdc\x5c\xa4\x9c\x74\x9b\xed\x8c\xe4\xba\x48\x89\x70\x62\xae\x84\x24\xca\x6d\xde\x5f\x55\xc0\xe4\x2a\x95\xd1\xe2\x92\xca\x54\xfb\x46\xa8\x4f\xbc\x9c\xd8\x7f\x2d\x0c\x9e\x74\x48\xde\x30\x43\xae\x22\xfd\xd2\x29",
+       "\xb9\x5f\x72\x51\x25\x46\xe4\xaf\x68\x59\x31\x24\x67\x17\xbc\x48\x2b\xfe\x92\x27\x89\xa2\x6e\xef\x01\xbd\xe8\x2d",
+       141 },
+      { GCRY_MD_SHA3_224,
+       "\x94\xb7\xfa\x0b\xc1\xc4\x4e\x94\x9b\x1d\x76\x17\xd3\x1b\x47\x20\xcb\xe7\xca\x57\xc6\xfa\x4f\x40\x94\xd4\x76\x15\x67\xe3\x89\xec\xc6\x4f\x69\x68\xe4\x06\x4d\xf7\x0d\xf8\x36\xa4\x7d\x0c\x71\x33\x36\xb5\x02\x8b\x35\x93\x0d\x29\xeb\x7a\x7f\x9a\x5a\xf9\xad\x5c\xf4\x41\x74\x5b\xae\xc9\xbb\x01\x4c\xee\xff\x5a\x41\xba\x5c\x1c\xe0\x85\xfe\xb9\x80\xba\xb9\xcf\x79\xf2\x15\x8e\x03\xef\x7e\x63\xe2\x9c\x38\xd7\x81\x6a\x84\xd4\xf7\x1e\x0f\x54\x8b\x7f\xc3\x16\x08\x5a\xe3\x8a\x06\x0f\xf9\xb8\xde\xc3\x6f\x91\xad\x9e\xbc\x0a\x5b\x6c\x33\x8c\xbb\x8f\x66\x59\xd3\x42\xa2\x43\x68\xcf",
+       "\x62\x82\x38\xa9\x53\x27\x27\xcc\x83\xf8\xfd\xce\xd1\x1d\x13\x8a\x17\xee\xe4\x82\x2c\x5d\x35\x49\x15\x7d\x6d\x5e",
+       142 },
+      { GCRY_MD_SHA3_224,
+       "\xea\x40\xe8\x3c\xb1\x8b\x3a\x24\x2c\x1e\xcc\x6c\xcd\x0b\x78\x53\xa4\x39\xda\xb2\xc5\x69\xcf\xc6\xdc\x38\xa1\x9f\x5c\x90\xac\xbf\x76\xae\xf9\xea\x37\x42\xff\x3b\x54\xef\x7d\x36\xeb\x7c\xe4\xff\x1c\x9a\xb3\xbc\x11\x9c\xff\x6b\xe9\x3c\x03\xe2\x08\x78\x33\x35\xc0\xab\x81\x37\xbe\x5b\x10\xcd\xc6\x6f\xf3\xf8\x9a\x1b\xdd\xc6\xa1\xee\xd7\x4f\x50\x4c\xbe\x72\x90\x69\x0b\xb2\x95\xa8\x72\xb9\xe3\xfe\x2c\xee\x9e\x6c\x67\xc4\x1d\xb8\xef\xd7\xd8\x63\xcf\x10\xf8\x40\xfe\x61\x8e\x79\x36\xda\x3d\xca\x5c\xa6\xdf\x93\x3f\x24\xf6\x95\x4b\xa0\x80\x1a\x12\x94\xcd\x8d\x7e\x66\xdf\xaf\xec",
+       "\xab\x0f\xd3\x08\x59\x05\x74\xd6\xf6\x13\x02\x32\xd9\xfa\xfa\x9f\xfc\xfe\xa7\x85\x79\xa6\xa8\xf6\x7c\x59\x04\x20",
+       143 },
+      { GCRY_MD_SHA3_224,
+       "\x15\x7d\x5b\x7e\x45\x07\xf6\x6d\x9a\x26\x74\x76\xd3\x38\x31\xe7\xbb\x76\x8d\x4d\x04\xcc\x34\x38\xda\x12\xf9\x01\x02\x63\xea\x5f\xca\xfb\xde\x25\x79\xdb\x2f\x6b\x58\xf9\x11\xd5\x93\xd5\xf7\x9f\xb0\x5f\xe3\x59\x6e\x3f\xa8\x0f\xf2\xf7\x61\xd1\xb0\xe5\x70\x80\x05\x5c\x11\x8c\x53\xe5\x3c\xdb\x63\x05\x52\x61\xd7\xc9\xb2\xb3\x9b\xd9\x0a\xcc\x32\x52\x0c\xbb\xdb\xda\x2c\x4f\xd8\x85\x6d\xbc\xee\x17\x31\x32\xa2\x67\x91\x98\xda\xf8\x30\x07\xa9\xb5\xc5\x15\x11\xae\x49\x76\x6c\x79\x2a\x29\x52\x03\x88\x44\x4e\xbe\xfe\x28\x25\x6f\xb3\x3d\x42\x60\x43\x9c\xba\x73\xa9\x47\x9e\xe0\x0c\x63",
+       "\xd5\x13\x42\x00\xdc\x98\xf4\xca\x48\x0c\xd2\x4d\x24\x49\x77\x37\x25\x2b\x55\x97\x7a\xe5\xa8\x69\xba\x27\x08\x9d",
+       144 },
+      { GCRY_MD_SHA3_224,
+       "\x83\x6b\x34\xb5\x15\x47\x6f\x61\x3f\xe4\x47\xa4\xe0\xc3\xf3\xb8\xf2\x09\x10\xac\x89\xa3\x97\x70\x55\xc9\x60\xd2\xd5\xd2\xb7\x2b\xd8\xac\xc7\x15\xa9\x03\x53\x21\xb8\x67\x03\xa4\x11\xdd\xe0\x46\x6d\x58\xa5\x97\x69\x67\x2a\xa6\x0a\xd5\x87\xb8\x48\x1d\xe4\xbb\xa5\x52\xa1\x64\x57\x79\x78\x95\x01\xec\x53\xd5\x40\xb9\x04\x82\x1f\x32\xb0\xbd\x18\x55\xb0\x4e\x48\x48\xf9\xf8\xcf\xe9\xeb\xd8\x91\x1b\xe9\x57\x81\xa7\x59\xd7\xad\x97\x24\xa7\x10\x2d\xbe\x57\x67\x76\xb7\xc6\x32\xbc\x39\xb9\xb5\xe1\x90\x57\xe2\x26\x55\x2a\x59\x94\xc1\xdb\xb3\xb5\xc7\x87\x1a\x11\xf5\x53\x70\x11\x04\x4c\x53",
+       "\x49\x4c\xbc\x9b\x64\x9e\x48\xec\x5a\xd7\x36\x4a\xeb\x9c\x8e\xdf\x4a\x4f\x40\x07\x89\xef\x20\x3f\x7b\x81\x8a\x44",
+       145 },
+      { GCRY_MD_SHA3_224,
+       "\xcc\x77\x84\xa4\x91\x2a\x7a\xb5\xad\x36\x20\xaa\xb2\x9b\xa8\x70\x77\xcd\x3c\xb8\x36\x36\xad\xc9\xf3\xdc\x94\xf5\x1e\xdf\x52\x1b\x21\x61\xef\x10\x8f\x21\xa0\xa2\x98\x55\x79\x81\xc0\xe5\x3c\xe6\xce\xd4\x5b\xdf\x78\x2c\x1e\xf2\x00\xd2\x9b\xab\x81\xdd\x64\x60\x58\x69\x64\xed\xab\x7c\xeb\xdb\xbe\xc7\x5f\xd7\x92\x50\x60\xf7\xda\x2b\x85\x3b\x2b\x08\x95\x88\xfa\x0f\x8c\x16\xec\x64\x98\xb1\x4c\x55\xdc\xee\x33\x5c\xb3\xa9\x1d\x69\x8e\x4d\x39\x3a\xb8\xe8\xea\xc0\x82\x5f\x8a\xde\xbe\xee\x19\x6d\xf4\x12\x05\xc0\x11\x67\x4e\x53\x42\x6c\xaa\x45\x3f\x8d\xe1\xcb\xb5\x79\x32\xb0\xb7\x41\xd4\xc6",
+       "\x7f\xf8\xa2\x8a\xb1\x20\x74\x10\x2a\xef\x3e\xfb\x89\x04\x28\x4b\x61\x72\x37\x32\x2a\x2b\xf7\x01\xc9\xfc\xfe\xfc",
+       146 },
+      { GCRY_MD_SHA3_224,
+       "\x76\x39\xb4\x61\xff\xf2\x70\xb2\x45\x5a\xc1\xd1\xaf\xce\x78\x29\x44\xae\xa5\xe9\x08\x7e\xb4\xa3\x9e\xb9\x6b\xb5\xc3\xba\xaf\x0e\x86\x8c\x85\x26\xd3\x40\x4f\x94\x05\xe7\x9e\x77\xbf\xac\x5f\xfb\x89\xbf\x19\x57\xb5\x23\xe1\x7d\x34\x1d\x73\x23\xc3\x02\xea\x70\x83\x87\x2d\xd5\xe8\x70\x56\x94\xac\xdd\xa3\x6d\x5a\x1b\x89\x5a\xaa\x16\xec\xa6\x10\x4c\x82\x68\x85\x32\xc8\xbf\xe1\x79\x0b\x5d\xc9\xf4\xec\x5f\xe9\x5b\xae\xd3\x7e\x1d\x28\x7b\xe7\x10\x43\x1f\x1e\x5e\x8e\xe1\x05\xbc\x42\xed\x37\xd7\x4b\x1e\x55\x98\x4b\xf1\xc0\x9f\xe6\xa1\xfa\x13\xef\x3b\x96\xfa\xea\xed\x6a\x2a\x19\x50\xa1\x21\x53",
+       "\x50\xcd\xbe\xab\x4b\xba\xa0\x86\x1f\x3e\x36\x4a\xf5\x20\xf9\xd8\xb5\x4e\x79\xe3\x87\x1a\xbc\xa7\xbb\xb2\xba\xe5",
+       147 },
+      { GCRY_MD_SHA3_224,
+       "\xeb\x65\x13\xfc\x61\xb3\x0c\xfb\xa5\x8d\x4d\x7e\x80\xf9\x4d\x14\x58\x90\x90\xcf\x1d\x80\xb1\xdf\x2e\x68\x08\x8d\xc6\x10\x49\x59\xba\x0d\x58\x3d\x58\x5e\x95\x78\xab\x0a\xec\x0c\xf3\x6c\x48\x43\x5e\xb5\x2e\xd9\xab\x4b\xbc\xe7\xa5\xab\xe6\x79\xc9\x7a\xe2\xdb\xe3\x5e\x8c\xc1\xd4\x5b\x06\xdd\xa3\xcf\x41\x86\x65\xc5\x7c\xbe\xe4\xbb\xb4\x7f\xa4\xca\xf7\x8f\x4e\xe6\x56\xfe\xc2\x37\xfe\x4e\xeb\xba\xfa\x20\x6e\x1e\xf2\xbd\x0e\xe4\xae\x71\xbd\x0e\x9b\x2f\x54\xf9\x1d\xaa\xdf\x1f\xeb\xfd\x70\x32\x38\x1d\x63\x6b\x73\x3d\xcb\x3b\xf7\x6f\xb1\x4e\x23\xaf\xf1\xf6\x8e\xd3\xdb\xcf\x75\xc9\xb9\x9c\x6f\x26",
+       "\x29\xb6\xb5\x23\xc8\x2f\x49\x90\x78\xc7\x36\x30\xba\x38\x22\x7b\xbd\x08\xef\x1a\x2d\x67\xb4\x25\xc0\x58\xde\xf5",
+       148 },
+      { GCRY_MD_SHA3_224,
+       "\x15\x94\xd7\x4b\xf5\xdd\xe4\x44\x26\x5d\x4c\x04\xda\xd9\x72\x1f\xf3\xe3\x4c\xbf\x62\x2d\xaf\x34\x1f\xe1\x6b\x96\x43\x1f\x6c\x4d\xf1\xf7\x60\xd3\x4f\x29\x6e\xb9\x7d\x98\xd5\x60\xad\x52\x86\xfe\xc4\xdc\xe1\x72\x4f\x20\xb5\x4f\xd7\xdf\x51\xd4\xbf\x13\x7a\xdd\x65\x6c\x80\x54\x6f\xb1\xbf\x51\x6d\x62\xee\x82\xba\xa9\x92\x91\x0e\xf4\xcc\x18\xb7\x0f\x3f\x86\x98\x27\x6f\xcf\xb4\x4e\x0e\xc5\x46\xc2\xc3\x9c\xfd\x8e\xe9\x10\x34\xff\x93\x03\x05\x8b\x42\x52\x46\x2f\x86\xc8\x23\xeb\x15\xbf\x48\x1e\x6b\x79\xcc\x3a\x02\x21\x85\x95\xb3\x65\x8e\x8b\x37\x38\x2b\xd5\x04\x8e\xae\xd5\xfd\x02\xc3\x79\x44\xe7\x3b",
+       "\x93\xce\x0c\x8d\x43\x55\x30\x0d\x4e\x63\xd6\x59\x91\x29\xde\xa7\x42\x0e\x5b\x60\x9d\xbb\x35\xbe\x43\x2b\x12\xb5",
+       149 },
+      { GCRY_MD_SHA3_224,
+       "\x4c\xfa\x12\x78\x90\x30\x26\xf6\x6f\xed\xd4\x13\x74\x55\x8b\xe1\xb5\x85\xd0\x3c\x5c\x55\xda\xc9\x43\x61\xdf\x28\x6d\x4b\xd3\x9c\x7c\xb8\x03\x7e\xd3\xb2\x67\xb0\x7c\x34\x66\x26\x44\x9d\x0c\xc5\xb0\xdd\x2c\xf2\x21\xf7\xe4\xc3\x44\x9a\x4b\xe9\x99\x85\xd2\xd5\xe6\x7b\xff\x29\x23\x35\x7d\xde\xab\x5a\xbc\xb4\x61\x9f\x3a\x3a\x57\xb2\xcf\x92\x8a\x02\x2e\xb2\x76\x76\xc6\xcf\x80\x56\x89\x00\x4f\xca\x4d\x41\xea\x6c\x2d\x0a\x47\x89\xc7\x60\x5f\x7b\xb8\x38\xdd\x88\x3b\x3a\xd3\xe6\x02\x7e\x77\x5b\xcf\x26\x28\x81\x42\x80\x99\xc7\xff\xf9\x5b\x14\xc0\x95\xea\x13\x0e\x0b\x99\x38\xa5\xe2\x2f\xc5\x26\x50\xf5\x91",
+       "\xd0\x28\x96\xd9\x57\xb5\x99\x86\x9f\x2b\x2a\x49\x92\xa4\x9e\xef\x7a\xb1\x30\x8f\x45\x6c\x78\xc8\x09\xbd\xac\x88",
+       150 },
+      { GCRY_MD_SHA3_224,
+       "\xd3\xe6\x5c\xb9\x2c\xfa\x79\x66\x2f\x6a\xf4\x93\xd6\x96\xa0\x7c\xcf\x32\xaa\xad\xcc\xef\xf0\x6e\x73\xe8\xd9\xf6\xf9\x09\x20\x9e\x66\x71\x5d\x6e\x97\x87\x88\xc4\x9e\xfb\x90\x87\xb1\x70\xec\xf3\xaa\x86\xd2\xd4\xd1\xa0\x65\xae\x0e\xfc\x89\x24\xf3\x65\xd6\x76\xb3\xcb\x9e\x2b\xec\x91\x8f\xd9\x6d\x0b\x43\xde\xe8\x37\x27\xc9\xa9\x3b\xf5\x6c\xa2\xb2\xe5\x9a\xdb\xa8\x56\x96\x54\x6a\x81\x50\x67\xfc\x7a\x78\x03\x96\x29\xd4\x94\x8d\x15\x7e\x7b\x0d\x82\x6d\x1b\xf8\xe8\x12\x37\xba\xb7\x32\x13\x12\xfd\xaa\x4d\x52\x17\x44\xf9\x88\xdb\x6f\xdf\x04\x54\x9d\x0f\xdc\xa3\x93\xd6\x39\xc7\x29\xaf\x71\x6e\x9c\x8b\xba\x48",
+       "\x18\x1e\x23\x01\xf6\x29\xa5\x69\x27\x1b\xb7\x40\xd3\x2b\x1d\x3b\xd2\x5a\xcb\x17\x9e\x9a\xeb\xef\x98\x00\x9e\xd4",
+       151 },
+      { GCRY_MD_SHA3_224,
+       "\x84\x2c\xc5\x83\x50\x45\x39\x62\x2d\x7f\x71\xe7\xe3\x18\x63\xa2\xb8\x85\xc5\x6a\x0b\xa6\x2d\xb4\xc2\xa3\xf2\xfd\x12\xe7\x96\x60\xdc\x72\x05\xca\x29\xa0\xdc\x0a\x87\xdb\x4d\xc6\x2e\xe4\x7a\x41\xdb\x36\xb9\xdd\xb3\x29\x3b\x9a\xc4\xba\xae\x7d\xf5\xc6\xe7\x20\x1e\x17\xf7\x17\xab\x56\xe1\x2c\xad\x47\x6b\xe4\x96\x08\xad\x2d\x50\x30\x9e\x7d\x48\xd2\xd8\xde\x4f\xa5\x8a\xc3\xcf\xea\xfe\xee\x48\xc0\xa9\xee\xc8\x84\x98\xe3\xef\xc5\x1f\x54\xd3\x00\xd8\x28\xdd\xdc\xcb\x9d\x0b\x06\xdd\x02\x1a\x29\xcf\x5c\xb5\xb2\x50\x69\x15\xbe\xb8\xa1\x19\x98\xb8\xb8\x86\xe0\xf9\xb7\xa8\x0e\x97\xd9\x1a\x7d\x01\x27\x0f\x9a\x77\x17",
+       "\x5c\xd0\x17\xb2\x69\xa6\x36\x6c\x78\x9d\x9c\xec\xae\xf3\xee\x9c\x35\x75\x18\x1a\x08\x42\x66\xd7\x8a\x02\x8d\xb7",
+       152 },
+      { GCRY_MD_SHA3_224,
+       "\x6c\x4b\x0a\x07\x19\x57\x3e\x57\x24\x86\x61\xe9\x8f\xeb\xe3\x26\x57\x1f\x9a\x1c\xa8\x13\xd3\x63\x85\x31\xae\x28\xb4\x86\x0f\x23\xc3\xa3\xa8\xac\x1c\x25\x00\x34\xa6\x60\xe2\xd7\x1e\x16\xd3\xac\xc4\xbf\x9c\xe2\x15\xc6\xf1\x5b\x1c\x0f\xc7\xe7\x7d\x3d\x27\x15\x7e\x66\xda\x9c\xee\xc9\x25\x8f\x8f\x2b\xf9\xe0\x2b\x4a\xc9\x37\x93\xdd\x6e\x29\xe3\x07\xed\xe3\x69\x5a\x0d\xf6\x3c\xbd\xc0\xfc\x66\xfb\x77\x08\x13\xeb\x14\x9c\xa2\xa9\x16\x91\x1b\xee\x49\x02\xc4\x7c\x78\x02\xe6\x9e\x40\x5f\xe3\xc0\x4c\xeb\x55\x22\x79\x2a\x55\x03\xfa\x82\x9f\x70\x72\x72\x22\x66\x21\xf7\xc4\x88\xa7\x69\x8c\x0d\x69\xaa\x56\x1b\xe9\xf3\x78",
+       "\xac\x28\x0a\x21\x1c\x98\xa0\x7f\x6f\xcb\xb7\x19\xf2\x50\xe3\xe5\xa6\xba\x2c\x93\xa8\x33\x97\x6c\x9f\x31\x47\xeb",
+       153 },
+      { GCRY_MD_SHA3_224,
+       "\x51\xb7\xdb\xb7\xce\x2f\xfe\xb4\x27\xa9\x1c\xcf\xe5\x21\x8f\xd4\x0f\x9e\x0b\x7e\x24\x75\x6d\x4c\x47\xcd\x55\x60\x60\x08\xbd\xc2\x7d\x16\x40\x09\x33\x90\x6f\xd9\xf3\x0e\xff\xdd\x48\x80\x02\x2d\x08\x11\x55\x34\x2a\xf3\xfb\x6c\xd5\x36\x72\xab\x7f\xb5\xb3\xa3\xbc\xbe\x47\xbe\x1f\xd3\xa2\x27\x8c\xae\x8a\x5f\xd6\x1c\x14\x33\xf7\xd3\x50\x67\x5d\xd2\x18\x03\x74\x6c\xad\xca\x57\x41\x30\xf0\x12\x00\x02\x4c\x63\x40\xab\x0c\xc2\xcf\x74\xf2\x23\x46\x69\xf3\x4e\x90\x09\xef\x2e\xb9\x48\x23\xd6\x2b\x31\x40\x7f\x4b\xa4\x6f\x1a\x1e\xec\x41\x64\x1e\x84\xd7\x77\x27\xb5\x9e\x74\x6b\x8a\x67\x1b\xef\x93\x6f\x05\xbe\x82\x07\x59\xfa",
+       "\xc2\x84\xc9\x30\x8a\x28\xb6\xd2\x9c\xca\xa7\x85\x3f\x8c\x41\xba\xdc\xdd\xbc\x1a\xa4\xe9\x94\x81\xa6\xee\x2f\x4d",
+       154 },
+      { GCRY_MD_SHA3_224,
+       "\x83\x59\x9d\x93\xf5\x56\x1e\x82\x1b\xd0\x1a\x47\x23\x86\xbc\x2f\xf4\xef\xbd\x4a\xed\x60\xd5\x82\x1e\x84\xaa\xe7\x4d\x80\x71\x02\x98\x10\xf5\xe2\x86\xf8\xf1\x76\x51\xcd\x27\xda\x07\xb1\xeb\x43\x82\xf7\x54\xcd\x1c\x95\x26\x87\x83\xad\x09\x22\x0f\x55\x02\x84\x03\x70\xd4\x94\xbe\xb1\x71\x24\x22\x0f\x6a\xfc\xe9\x1e\xc8\xa0\xf5\x52\x31\xf9\x65\x24\x33\xe5\xce\x34\x89\xb7\x27\x71\x6c\xf4\xae\xba\x7d\xcd\xa2\x0c\xd2\x9a\xa9\xa8\x59\x20\x12\x53\xf9\x48\xdd\x94\x39\x5a\xba\x9e\x38\x52\xbd\x1d\x60\xdd\xa7\xae\x5d\xc0\x45\xb2\x83\xda\x00\x6e\x1c\xba\xd8\x3c\xc1\x32\x92\xa3\x15\xdb\x55\x53\x30\x5c\x62\x8d\xd0\x91\x14\x65\x97",
+       "\x3d\x9a\x97\x9b\x34\xd4\x55\x69\xe1\xc9\x8d\x09\xdc\x62\xd0\x36\x16\xc0\x25\x1c\x41\xa8\xb9\x01\x38\x75\x0f\x1e",
+       155 },
+      { GCRY_MD_SHA3_224,
+       "\x2b\xe9\xbf\x52\x6c\x9d\x5a\x75\xd5\x65\xdd\x11\xef\x63\xb9\x79\xd0\x68\x65\x9c\x7f\x02\x6c\x08\xbe\xa4\xaf\x16\x1d\x85\xa4\x62\xd8\x0e\x45\x04\x0e\x91\xf4\x16\x5c\x07\x4c\x43\xac\x66\x13\x80\x31\x1a\x8c\xbe\xd5\x9c\xc8\xe4\xc4\x51\x8e\x80\xcd\x2c\x78\xab\x1c\xab\xf6\x6b\xff\x83\xea\xb3\xa8\x01\x48\x55\x03\x07\x31\x09\x50\xd0\x34\xa6\x28\x6c\x93\xa1\xec\xe8\x92\x9e\x63\x85\xc5\xe3\xbb\x6e\xa8\xa7\xc0\xfb\x6d\x63\x32\xe3\x20\xe7\x1c\xc4\xeb\x46\x2a\x2a\x62\xe2\xbf\xe0\x8f\x0c\xca\xd9\x3e\x61\xbe\xdb\x5d\xd0\xb7\x86\xa7\x28\xab\x66\x6f\x07\xe0\x57\x6d\x18\x9c\x92\xbf\x9f\xb2\x0d\xca\x49\xac\x2d\x39\x56\xd4\x73\x85\xe2",
+       "\x8d\xdc\x9f\x1e\x0f\x94\xc1\x24\x7a\x67\xd6\x11\x9a\x91\x69\x76\x2c\x6c\x7f\x1e\xc7\xf6\x11\xd6\x13\x53\xab\x30",
+       156 },
+      { GCRY_MD_SHA3_224,
+       "\xca\x76\xd3\xa1\x25\x95\xa8\x17\x68\x26\x17\x00\x68\x48\x67\x55\x47\xd3\xe8\xf5\x0c\x22\x10\xf9\xaf\x90\x6c\x0e\x7c\xe5\x0b\x44\x60\x18\x6f\xe7\x04\x57\xa9\xe8\x79\xe7\x9f\xd4\xd1\xa6\x88\xc7\x0a\x34\x73\x61\xc8\x47\xba\x0d\xd6\xaa\x52\x93\x6e\xaf\x8e\x58\xa1\xbe\x2f\x5c\x1c\x70\x4e\x20\x14\x6d\x36\x6a\xeb\x38\x53\xbe\xd9\xde\x9b\xef\xe9\x56\x9a\xc8\xaa\xea\x37\xa9\xfb\x71\x39\xa1\xa1\xa7\xd5\xc7\x48\x60\x5a\x8d\xef\xb2\x97\x86\x9e\xbe\xdd\x71\xd6\x15\xa5\xda\x23\x49\x6d\x11\xe1\x1a\xbb\xb1\x26\xb2\x06\xfa\x0a\x77\x97\xee\x7d\xe1\x17\x98\x60\x12\xd0\x36\x2d\xce\xf7\x75\xc2\xfe\x14\x5a\xda\x6b\xda\x1c\xcb\x32\x6b\xf6\x44",
+       "\x46\xed\xa2\x62\x2d\x49\xb9\x14\x8b\x40\xb6\x01\x4c\x75\xa4\x08\x6e\xb9\xdd\x47\x40\xf0\xdd\x59\x1a\xca\x53\xb2",
+       157 },
+      { GCRY_MD_SHA3_224,
+       "\xf7\x6b\x85\xdc\x67\x42\x10\x25\xd6\x4e\x93\x09\x6d\x1d\x71\x2b\x7b\xaf\x7f\xb0\x01\x71\x6f\x02\xd3\x3b\x21\x60\xc2\xc8\x82\xc3\x10\xef\x13\xa5\x76\xb1\xc2\xd3\x0e\xf8\xf7\x8e\xf8\xd2\xf4\x65\x00\x71\x09\xaa\xd9\x3f\x74\xcb\x9e\x7d\x7b\xef\x7c\x95\x90\xe8\xaf\x3b\x26\x7c\x89\xc1\x5d\xb2\x38\x13\x8c\x45\x83\x3c\x98\xcc\x4a\x47\x1a\x78\x02\x72\x3e\xf4\xc7\x44\xa8\x53\xcf\x80\xa0\xc2\x56\x8d\xd4\xed\x58\xa2\xc9\x64\x48\x06\xf4\x21\x04\xce\xe5\x36\x28\xe5\xbd\xf7\xb6\x3b\x0b\x33\x8e\x93\x1e\x31\xb8\x7c\x24\xb1\x46\xc6\xd0\x40\x60\x55\x67\xce\xef\x59\x60\xdf\x9e\x02\x2c\xb4\x69\xd4\xc7\x87\xf4\xcb\xa3\xc5\x44\xa1\xac\x91\xf9\x5f",
+       "\x57\xcf\xa1\x37\x96\x8c\x39\xea\xa1\x25\x33\x04\x4b\x82\x65\xbb\x90\x3e\xc1\x6c\x8d\x17\xb6\xcf\x1f\x10\x6c\x57",
+       158 },
+      { GCRY_MD_SHA3_224,
+       "\x25\xb8\xc9\xc0\x32\xea\x6b\xcd\x73\x3f\xfc\x87\x18\xfb\xb2\xa5\x03\xa4\xea\x8f\x71\xde\xa1\x17\x61\x89\xf6\x94\x30\x4f\x0f\xf6\x8e\x86\x2a\x81\x97\xb8\x39\x95\x75\x49\xef\x24\x3a\x52\x79\xfc\x26\x46\xbd\x4c\x00\x9b\x6d\x1e\xde\xbf\x24\x73\x81\x97\xab\xb4\xc9\x92\xf6\xb1\xdc\x9b\xa8\x91\xf5\x70\x87\x9a\xcc\xd5\xa6\xb1\x86\x91\xa9\x3c\x7d\x0a\x8d\x38\xf9\x5b\x63\x9c\x1d\xae\xb4\x8c\x4c\x2f\x15\xcc\xf5\xb9\xd5\x08\xf8\x33\x3c\x32\xde\x78\x78\x1b\x41\x85\x0f\x26\x1b\x85\x5c\x4b\xeb\xcc\x12\x5a\x38\x0c\x54\xd5\x01\xc5\xd3\xbd\x07\xe6\xb5\x21\x02\x11\x60\x88\xe5\x3d\x76\x58\x3b\x01\x61\xe2\xa5\x8d\x07\x78\xf0\x91\x20\x6a\xab\xd5\xa1",
+       "\x87\x30\xc2\x19\xe1\x9d\x9d\x37\xcb\x7a\x63\xa4\xdd\xd5\x5e\x84\xdc\xb0\x23\x6e\xf7\xc8\x82\x8b\x2a\x23\xc9\xb9",
+       159 },
+      { GCRY_MD_SHA3_224,
+       "\x21\xcf\xdc\x2a\x7c\xcb\x7f\x33\x1b\x3d\x2e\xef\xff\x37\xe4\x8a\xd9\xfa\x9c\x78\x8c\x3f\x3c\x20\x0e\x01\x73\xd9\x99\x63\xe1\xcb\xca\x93\x62\x3b\x26\x4e\x92\x03\x94\xae\x48\xbb\x4c\x3a\x5b\xb9\x6f\xfb\xc8\xf0\xe5\x3f\x30\xe2\x29\x56\xad\xab\xc2\x76\x5f\x57\xfb\x76\x1e\x14\x7e\xcb\xf8\x56\x75\x33\xdb\x6e\x50\xc8\xa1\xf8\x94\x31\x0a\x94\xed\xf8\x06\xdd\x8c\xa6\xa0\xe1\x41\xc0\xfa\x7c\x9f\xae\x6c\x6a\xe6\x5f\x18\xc9\x3a\x85\x29\xe6\xe5\xb5\x53\xbf\x55\xf2\x5b\xe2\xe8\x0a\x98\x82\xbd\x37\xf1\x45\xfe\xcb\xeb\x3d\x44\x7a\x3c\x4e\x46\xc2\x15\x24\xcc\x55\xcd\xd6\x2f\x52\x1a\xb9\x2a\x8b\xa7\x2b\x89\x79\x96\xc4\x9b\xb2\x73\x19\x8b\x7b\x1c\x9e",
+       "\x61\xc0\x1f\xb4\xa0\x10\xf3\x19\xd1\x93\xcb\x6d\x36\x06\x37\x51\x95\x0a\x1a\x8f\x93\x53\x9b\xea\x32\xf8\x4e\xa1",
+       160 },
+      { GCRY_MD_SHA3_224,
+       "\x4e\x45\x2b\xa4\x21\x27\xdc\xc9\x56\xef\x4f\x8f\x35\xdd\x68\xcb\x22\x5f\xb7\x3b\x5b\xc7\xe1\xec\x5a\x89\x8b\xba\x29\x31\x56\x3e\x74\xfa\xff\x3b\x67\x31\x4f\x24\x1e\xc4\x9f\x4a\x70\x61\xe3\xbd\x02\x13\xae\x82\x6b\xab\x38\x0f\x1f\x14\xfa\xab\x8b\x0e\xfd\xdd\x5f\xd1\xbb\x49\x37\x38\x53\xa0\x8f\x30\x55\x3d\x5a\x55\xcc\xbb\xb8\x15\x3d\xe4\x70\x4f\x29\xca\x2b\xde\xef\x04\x19\x46\x8e\x05\xdd\x51\x55\x7c\xcc\x80\xc0\xa9\x61\x90\xbb\xcc\x4d\x77\xec\xff\x21\xc6\x6b\xdf\x48\x64\x59\xd4\x27\xf9\x86\x41\x0f\x88\x3a\x80\xa5\xbc\xc3\x2c\x20\xf0\x47\x8b\xb9\xa9\x7a\x12\x6f\xc5\xf9\x54\x51\xe4\x0f\x29\x2a\x46\x14\x93\x0d\x05\x4c\x85\x1a\xcd\x01\x9c\xcf",
+       "\x14\x59\x04\x4d\xf9\xc2\x6f\x5e\x24\x0f\x6a\x6b\x93\x80\x73\x4c\xad\x84\xb6\x59\x2f\xc9\x69\x3d\xdd\x9f\x97\x4e",
+       161 },
+      { GCRY_MD_SHA3_224,
+       "\xfa\x85\x67\x1d\xf7\xda\xdf\x99\xa6\xff\xee\x97\xa3\xab\x99\x91\x67\x1f\x56\x29\x19\x50\x49\x88\x04\x97\x48\x78\x67\xa6\xc4\x46\xb6\x00\x87\xfa\xc9\xa0\xf2\xfc\xc8\xe3\xb2\x4e\x97\xe4\x23\x45\xb9\x3b\x5f\x7d\x36\x91\x82\x9d\x3f\x8c\xcd\x4b\xb3\x64\x11\xb8\x5f\xc2\x32\x8e\xb0\xc5\x1c\xb3\x15\x1f\x70\x86\x0a\xd3\x24\x6c\xe0\x62\x3a\x8d\xc8\xb3\xc4\x9f\x95\x8f\x86\x90\xf8\xe3\x86\x0e\x71\xeb\x2b\x14\x79\xa5\xce\xa0\xb3\xf8\xbe\xfd\x87\xac\xaf\x53\x62\x43\x5e\xae\xcc\xb5\x2f\x38\x61\x7b\xc6\xc5\xc2\xc6\xe2\x69\xea\xd1\xfb\xd6\x9e\x94\x1d\x4a\xd2\x01\x2d\xa2\xc5\xb2\x1b\xcf\xbf\x98\xe4\xa7\x7a\xb2\xaf\x1f\x3f\xda\x32\x33\xf0\x46\xd3\x8f\x1d\xc8",
+       "\xeb\x5c\xc0\x01\x73\x23\x98\x51\xf3\x96\x0e\xda\xc3\x36\x00\x51\x09\x18\x9d\xfc\x04\xb2\x9c\xa4\xcd\xde\x5b\xc1",
+       162 },
+      { GCRY_MD_SHA3_224,
+       "\xe9\x08\x47\xae\x67\x97\xfb\xc0\xb6\xb3\x6d\x6e\x58\x8c\x0a\x74\x3d\x72\x57\x88\xca\x50\xb6\xd7\x92\x35\x2e\xa8\x29\x4f\x5b\xa6\x54\xa1\x53\x66\xb8\xe1\xb2\x88\xd8\x4f\x51\x78\x24\x08\x27\x97\x5a\x76\x3b\xc4\x5c\x7b\x04\x30\xe8\xa5\x59\xdf\x44\x88\x50\x5e\x00\x9c\x63\xda\x99\x4f\x14\x03\xf4\x07\x95\x82\x03\xce\xbb\x6e\x37\xd8\x9c\x94\xa5\xea\xcf\x60\x39\xa3\x27\xf6\xc4\xdb\xbc\x7a\x2a\x30\x7d\x97\x6a\xa3\x9e\x41\xaf\x65\x37\x24\x3f\xc2\x18\xdf\xa6\xab\x4d\xd8\x17\xb6\xa3\x97\xdf\x5c\xa6\x91\x07\xa9\x19\x87\x99\xed\x24\x86\x41\xb6\x3b\x42\xcb\x4c\x29\xbf\xdd\x79\x75\xac\x96\xed\xfc\x27\x4a\xc5\x62\xd0\x47\x4c\x60\x34\x7a\x07\x8c\xe4\xc2\x5e\x88",
+       "\xa6\x40\xd4\x84\x13\x90\xf4\x7d\xc4\x7d\x4b\xfc\xf1\x30\xfc\xf5\x1c\x5f\x2d\x49\x1f\x91\xc1\x33\x74\xce\x59\x65",
+       163 },
+      { GCRY_MD_SHA3_224,
+       "\xf6\xd5\xc2\xb6\xc9\x39\x54\xfc\x62\x76\x02\xc0\x0c\x4c\xa9\xa7\xd3\xed\x12\xb2\x71\x73\xf0\xb2\xc9\xb0\xe4\xa5\x93\x93\x98\xa6\x65\xe6\x7e\x69\xd0\xb1\x2f\xb7\xe4\xce\xb2\x53\xe8\x08\x3d\x1c\xeb\x72\x4a\xc0\x7f\x00\x9f\x09\x4e\x42\xf2\xd6\xf2\x12\x94\x89\xe8\x46\xea\xff\x07\x00\xa8\xd4\x45\x3e\xf4\x53\xa3\xed\xdc\x18\xf4\x08\xc7\x7a\x83\x27\x56\x17\xfa\xbc\x4e\xa3\xa2\x83\x3a\xa7\x34\x06\xc0\xe9\x66\x27\x60\x79\xd3\x8e\x8e\x38\x53\x9a\x70\xe1\x94\xcc\x55\x13\xaa\xa4\x57\xc6\x99\x38\x3f\xd1\x90\x0b\x1e\x72\xbd\xfb\x83\x5d\x1f\xd3\x21\xb3\x7b\xa8\x05\x49\xb0\x78\xa4\x9e\xa0\x81\x52\x86\x9a\x91\x8c\xa5\x7f\x5b\x54\xed\x71\xe4\xfd\x3a\xc5\xc0\x67\x29",
+       "\x85\xbb\x3e\xd9\x8c\x48\x08\xd8\xf6\x7c\x72\x2c\x91\x19\xc5\x4e\x65\x43\xb2\x9e\x57\xbd\x4f\xb5\xcb\xc8\x78\xc7",
+       164 },
+      { GCRY_MD_SHA3_224,
+       "\xcf\x85\x62\xb1\xbe\xd8\x98\x92\xd6\x7d\xda\xaf\x3d\xee\xb2\x82\x46\x45\x6e\x97\x23\x26\xdb\xcd\xb5\xcf\x3f\xb2\x89\xac\xa0\x1e\x68\xda\x5d\x59\x89\x6e\x3a\x61\x65\x35\x8b\x07\x1b\x30\x4d\x6a\xb3\xd0\x18\x94\x4b\xe5\x04\x9d\x5e\x0e\x2b\xb8\x19\xac\xf6\x7a\x60\x06\x11\x10\x89\xe6\x76\x71\x32\xd7\x2d\xd8\x5b\xed\xdc\xbb\x2d\x64\x49\x6d\xb0\xcc\x92\x95\x5a\xb4\xc6\x23\x4f\x1e\xea\x24\xf2\xd5\x14\x83\xf2\xe2\x09\xe4\x58\x9b\xf9\x51\x9f\xac\x51\xb4\xd0\x61\xe8\x01\x12\x5e\x60\x5f\x80\x93\xbb\x69\x97\xbc\x16\x3d\x55\x15\x96\xfe\x4a\xb7\xcf\xae\x8f\xb9\xa9\x0f\x69\x80\x48\x0c\xe0\xc2\x29\xfd\x16\x75\x40\x9b\xd7\x88\x35\x4d\xaf\x31\x62\x40\xcf\xe0\xaf\x93\xeb",
+       "\x50\xb7\xd0\xac\xb9\x32\x11\xe0\xfc\x93\x5f\x97\x0b\xc4\x3a\x00\xbe\x82\x9d\x6b\x3c\x13\x7d\x4a\x7e\x3b\x2b\xc1",
+       165 },
+      { GCRY_MD_SHA3_224,
+       "\x2a\xce\x31\xab\xb0\xa2\xe3\x26\x79\x44\xd2\xf7\x5e\x15\x59\x98\x5d\xb7\x35\x4c\x6e\x60\x5f\x18\xdc\x84\x70\x42\x3f\xca\x30\xb7\x33\x1d\x9b\x33\xc4\xa4\x32\x67\x83\xd1\xca\xae\x1b\x4f\x07\x06\x0e\xff\x97\x8e\x47\x46\xbf\x0c\x7e\x30\xcd\x61\x04\x0b\xd5\xec\x27\x46\xb2\x98\x63\xeb\x7f\x10\x3e\xbd\xa6\x14\xc4\x29\x1a\x80\x5b\x6a\x4c\x82\x14\x23\x05\x64\xa0\x55\x7b\xc7\x10\x2e\x0b\xd3\xed\x23\x71\x92\x52\xf7\x43\x5d\x64\xd2\x10\xee\x2a\xaf\xc5\x85\xbe\x90\x3f\xa4\x1e\x19\x68\xc5\x0f\xd5\xd5\x36\x79\x26\xdf\x7a\x05\xe3\xa4\x2c\xf0\x7e\x65\x6f\xf9\x2d\xe7\x3b\x03\x6c\xf8\xb1\x98\x98\xc0\xcb\x34\x55\x7c\x0c\x12\xc2\xd8\xb8\x4e\x91\x18\x1a\xf4\x67\xbc\x75\xa9\xd1",
+       "\x7c\xdc\x17\x82\xb3\x9f\xc0\xee\xb1\xf8\x74\xd9\x7c\x88\x05\x1c\xf1\x05\x08\xe0\x87\x5f\xa1\x73\xac\x41\xcc\x8e",
+       166 },
+      { GCRY_MD_SHA3_224,
+       "\x0d\x8d\x09\xae\xd1\x9f\x10\x13\x96\x9c\xe5\xe7\xeb\x92\xf8\x3a\x20\x9a\xe7\x6b\xe3\x1c\x75\x48\x44\xea\x91\x16\xce\xb3\x9a\x22\xeb\xb6\x00\x30\x17\xbb\xcf\x26\x55\x5f\xa6\x62\x41\x85\x18\x7d\xb8\xf0\xcb\x35\x64\xb8\xb1\xc0\x6b\xf6\x85\xd4\x7f\x32\x86\xed\xa2\x0b\x83\x35\x8f\x59\x9d\x20\x44\xbb\xf0\x58\x3f\xab\x8d\x78\xf8\x54\xfe\x0a\x59\x61\x83\x23\x0c\x5e\xf8\xe5\x44\x26\x75\x0e\xaf\x2c\xc4\xe2\x9d\x3b\xdd\x03\x7e\x73\x4d\x86\x3c\x2b\xd9\x78\x9b\x4c\x24\x30\x96\x13\x8f\x76\x72\xc2\x32\x31\x4e\xff\xdf\xc6\x51\x34\x27\xe2\xda\x76\x91\x6b\x52\x48\x93\x3b\xe3\x12\xeb\x5d\xde\x4c\xf7\x08\x04\xfb\x25\x8a\xc5\xfb\x82\xd5\x8d\x08\x17\x7a\xc6\xf4\x75\x60\x17\xff\xf5",
+       "\xee\x5d\x50\x8a\x4e\x75\x90\x01\x93\xe9\x9a\x04\xb8\xd8\x38\xa1\x8d\xed\xfc\xc4\x31\xe7\xaf\x31\x82\xa4\x7d\xd6",
+       167 },
+      { GCRY_MD_SHA3_224,
+       "\xc3\x23\x6b\x73\xde\xb7\x66\x2b\xf3\xf3\xda\xa5\x8f\x13\x7b\x35\x8b\xa6\x10\x56\x0e\xf7\x45\x57\x85\xa9\xbe\xfd\xb0\x35\xa0\x66\xe9\x07\x04\xf9\x29\xbd\x96\x89\xce\xf0\xce\x3b\xda\x5a\xcf\x44\x80\xbc\xeb\x8d\x09\xd1\x0b\x09\x8a\xd8\x50\x0d\x9b\x60\x71\xdf\xc3\xa1\x4a\xf6\xc7\x75\x11\xd8\x1e\x3a\xa8\x84\x49\x86\xc3\xbe\xa6\xf4\x69\xf9\xe0\x21\x94\xc9\x28\x68\xcd\x5f\x51\x64\x62\x56\x79\x8f\xf0\x42\x49\x54\xc1\x43\x4b\xdf\xed\x9f\xac\xb3\x90\xb0\x7d\x34\x2e\x99\x29\x36\xe0\xf8\x8b\xfd\x0e\x88\x4a\x0d\xdb\x67\x9d\x05\x47\xcc\xde\xc6\x38\x42\x85\xa4\x54\x29\xd1\x15\xac\x7d\x23\x5a\x71\x72\x42\x02\x1d\x1d\xc3\x56\x41\xf5\xf0\xa4\x8e\x84\x45\xdb\xa5\x8e\x6c\xb2\xc8\xea",
+       "\x59\x42\xba\x8b\x58\xa3\x55\xf2\xae\xf0\x7e\x29\xf8\xf9\x97\x13\x01\xe8\x77\xfa\x32\xd7\x02\x5d\xf5\x52\xb1\xeb",
+       168 },
+      { GCRY_MD_SHA3_224,
+       "\xb3\x9f\xeb\x82\x83\xea\xdc\x63\xe8\x18\x4b\x51\xdf\x5a\xe3\xfd\x41\xaa\xc8\xa9\x63\xbb\x0b\xe1\xcd\x08\xaa\x58\x67\xd8\xd9\x10\xc6\x69\x22\x1e\x73\x24\x33\x60\x64\x6f\x65\x53\xd1\xca\x05\xa8\x4e\x8d\xc0\xde\x05\xb6\x41\x9e\xc3\x49\xca\x99\x44\x80\x19\x3d\x01\xc9\x25\x25\xf3\xfb\x3d\xce\xfb\x08\xaf\xc6\xd2\x69\x47\xbd\xbb\xfd\x85\x19\x3f\x53\xb5\x06\x09\xc6\x14\x09\x05\xc5\x3a\x66\x86\xb5\x8e\x53\xa3\x19\xa5\x7b\x96\x23\x31\xed\xe9\x81\x49\xaf\x3d\xe3\x11\x8a\x81\x9d\xa4\xd7\x67\x06\xa0\x42\x4b\x4e\x1d\x29\x10\xb0\xed\x26\xaf\x61\xd1\x50\xeb\xcb\x46\x59\x5d\x42\x66\xa0\xbd\x7f\x65\x1b\xa4\x7d\x0c\x7f\x17\x9c\xa2\x85\x45\x00\x7d\x92\xe8\x41\x9d\x48\xfd\xfb\xd7\x44\xce",
+       "\x29\x24\x0a\x9e\x97\x38\x88\xb9\x8a\x3a\x83\x69\x33\x85\x5d\x41\xd8\xab\xb6\xc3\x80\x6a\x62\x6c\x3d\xf1\x8f\x6c",
+       169 },
+      { GCRY_MD_SHA3_224,
+       "\xa9\x83\xd5\x4f\x50\x38\x03\xe8\xc7\x99\x9f\x4e\xdb\xbe\x82\xe9\x08\x4f\x42\x21\x43\xa9\x32\xdd\xdd\xc4\x7a\x17\xb0\xb7\x56\x4a\x7f\x37\xa9\x9d\x07\x86\xe9\x94\x76\x42\x8d\x29\xe2\x9d\x3c\x19\x7a\x72\xbf\xab\x13\x42\xc1\x2a\x0f\xc4\x78\x7f\xd7\x01\x7d\x7a\x61\x74\x04\x9e\xa4\x3b\x57\x79\x16\x9e\xf7\x47\x2b\xdb\xbd\x94\x1d\xcb\x82\xfc\x73\xaa\xc4\x5a\x8a\x94\xc9\xf2\xbd\x34\x77\xf6\x1f\xd3\xb7\x96\xf0\x2a\x1b\x82\x64\xa2\x14\xc6\xfe\xa7\x4b\x70\x51\xb2\x26\xc7\x22\x09\x9e\xc7\x88\x3a\x46\x2b\x83\xb6\xaf\xdd\x40\x09\x24\x8b\x8a\x23\x7f\x60\x5f\xe5\xa0\x8f\xe7\xd8\xb4\x53\x21\x42\x1e\xbb\xa6\x7b\xd7\x0a\x0b\x00\xdd\xbf\x94\xba\xab\x7f\x35\x9d\x5d\x1e\xea\x10\x5f\x28\xdc\xfb",
+       "\x9a\xf1\x78\xb1\xdd\x3c\xef\xc9\x62\x27\xa2\x89\x17\x5b\xb6\x1d\x9f\x6b\x0b\x35\x2d\x78\x04\xf5\xe0\x7e\xa4\x5d",
+       170 },
+      { GCRY_MD_SHA3_224,
+       "\xe4\xd1\xc1\x89\x7a\x0a\x86\x6c\xe5\x64\x63\x5b\x74\x22\x2f\x96\x96\xbf\x2c\x7f\x64\x0d\xd7\x8d\x7e\x2a\xca\x66\xe1\xb6\x1c\x64\x2b\xb0\x3e\xa7\x53\x6a\xae\x59\x78\x11\xe9\xbf\x4a\x7b\x45\x3e\xde\x31\xf9\x7b\x46\xa5\xf0\xef\x51\xa0\x71\xa2\xb3\x91\x8d\xf1\x6b\x15\x25\x19\xae\x37\x76\xf9\xf1\xed\xab\x4c\x2a\x37\x7c\x32\x92\xe9\x64\x08\x35\x9d\x36\x13\x84\x4d\x5e\xb3\x93\x00\x02\x83\xd5\xad\x34\x01\xa3\x18\xb1\x2f\xd1\x47\x4b\x86\x12\xf2\xbb\x50\xfb\x6a\x8b\x9e\x02\x3a\x54\xd7\xdd\xe2\x8c\x43\xd6\xd8\x85\x4c\x8d\x9d\x11\x55\x93\x5c\x19\x98\x11\xdb\xfc\x87\xe9\xe0\x07\x2e\x90\xeb\x88\x68\x1c\xc7\x52\x97\x14\xf8\xfb\x8a\x2c\x9d\x88\x56\x7a\xdf\xb9\x74\xee\x20\x5a\x9b\xf7\xb8\x48",
+       "\xf5\x43\xb4\xd4\x23\xea\xac\x86\x33\x8b\xb6\xd8\xc6\x18\x1a\xd6\xdc\x0a\x25\x73\x39\x53\xce\xd7\xeb\x83\x77\xf3",
+       171 },
+      { GCRY_MD_SHA3_224,
+       "\xb1\x0c\x59\x72\x3e\x3d\xca\xdd\x6d\x75\xdf\x87\xd0\xa1\x58\x0e\x73\x13\x3a\x9b\x7d\x00\xcb\x95\xec\x19\xf5\x54\x70\x27\x32\x3b\xe7\x51\x58\xb1\x1f\x80\xb6\xe1\x42\xc6\xa7\x85\x31\x88\x6d\x90\x47\xb0\x8e\x55\x1e\x75\xe6\x26\x1e\x79\x78\x53\x66\xd7\x02\x4b\xd7\xcd\x9c\xf3\x22\xd9\xbe\x7d\x57\xfb\x66\x10\x69\xf2\x48\x1c\x7b\xb7\x59\xcd\x71\xb4\xb3\x6c\xa2\xbc\x2d\xf6\xd3\xa3\x28\xfa\xeb\xdb\x99\x5a\x97\x94\xa8\xd7\x21\x55\xed\x55\x1a\x1f\x87\xc8\x0b\xf6\x05\x9b\x43\xfc\x76\x49\x00\xb1\x8a\x1c\x24\x41\xf7\x48\x77\x43\xcf\x84\xe5\x65\xf6\x1f\x8d\xd2\xec\xe6\xb6\xcc\xc9\x44\x40\x49\x19\x7a\xaa\xf5\x3e\x92\x6f\xbe\xe3\xbf\xca\x8b\xe5\x88\xec\x77\xf2\x9d\x21\x1b\xe8\x9d\xe1\x8b\x15\xf6",
+       "\x77\xb4\x07\x9e\xee\x9d\x9e\x3f\xda\x05\x1e\xe0\xca\x43\x0b\x4d\xf0\x11\xd0\x56\x61\x2c\x1a\xf4\x46\xa1\x87\xc2",
+       172 },
+      { GCRY_MD_SHA3_224,
+       "\xdb\x11\xf6\x09\xba\xba\x7b\x0c\xa6\x34\x92\x6b\x1d\xd5\x39\xc8\xcb\xad\xa2\x49\x67\xd7\xad\xd4\xd9\x87\x6f\x77\xc2\xd8\x0c\x0f\x4d\xce\xfb\xd7\x12\x15\x48\x37\x35\x82\x70\x5c\xca\x24\x95\xbd\x2a\x43\x71\x6f\xe6\x4e\xd2\x6d\x05\x9c\xfb\x56\x6b\x33\x64\xbd\x49\xee\x07\x17\xbd\xd9\x81\x0d\xd1\x4d\x8f\xad\x80\xdb\xbd\xc4\xca\xfb\x37\xcc\x60\xfb\x0f\xe2\xa8\x0f\xb4\x54\x1b\x8c\xa9\xd5\x9d\xce\x45\x77\x38\xa9\xd3\xd8\xf6\x41\xaf\x8c\x3f\xd6\xda\x16\x2d\xc1\x6f\xc0\x1a\xac\x52\x7a\x4a\x02\x55\xb4\xd2\x31\xc0\xbe\x50\xf4\x4f\x0d\xb0\xb7\x13\xaf\x03\xd9\x68\xfe\x7f\x0f\x61\xed\x08\x24\xc5\x5c\x4b\x52\x65\x54\x8f\xeb\xd6\xaa\xd5\xc5\xee\xdf\x63\xef\xe7\x93\x48\x9c\x39\xb8\xfd\x29\xd1\x04\xce",
+       "\x98\x7d\x30\x12\x0c\x9a\xa4\x96\x46\x50\xa6\xa7\x30\xe9\x9c\x86\xf7\xfb\xdd\xb4\xea\x8d\x6b\x48\x15\xee\x4e\xbf",
+       173 },
+      { GCRY_MD_SHA3_224,
+       "\xbe\xbd\x4f\x1a\x84\xfc\x8b\x15\xe4\x45\x2a\x54\xbd\x02\xd6\x9e\x30\x4b\x7f\x32\x61\x6a\xad\xd9\x05\x37\x93\x71\x06\xae\x4e\x28\xde\x9d\x8a\xab\x02\xd1\x9b\xc3\xe2\xfd\xe1\xd6\x51\x55\x9e\x29\x64\x53\xe4\xdb\xa9\x43\x70\xa1\x4d\xbb\xb2\xd1\xd4\xe2\x02\x23\x02\xee\x90\xe2\x08\x32\x1e\xfc\xd8\x52\x8a\xd8\x9e\x46\xdc\x83\x9e\xa9\xdf\x61\x8e\xa8\x39\x4a\x6b\xff\x30\x8e\x77\x26\xba\xe0\xc1\x9b\xcd\x4b\xe5\x2d\xa6\x25\x8e\x2e\xf4\xe9\x6a\xa2\x12\x44\x42\x9f\x49\xef\x5c\xb4\x86\xd7\xff\x35\xca\xc1\xba\xcb\x7e\x95\x71\x19\x44\xbc\xcb\x2a\xb3\x47\x00\xd4\x2d\x1e\xb3\x8b\x5d\x53\x6b\x94\x73\x48\xa4\x58\xed\xe3\xdc\x6b\xd6\xec\x54\x7b\x1b\x0c\xae\x5b\x25\x7b\xe3\x6a\x71\x24\xe1\x06\x0c\x17\x0f\xfa",
+       "\x46\x19\x33\x59\x39\x7b\xc3\xea\xcd\x69\xbf\xf4\x10\x20\x35\x83\x38\x2d\xe9\x3e\xcc\x4d\x80\xdc\xfb\x4f\xc5\x1d",
+       174 },
+      { GCRY_MD_SHA3_224,
+       "\x5a\xca\x56\xa0\x3a\x13\x78\x4b\xdc\x32\x89\xd9\x36\x4f\x79\xe2\xa8\x5c\x12\x27\x6b\x49\xb9\x2d\xb0\xad\xaa\x4f\x20\x6d\x50\x28\xf2\x13\xf6\x78\xc3\x51\x0e\x11\x1f\x9d\xc4\xc1\xc1\xf8\xb6\xac\xb1\x7a\x64\x13\xaa\x22\x76\x07\xc5\x15\xc6\x2a\x73\x38\x17\xba\x5e\x76\x2c\xc6\x74\x8e\x7e\x0d\x68\x72\xc9\x84\xd7\x23\xc9\xbb\x3b\x11\x7e\xb8\x96\x31\x85\x30\x0a\x80\xbf\xa6\x5c\xde\x49\x5d\x70\xa4\x6c\x44\x85\x86\x05\xfc\xcb\xed\x08\x6c\x2b\x45\xce\xf9\x63\xd3\x32\x94\xdb\xe9\x70\x6b\x13\xaf\x22\xf1\xb7\xc4\xcd\x5a\x00\x1c\xfe\xc2\x51\xfb\xa1\x8e\x72\x2c\x6e\x1c\x4b\x11\x66\x91\x8b\x4f\x6f\x48\xa9\x8b\x64\xb3\xc0\x7f\xc8\x6a\x6b\x17\xa6\xd0\x48\x0a\xb7\x9d\x4e\x64\x15\xb5\x20\xf1\xc4\x84\xd6\x75\xb1",
+       "\x0b\xc2\x91\x07\xc7\xe2\x5d\x44\xf8\xce\x83\xa4\x15\xb1\xde\x5d\xf3\x8a\x67\x19\x76\x96\x06\x76\x2b\x71\x92\xc2",
+       175 },
+      { GCRY_MD_SHA3_224,
+       "\xa5\xaa\xd0\xe4\x64\x6a\x32\xc8\x5c\xfc\xac\x73\xf0\x2f\xc5\x30\x0f\x19\x82\xfa\xbb\x2f\x21\x79\xe2\x83\x03\xe4\x47\x85\x40\x94\xcd\xfc\x85\x43\x10\xe5\xc0\xf6\x09\x93\xce\xff\x54\xd8\x4d\x6b\x46\x32\x3d\x93\x0a\xdb\x07\xc1\x75\x99\xb3\x5b\x50\x5f\x09\xe7\x84\xbc\xa5\x98\x5e\x01\x72\x25\x77\x97\xfb\x53\x64\x9e\x2e\x97\x23\xef\xd1\x68\x65\xc3\x1b\x5c\x3d\x51\x13\xb5\x8b\xb0\xbf\xc8\x92\x0f\xab\xdd\xa0\x86\xd7\x53\x7e\x66\xd7\x09\xd0\x50\xbd\x14\xd0\xc9\x60\x87\x3f\x15\x6f\xad\x5b\x3d\x38\x40\xcd\xfc\xdc\x9b\xe6\xaf\x51\x9d\xb2\x62\xa2\x7f\x40\x89\x6a\xb2\x5c\xc3\x9f\x96\x98\x4d\x65\x06\x11\xc0\xd5\xa3\x08\x0d\x5b\x3a\x1b\xf1\x86\xab\xd4\x29\x56\x58\x8b\x3b\x58\xcd\x94\x89\x70\xd2\x98\x77\x60\x60",
+       "\xb4\x85\x64\x4c\x32\x28\x3b\x28\x01\x79\xf7\xc9\x71\x43\x50\xf0\xb3\xac\xfd\x7c\x45\xa2\x47\xbf\x3b\x6c\xdb\x07",
+       176 },
+      { GCRY_MD_SHA3_224,
+       "\x06\xcb\xbe\x67\xe9\x4a\x97\x82\x03\xea\xd6\xc0\x57\xa1\xa5\xb0\x98\x47\x8b\x4b\x4c\xbe\xf5\xa9\x7e\x93\xc8\xe4\x2f\x55\x72\x71\x35\x75\xfc\x2a\x88\x45\x31\xd7\x62\x2f\x8f\x87\x93\x87\xa8\x59\xa8\x0f\x10\xef\x02\x70\x8c\xd8\xf7\x41\x3a\xb3\x85\xaf\xc3\x57\x67\x8b\x95\x78\xc0\xeb\xf6\x41\xef\x07\x6a\x1a\x30\xf1\xf7\x53\x79\xe9\xdc\xb2\xa8\x85\xbd\xd2\x95\x90\x5e\xe8\x0c\x01\x68\xa6\x2a\x95\x97\xd1\x0c\xf1\x2d\xd2\xd8\xce\xe4\x66\x45\xc7\xe5\xa1\x41\xf6\xe0\xe2\x3a\xa4\x82\xab\xe5\x66\x1c\x16\xe6\x9e\xf1\xe2\x83\x71\xe2\xe2\x36\xc3\x59\xba\x4e\x92\xc2\x56\x26\xa7\xb7\xff\x13\xf6\xea\x4a\xe9\x06\xe1\xcf\xe1\x63\xe9\x17\x19\xb1\xf7\x50\xa9\x6c\xbd\xe5\xfb\xc9\x53\xd9\xe5\x76\xcd\x21\x6a\xfc\x90\x32\x3a",
+       "\xf3\x84\x54\x24\x99\xef\xd2\x33\x81\xde\xbc\xd9\x12\x4c\x53\x9c\x40\xbf\xa7\x0e\x51\x72\x80\xf5\x6a\x09\x20\xe1",
+       177 },
+      { GCRY_MD_SHA3_224,
+       "\xf1\xc5\x28\xcf\x77\x39\x87\x47\x07\xd4\xd8\xad\x5b\x98\xf7\xc7\x71\x69\xde\x0b\x57\x18\x8d\xf2\x33\xb2\xdc\x8a\x5b\x31\xed\xa5\xdb\x42\x91\xdd\x9f\x68\xe6\xba\xd3\x7b\x8d\x7f\x6c\x9c\x00\x44\xb3\xbf\x74\xbb\xc3\xd7\xd1\x79\x8e\x13\x87\x09\xb0\xd7\x5e\x7c\x59\x3d\x3c\xcc\xdc\x1b\x20\xc7\x17\x4b\x4e\x69\x2a\xdd\x82\x0a\xce\x26\x2d\x45\xcc\xfa\xe2\x07\x7e\x87\x87\x96\x34\x71\x68\x06\x0a\x16\x2e\xcc\xa8\xc3\x8c\x1a\x88\x35\x0b\xd6\x3b\xb5\x39\x13\x4f\x70\x0f\xd4\xad\xdd\x59\x59\xe2\x55\x33\x7d\xaa\x06\xbc\x86\x35\x8f\xab\xcb\xef\xdf\xb5\xbc\x88\x97\x83\xd8\x43\xc0\x8a\xad\xc6\xc4\xf6\xc3\x6f\x65\xf1\x56\xe8\x51\xc9\xa0\xf9\x17\xe4\xa3\x67\xb5\xad\x93\xd8\x74\x81\x2a\x1d\xe6\xa7\xb9\x3c\xd5\x3a\xd9\x72\x32",
+       "\xd1\x2e\x38\x84\xbc\x8c\xf9\x17\x5d\x17\x78\xe8\xa3\xaa\xa1\x19\xe4\xa8\x97\x73\x8f\x8d\x81\xb1\x27\x8b\xc4\x48",
+       178 },
+      { GCRY_MD_SHA3_224,
+       "\x9d\x9f\x3a\x7e\xcd\x51\xb4\x1f\x65\x72\xfd\x0d\x08\x81\xe3\x03\x90\xdf\xb7\x80\x99\x1d\xae\x7d\xb3\xb4\x76\x19\x13\x47\x18\xe6\xf9\x87\x81\x0e\x54\x26\x19\xdf\xaa\x7b\x50\x5c\x76\xb7\x35\x0c\x64\x32\xd8\xbf\x1c\xfe\xbd\xf1\x06\x9b\x90\xa3\x5f\x0d\x04\xcb\xdf\x13\x0b\x0d\xfc\x78\x75\xf4\xa4\xe6\x2c\xdb\x8e\x52\x5a\xad\xd7\xce\x84\x25\x20\xa4\x82\xac\x18\xf0\x94\x42\xd7\x83\x05\xfe\x85\xa7\x4e\x39\xe7\x60\xa4\x83\x74\x82\xed\x2f\x43\x7d\xd1\x3b\x2e\xc1\x04\x2a\xfc\xf9\xde\xcd\xc3\xe8\x77\xe5\x0f\xf4\x10\x6a\xd1\x0a\x52\x52\x30\xd1\x19\x20\x32\x4a\x81\x09\x4d\xa3\x1d\xea\xb6\x47\x6a\xa4\x2f\x20\xc8\x48\x43\xcf\xc1\xc5\x85\x45\xee\x80\x35\x2b\xdd\x37\x40\xdd\x6a\x16\x79\x2a\xe2\xd8\x6f\x11\x64\x1b\xb7\x17\xc2",
+       "\xd8\xa3\x48\x26\x4d\x48\x04\x5d\x44\x82\xf3\xfe\x00\x2c\x1a\x1f\x36\xd4\xdf\x0d\x5e\x47\xfa\xc5\x12\x5c\x79\x47",
+       179 },
+      { GCRY_MD_SHA3_224,
+       "\x51\x79\x88\x87\x24\x81\x9f\xba\xd3\xaf\xa9\x27\xd3\x57\x77\x96\x66\x0e\x6a\x81\xc5\x2d\x98\xe9\x30\x32\x61\xd5\xa4\xa8\x32\x32\xf6\xf7\x58\x93\x4d\x50\xaa\x83\xff\x9e\x20\xa5\x92\x6d\xfe\xba\xac\x49\x52\x9d\x00\x6e\xb9\x23\xc5\xae\x50\x48\xed\x54\x4e\xc4\x71\xed\x71\x91\xed\xf4\x63\x63\x38\x38\x24\xf9\x15\x76\x9b\x3e\x68\x80\x94\xc6\x82\xb0\x21\x51\xe5\xee\x01\xe5\x10\xb4\x31\xc8\x86\x5a\xff\x8b\x6b\x6f\x2f\x59\xcb\x6d\x12\x9d\xa7\x9e\x97\xc6\xd2\xb8\xfa\x6c\x6d\xa3\xf6\x03\x19\x9d\x2d\x1b\xca\xb5\x47\x68\x2a\x81\xcd\x6c\xf6\x5f\x65\x51\x12\x13\x91\xd7\x8b\xcc\x23\xb5\xbd\x0e\x92\x2e\xc6\xd8\xbf\x97\xc9\x52\xe8\x4d\xd2\x8a\xef\x90\x9a\xba\x31\xed\xb9\x03\xb2\x8f\xbf\xc3\x3b\x77\x03\xcd\x99\x62\x15\xa1\x12\x38",
+       "\x68\x65\x46\x4c\x6a\x23\x0b\x4b\xf6\x4b\xa3\x3b\xf9\x74\x59\xd1\xd2\x2d\xaf\xb1\x9e\x08\xf4\xb7\xda\xce\x02\xff",
+       180 },
+      { GCRY_MD_SHA3_224,
+       "\x57\x6e\xf3\x52\x0d\x30\xb7\xa4\x89\x9b\x8c\x0d\x5e\x35\x9e\x45\xc5\x18\x9a\xdd\x10\x0e\x43\xbe\x42\x9a\x02\xfb\x3d\xe5\xff\x4f\x8f\xd0\xe7\x9d\x96\x63\xac\xca\x72\xcd\x29\xc9\x45\x82\xb1\x92\x92\xa5\x57\xc5\xb1\x31\x52\x97\xd1\x68\xfb\xb5\x4e\x9e\x2e\xcd\x13\x80\x9c\x2b\x5f\xce\x99\x8e\xdc\x65\x70\x54\x5e\x14\x99\xdb\xe7\xfb\x74\xd4\x7c\xd7\xf3\x58\x23\xb2\x12\xb0\x5b\xf3\xf5\xa7\x9c\xaa\x34\x22\x4f\xdd\x67\x0d\x33\x5f\xcb\x10\x6f\x5d\x92\xc3\x94\x6f\x44\xd3\xaf\xcb\xae\x2e\x41\xac\x55\x4d\x8e\x67\x59\xf3\x32\xb7\x6b\xe8\x9a\x03\x24\xaa\x12\xc5\x48\x2d\x1e\xa3\xee\x89\xde\xd4\x93\x6f\x3e\x3c\x08\x04\x36\xf5\x39\xfa\x13\x7e\x74\xc6\xd3\x38\x9b\xdf\x5a\x45\x07\x4c\x47\xbc\x7b\x20\xb0\x94\x84\x07\xa6\x6d\x85\x5e\x2f",
+       "\x19\xd3\x3c\xd3\x54\xa1\x3a\xb2\xa4\x40\x44\x15\x4b\xd8\x65\xf1\x17\xef\x8a\x88\x7f\xbd\x05\x70\xa8\xa4\xca\x80",
+       181 },
+      { GCRY_MD_SHA3_224,
+       "\x0d\xf2\x15\x2f\xa4\xf4\x35\x7c\x87\x41\x52\x9d\xd7\x7e\x78\x39\x25\xd3\xd7\x6e\x95\xba\xfa\x2b\x54\x2a\x2c\x33\xf3\xd1\xd1\x17\xd1\x59\xcf\x47\x3f\x82\x31\x03\x56\xfe\xe4\xc9\x0a\x9e\x50\x5e\x70\xf8\xf2\x48\x59\x65\x63\x68\xba\x09\x38\x1f\xa2\x45\xeb\x6c\x3d\x76\x3f\x30\x93\xf0\xc8\x9b\x97\x2e\x66\xb5\x3d\x59\x40\x6d\x9f\x01\xae\xa0\x7f\x8b\x3b\x61\x5c\xac\x4e\xe4\xd0\x5f\x54\x2e\x7d\x0d\xab\x45\xd6\x7c\xcc\xcd\x3a\x60\x6c\xcb\xeb\x31\xea\x1f\xa7\x00\x5b\xa0\x71\x76\xe6\x0d\xab\x7d\x78\xf6\x81\x0e\xf0\x86\xf4\x2f\x08\xe5\x95\xf0\xec\x21\x73\x72\xb9\x89\x70\xcc\x63\x21\x57\x6d\x92\xce\x38\xf7\xc3\x97\xa4\x03\xba\xda\x15\x48\xd2\x05\xc3\x43\xac\x09\xde\xca\x86\x32\x53\x73\xc3\xb7\x6d\x9f\x32\x02\x8f\xea\x8e\xb3\x25\x15",
+       "\xe4\x38\xae\x41\x53\x46\x3b\x33\x3a\xe4\xfe\x57\xbf\x13\x15\x05\xc8\xc0\x4a\x53\x4a\x39\xa2\x05\x74\x15\x5e\x49",
+       182 },
+      { GCRY_MD_SHA3_224,
+       "\x3e\x15\x35\x0d\x87\xd6\xeb\xb5\xc8\xad\x99\xd4\x25\x15\xcf\xe1\x79\x80\x93\x3c\x7a\x8f\x6b\x8b\xbb\xf0\xa6\x37\x28\xce\xfa\xad\x20\x52\x62\x3c\x0b\xd5\x93\x18\x39\x11\x2a\x48\x63\x3f\xb3\xc2\x00\x4e\x07\x49\xc8\x7a\x41\xb2\x6a\x8b\x48\x94\x55\x39\xd1\xff\x41\xa4\xb2\x69\x46\x2f\xd1\x99\xbf\xec\xd4\x53\x74\x75\x6f\x55\xa9\x11\x6e\x92\x09\x3a\xc9\x94\x51\xae\xfb\x2a\xf9\xfd\x32\xd6\xd7\xf5\xfb\xc7\xf7\xa5\x40\xd5\x09\x7c\x09\x6e\xbc\x3b\x3a\x72\x15\x41\xde\x07\x3a\x1c\xc0\x2f\x7f\xb0\xfb\x1b\x93\x27\xfb\x0b\x12\x18\xca\x49\xc9\x48\x7a\xb5\x39\x66\x22\xa1\x3a\xe5\x46\xc9\x7a\xbd\xef\x6b\x56\x38\x0d\xda\x70\x12\xa8\x38\x40\x91\xb6\x65\x6d\x0a\xb2\x72\xd3\x63\xce\xa7\x81\x63\xff\x76\x5c\xdd\x13\xab\x17\x38\xb9\x40\xd1\x6c\xae",
+       "\x45\x47\x96\xc7\x21\x9c\x6f\x7e\x88\x50\x8d\xfc\x13\x66\x8b\x81\x74\x82\x11\xbd\x01\x6d\x84\xb5\x92\x93\xb4\x45",
+       183 },
+      { GCRY_MD_SHA3_224,
+       "\xc3\x8d\x6b\x0b\x75\x7c\xb5\x52\xbe\x40\x94\x0e\xce\x00\x09\xef\x3b\x0b\x59\x30\x7c\x14\x51\x68\x6f\x1a\x22\x70\x29\x22\x80\x0d\x58\xbc\xe7\xa6\x36\xc1\x72\x7e\xe5\x47\xc0\x1b\x21\x47\x79\xe8\x98\xfc\x0e\x56\x0f\x8a\xe7\xf6\x1b\xef\x4d\x75\xea\xa6\x96\xb9\x21\xfd\x6b\x73\x5d\x17\x15\x35\xe9\xed\xd2\x67\xc1\x92\xb9\x98\x80\xc8\x79\x97\x71\x10\x02\x00\x90\x95\xd8\xa7\xa4\x37\xe2\x58\x10\x4a\x41\xa5\x05\xe5\xef\x71\xe5\x61\x3d\xdd\x20\x08\x19\x5f\x0c\x57\x4e\x6b\xa3\xfe\x40\x09\x9c\xfa\x11\x6e\x5f\x1a\x2f\xa8\xa6\xda\x04\xba\xdc\xb4\xe2\xd5\xd0\xde\x31\xfd\xc4\x80\x08\x91\xc4\x57\x81\xa0\xaa\xc7\xc9\x07\xb5\x6d\x63\x1f\xca\x5c\xe8\xb2\xcd\xe6\x20\xd1\x1d\x17\x77\xed\x9f\xa6\x03\x54\x1d\xe7\x94\xdd\xc5\x75\x8f\xcd\x5f\xad\x78\xc0",
+       "\xce\x15\x8a\xed\x6e\xd3\xc9\xd4\x43\x2e\x24\x22\xaf\x8d\x25\x5a\xb1\xf3\x89\x8f\x6f\x5b\x5c\x5a\x14\x78\x55\x2c",
+       184 },
+      { GCRY_MD_SHA3_224,
+       "\x8d\x2d\xe3\xf0\xb3\x7a\x63\x85\xc9\x07\x39\x80\x5b\x17\x00\x57\xf0\x91\xcd\x0c\x7a\x0b\xc9\x51\x54\x0f\x26\xa5\xa7\x5b\x3e\x69\x46\x31\xbb\x64\xc7\x63\x5e\xed\x31\x6f\x51\x31\x8e\x9d\x8d\xe1\x3c\x70\xa2\xab\xa0\x4a\x14\x83\x68\x55\xf3\x5e\x48\x05\x28\xb7\x76\xd0\xa1\xe8\xa2\x3b\x54\x7c\x8b\x8d\x6a\x0d\x09\xb2\x41\xd3\xbe\x93\x77\x16\x0c\xca\x4e\x67\x93\xd0\x0a\x51\x5d\xc2\x99\x2c\xb7\xfc\x74\x1d\xac\xa1\x71\x43\x1d\xa9\x9c\xce\x6f\x77\x89\xf1\x29\xe2\xac\x5c\xf6\x5b\x40\xd7\x03\x03\x5c\xd2\x18\x5b\xb9\x36\xc8\x20\x02\xda\xf8\xcb\xc2\x7a\x7a\x9e\x55\x4b\x06\x19\x66\x30\x44\x6a\x6f\x0a\x14\xba\x15\x5e\xd2\x6d\x95\xbd\x62\x7b\x72\x05\xc0\x72\xd0\x2b\x60\xdb\x0f\xd7\xe4\x9e\xa0\x58\xc2\xe0\xba\x20\x2d\xaf\xf0\xde\x91\xe8\x45\xcf\x79",
+       "\xa0\xa2\x1d\x95\xe6\x40\xf1\x3b\x25\x65\x24\x84\xe2\x44\xbe\x1b\x37\x3e\x9b\x06\x09\xb6\x85\xef\xce\x48\x10\x7a",
+       185 },
+      { GCRY_MD_SHA3_224,
+       "\xc4\x64\xbb\xda\xd2\x75\xc5\x0d\xcd\x98\x3b\x65\xad\x10\x19\xb9\xff\x85\xa1\xe7\x1c\x80\x7f\x32\x04\xbb\x2c\x92\x1d\xc3\x1f\xbc\xd8\xc5\xfc\x45\x86\x8a\xe9\xef\x85\xb6\xc9\xb8\x3b\xba\x2a\x5a\x82\x22\x01\xed\x68\x58\x6e\xc5\xec\x27\xfb\x28\x57\xa5\xd1\xa2\xd0\x9d\x09\x11\x5f\x22\xdc\xc3\x9f\xe6\x1f\x5e\x1b\xa0\xff\x6e\x8b\x4a\xcb\x4c\x6d\xa7\x48\xbe\x7f\x3f\x08\x39\x73\x93\x94\xff\x7f\xa8\xe3\x9f\x7f\x7e\x84\xa3\x3c\x38\x66\x87\x5c\x01\xbc\xb1\x26\x3c\x94\x05\xd9\x19\x08\xe9\xe0\xb5\x0e\x74\x59\xfa\xbb\x63\xd8\xc6\xbb\xb7\x3d\x8e\x34\x83\xc0\x99\xb5\x5b\xc3\x0f\xf0\x92\xff\x68\xb6\xad\xed\xfd\x47\x7d\x63\x57\x0c\x9f\x55\x15\x84\x7f\x36\xe2\x4b\xa0\xb7\x05\x55\x71\x30\xce\xc5\x7e\xba\xd1\xd0\xb3\x1a\x37\x8e\x91\x89\x4e\xe2\x6e\x3a\x04",
+       "\xca\x8c\xb1\x35\x9f\x0b\x05\xe2\xff\x94\x14\xcc\xe0\xde\x6d\x2c\xb4\xd0\x5b\x08\x35\x4c\x21\x19\xa8\x73\x42\xca",
+       186 },
+      { GCRY_MD_SHA3_224,
+       "\x8b\x8d\x68\xbb\x8a\x75\x73\x2f\xe2\x72\x81\x5a\x68\xa1\xc9\xc5\xaa\x31\xb4\x1d\xed\xc8\x49\x3e\x76\x52\x5d\x1d\x01\x3d\x33\xce\xbd\x9e\x21\xa5\xbb\x95\xdb\x26\x16\x97\x6a\x8c\x07\xfc\xf4\x11\xf5\xf6\xbc\x6f\x7e\x0b\x57\xac\xa7\x8c\xc2\x79\x0a\x6f\x9b\x89\x88\x58\xac\x9c\x79\xb1\x65\xff\x24\xe6\x66\x77\x53\x1e\x39\xf5\x72\xbe\x5d\x81\xeb\x32\x64\x52\x41\x81\x11\x5f\x32\x78\x02\x57\xbf\xb9\xae\xec\x6a\xf1\x2a\xf2\x8e\x58\x7c\xac\x06\x8a\x1a\x29\x53\xb5\x9a\xd6\x80\xf4\xc2\x45\xb2\xe3\xec\x36\xf5\x99\x40\xd3\x7e\x1d\x3d\xb3\x8e\x13\xed\xb2\x9b\x5c\x0f\x40\x4f\x6f\xf8\x7f\x80\xfc\x8b\xe7\xa2\x25\xff\x22\xfb\xb9\xc8\xb6\xb1\xd7\x33\x0c\x57\x84\x0d\x24\xbc\x75\xb0\x6b\x80\xd3\x0d\xad\x68\x06\x54\x4d\x51\x0a\xf6\xc4\x78\x5e\x82\x3a\xc3\xe0\xb8",
+       "\x0d\xdd\xd1\x52\xcf\x06\x3f\x0f\x50\x5b\x51\x8e\xb8\xdb\x75\x57\x04\xf4\x5c\x97\x35\x78\x0e\xc3\xa8\x98\xa9\x23",
+       187 },
+      { GCRY_MD_SHA3_224,
+       "\x6b\x01\x87\x10\x44\x6f\x36\x8e\x74\x21\xf1\xbc\x0c\xcf\x56\x2d\x9c\x18\x43\x84\x6b\xc8\xd9\x8d\x1c\x9b\xf7\xd9\xd6\xfc\xb4\x8b\xfc\x3b\xf8\x3b\x36\xd4\x4c\x4f\xa9\x34\x30\xaf\x75\xcd\x19\x0b\xde\x36\xa7\xf9\x2f\x86\x7f\x58\xa8\x03\x90\x0d\xf8\x01\x81\x50\x38\x4d\x85\xd8\x21\x32\xf1\x23\x00\x6a\xc2\xae\xba\x58\xe0\x2a\x03\x7f\xe6\xaf\xbd\x65\xec\xa7\xc4\x49\x77\xdd\x3d\xc7\x4f\x48\xb6\xe7\xa1\xbf\xd5\xcc\x4d\xcf\x24\xe4\xd5\x2e\x92\xbd\x44\x55\x84\x8e\x49\x28\xb0\xea\xc8\xb7\x47\x6f\xe3\xcc\x03\xe8\x62\xaa\x4d\xff\x44\x70\xdb\xfe\xd6\xde\x48\xe4\x10\xf2\x50\x96\x48\x7e\xcf\xc3\x2a\x27\x27\x7f\x3f\x50\x23\xb2\x72\x5a\xde\x46\x1b\x13\x55\x88\x95\x54\xa8\x83\x6c\x9c\xf5\x3b\xd7\x67\xf5\x73\x7d\x55\x18\x4e\xea\x1a\xb3\xf5\x3e\xdd\x09\x76\xc4\x85",
+       "\x57\x39\x7b\xb1\xf8\x47\x11\x64\x1e\x94\xf4\x13\xf5\xd7\x35\x56\xb9\x6b\xa5\xcf\xe1\x5f\x70\x95\x28\x62\x6d\x07",
+       188 },
+      { GCRY_MD_SHA3_224,
+       "\xc9\x53\x4a\x24\x71\x4b\xd4\xbe\x37\xc8\x8a\x3d\xa1\x08\x2e\xda\x7c\xab\xd1\x54\xc3\x09\xd7\xbd\x67\x0d\xcc\xd9\x5a\xa5\x35\x59\x44\x63\x05\x8a\x29\xf7\x90\x31\xd6\xec\xaa\x9f\x67\x5d\x12\x11\xe9\x35\x9b\xe8\x26\x69\xa7\x9c\x85\x5e\xa8\xd8\x9d\xd3\x8c\x2c\x76\x1d\xdd\x0e\xc0\xce\x9e\x97\x59\x74\x32\xe9\xa1\xbe\xae\x06\x2c\xdd\x71\xed\xfd\xfd\x46\x41\x19\xbe\x9e\x69\xd1\x8a\x7a\x7f\xd7\xce\x0e\x21\x06\xf0\xc8\xb0\xab\xf4\x71\x5e\x2c\xa4\x8e\xf9\xf4\x54\xdc\x20\x3c\x96\x65\x66\x53\xb7\x27\x08\x35\x13\xf8\xef\xb8\x6e\x49\xc5\x13\xbb\x75\x8b\x3b\x05\x2f\xe2\x1f\x1c\x05\xbb\x33\xc3\x71\x29\xd6\xcc\x81\xf1\xae\xf6\xad\xc4\x5b\x0e\x88\x27\xa8\x30\xfe\x54\x5c\xf5\x7d\x09\x55\x80\x2c\x11\x7d\x23\xcc\xb5\x5e\xa2\x8f\x95\xc0\xd8\xc2\xf9\xc5\xa2\x42\xb3\x3f",
+       "\x68\xf6\xac\x42\x89\xfd\x52\x14\x26\x31\x30\x83\x0f\xda\x4d\xa6\x01\xb8\x8b\x1f\x85\x33\xea\xc0\x7a\x03\x38\xd9",
+       189 },
+      { GCRY_MD_SHA3_224,
+       "\x07\x90\x6c\x87\x29\x7b\x86\x7a\xbf\x45\x76\xe9\xf3\xcc\x7f\x82\xf2\x2b\x15\x4a\xfc\xbf\x29\x3b\x93\x19\xf1\xb0\x58\x4d\xa6\xa4\x0c\x27\xb3\x2e\x0b\x1b\x7f\x41\x2c\x4f\x1b\x82\x48\x0e\x70\xa9\x23\x5b\x12\xec\x27\x09\x0a\x5a\x33\x17\x5a\x2b\xb2\x8d\x8a\xdc\x47\x5c\xef\xe3\x3f\x78\x03\xf8\xce\x27\x96\x72\x17\x38\x1f\x02\xe6\x7a\x3b\x4f\x84\xa7\x1f\x1c\x52\x28\xe0\xc2\xad\x97\x13\x73\xf6\xf6\x72\x62\x4f\xce\xa8\xd1\xa9\xf8\x51\x70\xfa\xd3\x0f\xa0\xbb\xd2\x50\x35\xc3\xb4\x1a\x61\x75\xd4\x67\x99\x8b\xd1\x21\x5f\x6f\x38\x66\xf5\x38\x47\xf9\xcf\x68\xef\x3e\x2f\xbb\x54\xbc\x99\x4d\xe2\x30\x2b\x82\x9c\x5e\xea\x68\xec\x44\x1f\xcb\xaf\xd7\xd1\x6a\xe4\xfe\x9f\xff\x98\xbf\x00\xe5\xbc\x2a\xd5\x4d\xd9\x1f\xf9\xfd\xa4\xdd\x77\xb6\xc7\x54\xa9\x19\x55\xd1\xfb\xaa\xd0",
+       "\xf1\x45\xc4\x52\x12\x39\x28\x94\xe7\xf1\xc4\xe5\x27\x28\x47\x0f\x8a\x2d\x96\x15\x14\x86\x99\x90\xef\xbe\x82\x32",
+       190 },
+      { GCRY_MD_SHA3_224,
+       "\x58\x8e\x94\xb9\x05\x4a\xbc\x21\x89\xdf\x69\xb8\xba\x34\x34\x1b\x77\xcd\xd5\x28\xe7\x86\x0e\x5d\xef\xca\xa7\x9b\x0c\x9a\x45\x2a\xd4\xb8\x2a\xa3\x06\xbe\x84\x53\x6e\xb7\xce\xdc\xbe\x05\x8d\x7b\x84\xa6\xae\xf8\x26\xb0\x28\xb8\xa0\x27\x1b\x69\xac\x36\x05\xa9\x63\x5e\xa9\xf5\xea\x0a\xa7\x00\xf3\xeb\x78\x35\xbc\x54\x61\x1b\x92\x29\x64\x30\x0c\x95\x3e\xfe\x74\x91\xe3\x67\x7c\x2c\xeb\xe0\x82\x2e\x95\x6c\xd1\x64\x33\xb0\x2c\x68\xc4\xa2\x32\x52\xc3\xf9\xe1\x51\xa4\x16\xb4\x96\x32\x57\xb7\x83\xe0\x38\xf6\xb4\xd5\xc9\xf1\x10\xf8\x71\x65\x2c\x7a\x64\x9a\x7b\xce\xdc\xbc\xcc\x6f\x2d\x07\x25\xbb\x90\x3c\xc1\x96\xba\x76\xc7\x6a\xa9\xf1\x0a\x19\x0b\x1d\x11\x68\x99\x3b\xaa\x9f\xfc\x96\xa1\x65\x52\x16\x77\x34\x58\xbe\xc7\x2b\x0e\x39\xc9\xf2\xc1\x21\x37\x8f\xea\xb4\xe7\x6a",
+       "\x38\xce\x71\x00\xe9\x2e\xe4\xb6\x5c\xc8\x31\x91\x5a\x06\xcf\xc2\x10\x19\x90\xcb\x68\xe1\x00\x4f\x7e\x90\x17\xd4",
+       191 },
+      { GCRY_MD_SHA3_224,
+       "\x08\x95\x9a\x7e\x4b\xaa\xe8\x74\x92\x88\x13\x36\x40\x71\x19\x4e\x29\x39\x77\x2f\x20\xdb\x7c\x31\x57\x07\x89\x87\xc5\x57\xc2\xa6\xd5\xab\xe6\x8d\x52\x0e\xef\x3d\xc4\x91\x69\x2e\x1e\x21\xbc\xd8\x80\xad\xeb\xf6\x3b\xb4\x21\x3b\x50\x89\x7f\xa0\x05\x25\x6e\xd4\x1b\x56\x90\xf7\x8f\x52\x85\x5c\x8d\x91\x68\xa4\xb6\x66\xfc\xe2\xda\x2b\x45\x6d\x7a\x7e\x7c\x17\xab\x5f\x2f\xb1\xee\x90\xb7\x9e\x69\x87\x12\xe9\x63\x71\x59\x83\xfd\x07\x64\x1a\xe4\xb4\xe9\xdc\x73\x20\x3f\xac\x1a\xe1\x1f\xa1\xf8\xc7\x94\x1f\xcc\x82\xea\xb2\x47\xad\xdb\x56\xe2\x63\x84\x47\xe9\xd6\x09\xe6\x10\xb6\x0c\xe0\x86\x65\x6a\xae\xbf\x1d\xa3\xc8\xa2\x31\xd7\xd9\x4e\x2f\xd0\xaf\xe4\x6b\x39\x1f\xf1\x4a\x72\xea\xeb\x3f\x44\xad\x4d\xf8\x58\x66\xde\xf4\x3d\x47\x81\xa0\xb3\x57\x8b\xc9\x96\xc8\x79\x70\xb1\x32",
+       "\xbd\x63\xca\x84\xda\xc8\xbc\x58\x6d\x0f\x0b\xe3\x52\xdb\xbb\xa1\xf4\xcb\x43\x0d\xea\xa8\x11\x9b\x8d\xa1\x3c\x06",
+       192 },
+      { GCRY_MD_SHA3_224,
+       "\xcb\x2a\x23\x4f\x45\xe2\xec\xd5\x86\x38\x95\xa4\x51\xd3\x89\xa3\x69\xaa\xb9\x9c\xfe\xf0\xd5\xc9\xff\xca\x1e\x6e\x63\xf7\x63\xb5\xc1\x4f\xb9\xb4\x78\x31\x3c\x8e\x8c\x0e\xfe\xb3\xac\x95\x00\xcf\x5f\xd9\x37\x91\xb7\x89\xe6\x7e\xac\x12\xfd\x03\x8e\x25\x47\xcc\x8e\x0f\xc9\xdb\x59\x1f\x33\xa1\xe4\x90\x7c\x64\xa9\x22\xdd\xa2\x3e\xc9\x82\x73\x10\xb3\x06\x09\x85\x54\xa4\xa7\x8f\x05\x02\x62\xdb\x5b\x54\x5b\x15\x9e\x1f\xf1\xdc\xa6\xeb\x73\x4b\x87\x23\x43\xb8\x42\xc5\x7e\xaf\xcf\xda\x84\x05\xee\xdb\xb4\x8e\xf3\x2e\x99\x69\x6d\x13\x59\x79\x23\x5c\x3a\x05\x36\x4e\x37\x1c\x2d\x76\xf1\x90\x2f\x1d\x83\x14\x6d\xf9\x49\x5c\x0a\x6c\x57\xd7\xbf\x9e\xe7\x7e\x80\xf9\x78\x7a\xee\x27\xbe\x1f\xe1\x26\xcd\xc9\xef\x89\x3a\x4a\x7d\xcb\xbc\x36\x7e\x40\xfe\x4e\x1e\xe9\x0b\x42\xea\x25\xaf\x01",
+       "\x7e\xe4\xea\xea\x61\x27\xc6\x8e\xfc\xe6\x69\x91\xb8\xf0\x85\x1f\xe0\x72\xdf\x3b\x1e\x0b\x5d\x07\xe3\xa4\xbe\x06",
+       193 },
+      { GCRY_MD_SHA3_224,
+       "\xd1\x6b\xea\xdf\x02\xab\x1d\x4d\xc6\xf8\x8b\x8c\x45\x54\xc5\x1e\x86\x6d\xf8\x30\xb8\x9c\x06\xe7\x86\xa5\xf8\x75\x7e\x89\x09\x31\x0a\xf5\x1c\x84\x0e\xfe\x8d\x20\xb3\x53\x31\xf4\x35\x5d\x80\xf7\x32\x95\x97\x46\x53\xdd\xd6\x20\xcd\xde\x47\x30\xfb\x6c\x8d\x0d\x2d\xcb\x2b\x45\xd9\x2d\x4f\xbd\xb5\x67\xc0\xa3\xe8\x6b\xd1\xa8\xa7\x95\xaf\x26\xfb\xf2\x9f\xc6\xc6\x59\x41\xcd\xdb\x09\x0f\xf7\xcd\x23\x0a\xc5\x26\x8a\xb4\x60\x6f\xcc\xba\x9e\xde\xd0\xa2\xb5\xd0\x14\xee\x0c\x34\xf0\xb2\x88\x1a\xc0\x36\xe2\x4e\x15\x1b\xe8\x9e\xeb\x6c\xd9\xa7\xa7\x90\xaf\xcc\xff\x23\x4d\x7c\xb1\x1b\x99\xeb\xf5\x8c\xd0\xc5\x89\xf2\x0b\xda\xc4\xf9\xf0\xe2\x8f\x75\xe3\xe0\x4e\x5b\x3d\xeb\xce\x60\x7a\x49\x6d\x84\x8d\x67\xfa\x7b\x49\x13\x2c\x71\xb8\x78\xfd\x55\x57\xe0\x82\xa1\x8e\xca\x1f\xbd\xa9\x4d\x4b",
+       "\x7f\x3e\xe5\x78\xb0\x41\x06\x87\xea\xf5\x36\xf9\xec\x7d\x65\x4b\x75\xf5\x04\xc1\x04\xb7\x87\x93\xc4\xcf\x90\xd5",
+       194 },
+      { GCRY_MD_SHA3_224,
+       "\x8f\x65\xf6\xbc\x59\xa8\x57\x05\x01\x6e\x2b\xae\x7f\xe5\x79\x80\xde\x31\x27\xe5\xab\x27\x5f\x57\x3d\x33\x4f\x73\xf8\x60\x31\x06\xec\x35\x53\x01\x66\x08\xef\x2d\xd6\xe6\x9b\x24\xbe\x0b\x71\x13\xbf\x6a\x76\x0b\xa6\xe9\xce\x1c\x48\xf9\xe1\x86\x01\x2c\xf9\x6a\x1d\x48\x49\xd7\x5d\xf5\xbb\x83\x15\x38\x7f\xd7\x8e\x9e\x15\x3e\x76\xf8\xba\x7e\xc6\xc8\x84\x98\x10\xf5\x9f\xb4\xbb\x9b\x00\x43\x18\x21\x0b\x37\xf1\x29\x95\x26\x86\x6f\x44\x05\x9e\x01\x7e\x22\xe9\x6c\xbe\x41\x86\x99\xd0\x14\xc6\xea\x01\xc9\xf0\x03\x8b\x10\x29\x98\x84\xdb\xec\x31\x99\xbb\x05\xad\xc9\x4e\x95\x5a\x15\x33\x21\x9c\x11\x15\xfe\xd0\xe5\xf2\x12\x28\xb0\x71\xf4\x0d\xd5\x7c\x42\x40\xd9\x8d\x37\xb7\x3e\x41\x2f\xe0\xfa\x47\x03\x12\x0d\x7c\x0c\x67\x97\x2e\xd2\x33\xe5\xde\xb3\x00\xa2\x26\x05\x47\x2f\xa3\xa3\xba\x86",
+       "\xc9\xc2\x63\x96\xe5\x60\xcd\x1e\x68\x24\xd9\xe5\x6e\x17\x9f\xcc\x8a\xac\x4c\x0d\x93\x2f\x76\x32\xba\x59\x4d\x4c",
+       195 },
+      { GCRY_MD_SHA3_224,
+       "\x84\x89\x1e\x52\xe0\xd4\x51\x81\x32\x10\xc3\xfd\x63\x5b\x39\xa0\x3a\x6b\x7a\x73\x17\xb2\x21\xa7\xab\xc2\x70\xdf\xa9\x46\xc4\x26\x69\xaa\xcb\xbb\xdf\x80\x1e\x15\x84\xf3\x30\xe2\x8c\x72\x98\x47\xea\x14\x15\x2b\xd6\x37\xb3\xd0\xf2\xb3\x8b\x4b\xd5\xbf\x9c\x79\x1c\x58\x80\x62\x81\x10\x3a\x3e\xab\xba\xed\xe5\xe7\x11\xe5\x39\xe6\xa8\xb2\xcf\x29\x7c\xf3\x51\xc0\x78\xb4\xfa\x8f\x7f\x35\xcf\x61\xbe\xbf\x88\x14\xbf\x24\x8a\x01\xd4\x1e\x86\xc5\x71\x5e\xa4\x0c\x63\xf7\x37\x53\x79\xa7\xeb\x1d\x78\xf2\x76\x22\xfb\x46\x8a\xb7\x84\xaa\xab\xa4\xe5\x34\xa6\xdf\xd1\xdf\x6f\xa1\x55\x11\x34\x1e\x72\x5e\xd2\xe8\x7f\x98\x73\x7c\xcb\x7b\x6a\x6d\xfa\xe4\x16\x47\x74\x72\xb0\x46\xbf\x18\x11\x18\x7d\x15\x1b\xfa\x9f\x7b\x2b\xf9\xac\xdb\x23\xa3\xbe\x50\x7c\xdf\x14\xcf\xdf\x51\x7d\x2c\xb5\xfb\x9e\x4a\xb6",
+       "\xef\x30\x65\x2e\x3c\x6e\xa4\xec\x21\x44\x72\xbf\x96\xe5\xf3\x0d\xca\x1d\x31\xa7\x8e\xb4\x22\x73\x46\x15\xea\xf1",
+       196 },
+      { GCRY_MD_SHA3_224,
+       "\xfd\xd7\xa9\x43\x3a\x3b\x4a\xfa\xbd\x7a\x3a\x5e\x34\x57\xe5\x6d\xeb\xf7\x8e\x84\xb7\xa0\xb0\xca\x0e\x8c\x6d\x53\xbd\x0c\x2d\xae\x31\xb2\x70\x0c\x61\x28\x33\x4f\x43\x98\x1b\xe3\xb2\x13\xb1\xd7\xa1\x18\xd5\x9c\x7e\x6b\x64\x93\xa8\x6f\x86\x6a\x16\x35\xc1\x28\x59\xcf\xb9\xad\x17\x46\x0a\x77\xb4\x52\x2a\x5c\x18\x83\xc3\xd6\xac\xc8\x6e\x61\x62\x66\x7e\xc4\x14\xe9\xa1\x04\xaa\x89\x20\x53\xa2\xb1\xd7\x21\x65\xa8\x55\xba\xcd\x8f\xaf\x80\x34\xa5\xdd\x9b\x71\x6f\x47\xa0\x81\x8c\x09\xbb\x6b\xaf\x22\xaa\x50\x3c\x06\xb4\xca\x26\x1f\x55\x77\x61\x98\x9d\x2a\xfb\xd8\x8b\x6a\x67\x8a\xd1\x28\xaf\x68\x67\x21\x07\xd0\xf1\xfc\x73\xc5\xca\x74\x04\x59\x29\x7b\x32\x92\xb2\x81\xe9\x3b\xce\xb7\x61\xbd\xe7\x22\x1c\x3a\x55\x70\x8e\x5e\xc8\x44\x72\xcd\xdc\xaa\x84\xec\xf2\x37\x23\xcc\x09\x91\x35\x5c\x62\x80",
+       "\x5a\x96\x4b\xf3\x8e\xb3\x47\x68\x42\x20\xa3\xe8\x3e\xb1\xef\xcb\x64\x1c\x8f\x91\x1c\xb0\x68\xa7\x74\xb2\x5b\x8c",
+       197 },
+      { GCRY_MD_SHA3_224,
+       "\x70\xa4\x0b\xfb\xef\x92\x27\x7a\x1a\xad\x72\xf6\xb7\x9d\x01\x77\x19\x7c\x4e\xbd\x43\x26\x68\xcf\xec\x05\xd0\x99\xac\xcb\x65\x10\x62\xb5\xdf\xf1\x56\xc0\xb2\x73\x36\x68\x7a\x94\xb2\x66\x79\xcf\xdd\x9d\xaf\x7a\xd2\x04\x33\x8d\xd9\xc4\xd1\x41\x14\x03\x3a\x5c\x22\x5b\xd1\x1f\x21\x7b\x5f\x47\x32\xda\x16\x7e\xe3\xf9\x39\x26\x2d\x40\x43\xfc\x9c\xba\x92\x30\x3b\x7b\x5e\x96\xae\xa1\x2a\xdd\xa6\x48\x59\xdf\x4b\x86\xe9\xee\x0b\x58\xe3\x90\x91\xe6\xb1\x88\xb4\x08\xac\x94\xe1\x29\x4a\x89\x11\x24\x5e\xe3\x61\xe6\x0e\x60\x1e\xff\x58\xd1\xd3\x76\x39\xf3\x75\x3b\xec\x80\xeb\xb4\xef\xde\x25\x81\x74\x36\x07\x66\x23\xfc\x65\x41\x5f\xe5\x1d\x1b\x02\x80\x36\x6d\x12\xc5\x54\xd8\x67\x43\xf3\xc3\xb6\x57\x2e\x40\x03\x61\xa6\x07\x26\x13\x14\x41\xba\x49\x3a\x83\xfb\xe9\xaf\xda\x90\xf7\xaf\x1a\xe7\x17\x23\x8d",
+       "\x07\x41\x36\x65\xed\xcb\x8a\x35\x02\x18\x74\x98\x49\x10\xb4\x98\xcf\x74\x82\x30\x50\x64\x02\x43\xae\x7c\x84\xcd",
+       198 },
+      { GCRY_MD_SHA3_224,
+       "\x74\x35\x6e\x44\x9f\x4b\xf8\x64\x4f\x77\xb1\x4f\x4d\x67\xcb\x6b\xd9\xc1\xf5\xae\x35\x76\x21\xd5\xb8\x14\x7e\x56\x2b\x65\xc6\x65\x85\xca\xf2\xe4\x91\xb4\x85\x29\xa0\x1a\x34\xd2\x26\xd4\x36\x95\x91\x53\x81\x53\x80\xd5\x68\x9e\x30\xb3\x53\x57\xcd\xac\x6e\x08\xd3\xf2\xb0\xe8\x8e\x20\x06\x00\xd6\x2b\xd9\xf5\xea\xf4\x88\xdf\x86\xa4\x47\x0e\xa2\x27\x00\x61\x82\xe4\x48\x09\x00\x98\x68\xc4\xc2\x80\xc4\x3d\x7d\x64\xa5\x26\x8f\xa7\x19\x07\x49\x60\x08\x7b\x3a\x6a\xbc\x83\x78\x82\xf8\x82\xc8\x37\x83\x45\x35\x92\x93\x89\xa1\x2b\x2c\x78\x18\x7e\x2e\xa0\x7e\xf8\xb8\xee\xf2\x7d\xc8\x50\x02\xc3\xae\x35\xf1\xa5\x0b\xee\x6a\x1c\x48\xba\x7e\x17\x5f\x33\x16\x67\x0b\x27\x98\x34\x72\xaa\x6a\x61\xee\xd0\xa6\x83\xa3\x9e\xe3\x23\x08\x06\x20\xea\x44\xa9\xf7\x44\x11\xae\x5c\xe9\x90\x30\x52\x8f\x9a\xb4\x9c\x79\xf2",
+       "\xfc\xc9\xea\xd1\x60\x83\x2f\x5f\x0f\xaf\xed\x63\x81\xaf\xd5\x7f\xe1\x33\x5f\xbf\xb0\x5b\x7f\xb1\xf0\x07\x5d\x37",
+       199 },
+      { GCRY_MD_SHA3_224,
+       "\x8c\x37\x98\xe5\x1b\xc6\x84\x82\xd7\x33\x7d\x3a\xbb\x75\xdc\x9f\xfe\x86\x07\x14\xa9\xad\x73\x55\x1e\x12\x00\x59\x86\x0d\xde\x24\xab\x87\x32\x72\x22\xb6\x4c\xf7\x74\x41\x5a\x70\xf7\x24\xcd\xf2\x70\xde\x3f\xe4\x7d\xda\x07\xb6\x1c\x9e\xf2\xa3\x55\x1f\x45\xa5\x58\x48\x60\x24\x8f\xab\xde\x67\x6e\x1c\xd7\x5f\x63\x55\xaa\x3e\xae\xab\xe3\xb5\x1d\xc8\x13\xd9\xfb\x2e\xaa\x4f\x0f\x1d\x9f\x83\x4d\x7c\xad\x9c\x7c\x69\x5a\xe8\x4b\x32\x93\x85\xbc\x0b\xef\x89\x5b\x9f\x1e\xdf\x44\xa0\x3d\x4b\x41\x0c\xc2\x3a\x79\xa6\xb6\x2e\x4f\x34\x6a\x5e\x8d\xd8\x51\xc2\x85\x79\x95\xdd\xbf\x5b\x2d\x71\x7a\xeb\x84\x73\x10\xe1\xf6\xa4\x6a\xc3\xd2\x6a\x7f\x9b\x44\x98\x5a\xf6\x56\xd2\xb7\xc9\x40\x6e\x8a\x9e\x8f\x47\xdc\xb4\xef\x6b\x83\xca\xac\xf9\xae\xfb\x61\x18\xbf\xcf\xf7\xe4\x4b\xef\x69\x37\xeb\xdd\xc8\x91\x86\x83\x9b\x77",
+       "\xec\x5c\x6d\xb6\x0b\x08\x34\xfb\x2e\x0e\x71\x06\xae\xea\xfb\x9e\x61\x4b\xe0\x93\xc8\x47\x01\x82\x14\xd8\xa5\xdb",
+       200 },
+      { GCRY_MD_SHA3_224,
+       "\xfa\x56\xbf\x73\x0c\x4f\x83\x95\x87\x51\x89\xc1\x0c\x4f\xb2\x51\x60\x57\x57\xa8\xfe\xcc\x31\xf9\x73\x7e\x3c\x25\x03\xb0\x26\x08\xe6\x73\x1e\x85\xd7\xa3\x83\x93\xc6\x7d\xe5\x16\xb8\x53\x04\x82\x4b\xfb\x13\x5e\x33\xbf\x22\xb3\xa2\x3b\x91\x3b\xf6\xac\xd2\xb7\xab\x85\x19\x8b\x81\x87\xb2\xbc\xd4\x54\xd5\xe3\x31\x8c\xac\xb3\x2f\xd6\x26\x1c\x31\xae\x7f\x6c\x54\xef\x6a\x7a\x2a\x4c\x9f\x3e\xcb\x81\xce\x35\x55\xd4\xf0\xad\x46\x6d\xd4\xc1\x08\xa9\x03\x99\xd7\x00\x41\x99\x7c\x3b\x25\x34\x5a\x96\x53\xf3\xc9\xa6\x71\x1a\xb1\xb9\x1d\x6a\x9d\x22\x16\x44\x2d\xa2\xc9\x73\xcb\xd6\x85\xee\x76\x43\xbf\xd7\x73\x27\xa2\xf7\xae\x9c\xb2\x83\x62\x0a\x08\x71\x6d\xfb\x46\x2e\x5c\x1d\x65\x43\x2c\xa9\xd5\x6a\x90\xe8\x11\x44\x3c\xd1\xec\xb8\xf0\xde\x17\x9c\x9c\xb4\x8b\xa4\xf6\xfe\xc3\x60\xc6\x6f\x25\x2f\x6e\x64\xed\xc9\x6b",
+       "\x0d\x5f\x6d\xe1\x6b\x7c\xbb\xa4\x9c\x28\x65\x4f\x2a\xe9\x81\x63\x25\x7e\x7b\x6b\x50\x0a\x38\x01\xee\xf0\x73\x3f",
+       201 },
+      { GCRY_MD_SHA3_224,
+       "\xb6\x13\x4f\x9c\x3e\x91\xdd\x80\x00\x74\x0d\x00\x9d\xd8\x06\x24\x08\x11\xd5\x1a\xb1\x54\x6a\x97\x4b\xcb\x18\xd3\x44\x64\x2b\xaa\x5c\xd5\x90\x3a\xf8\x4d\x58\xec\x5b\xa1\x73\x01\xd5\xec\x0f\x10\xcc\xd0\x50\x9c\xbb\x3f\xd3\xff\xf9\x17\x2d\x19\x3a\xf0\xf7\x82\x25\x2f\xd1\x33\x8c\x72\x44\xd4\x0e\x0e\x42\x36\x22\x75\xb2\x2d\x01\xc4\xc3\x38\x9f\x19\xdd\x69\xbd\xf9\x58\xeb\xe2\x8e\x31\xa4\xff\xe2\xb5\xf1\x8a\x87\x83\x1c\xfb\x70\x95\xf5\x8a\x87\xc9\xfa\x21\xdb\x72\xba\x26\x93\x79\xb2\xdc\x23\x84\xb3\xda\x95\x3c\x79\x25\x76\x1f\xed\x32\x46\x20\xac\xea\x43\x5e\x52\xb4\x24\xa7\x72\x3f\x6a\x23\x57\x37\x41\x57\xa3\x4c\xd8\x25\x23\x51\xc2\x5a\x1b\x23\x28\x26\xce\xfe\x1b\xd3\xe7\x0f\xfc\x15\xa3\x1e\x7c\x05\x98\x21\x9d\x7f\x00\x43\x62\x94\xd1\x18\x91\xb8\x24\x97\xbc\x78\xaa\x53\x63\x89\x2a\x24\x95\xdf\x8c\x1e\xef",
+       "\x7b\x7e\x1f\xc4\xd3\x83\x3e\xd8\x7f\xd1\x66\xf9\x09\xf5\xc2\x56\x6d\xc0\xe9\x5b\x17\xac\x83\x4f\x1e\x9e\x3d\xad",
+       202 },
+      { GCRY_MD_SHA3_224,
+       "\xc9\x41\xcd\xb9\xc2\x8a\xb0\xa7\x91\xf2\xe5\xc8\xe8\xbb\x52\x85\x06\x26\xaa\x89\x20\x5b\xec\x3a\x7e\x22\x68\x23\x13\xd1\x98\xb1\xfa\x33\xfc\x72\x95\x38\x13\x54\x85\x87\x58\xae\x6c\x8e\xc6\xfa\xc3\x24\x5c\x6e\x45\x4d\x16\xfa\x2f\x51\xc4\x16\x6f\xab\x51\xdf\x27\x28\x58\xf2\xd6\x03\x77\x0c\x40\x98\x7f\x64\x44\x2d\x48\x7a\xf4\x9c\xd5\xc3\x99\x1c\xe8\x58\xea\x2a\x60\xda\xb6\xa6\x5a\x34\x41\x49\x65\x93\x39\x73\xac\x24\x57\x08\x9e\x35\x91\x60\xb7\xcd\xed\xc4\x2f\x29\xe1\x0a\x91\x92\x17\x85\xf6\xb7\x22\x4e\xe0\xb3\x49\x39\x3c\xdc\xff\x61\x51\xb5\x0b\x37\x7d\x60\x95\x59\x92\x3d\x09\x84\xcd\xa6\x00\x08\x29\xb9\x16\xab\x68\x96\x69\x3e\xf6\xa2\x19\x9b\x3c\x22\xf7\xdc\x55\x00\xa1\x5b\x82\x58\x42\x0e\x31\x4c\x22\x2b\xc0\x00\xbc\x4e\x54\x13\xe6\xdd\x82\xc9\x93\xf8\x33\x0f\x5c\x6d\x1b\xe4\xbc\x79\xf0\x8a\x1a\x0a\x46",
+       "\xc6\xac\x9d\x54\x64\x85\x5e\x5c\x2f\x83\xf2\xa5\x6f\x9a\x99\x21\x37\xda\x47\xec\x05\xc5\x41\x29\x5f\x8c\x43\xe7",
+       203 },
+      { GCRY_MD_SHA3_224,
+       "\x44\x99\xef\xff\xac\x4b\xce\xa5\x27\x47\xef\xd1\xe4\xf2\x0b\x73\xe4\x87\x58\xbe\x91\x5c\x88\xa1\xff\xe5\x29\x9b\x0b\x00\x58\x37\xa4\x6b\x2f\x20\xa9\xcb\x3c\x6e\x64\xa9\xe3\xc5\x64\xa2\x7c\x0f\x1c\x6a\xd1\x96\x03\x73\x03\x6e\xc5\xbf\xe1\xa8\xfc\x6a\x43\x5c\x21\x85\xed\x0f\x11\x4c\x50\xe8\xb3\xe4\xc7\xed\x96\xb0\x6a\x03\x68\x19\xc9\x46\x3e\x86\x4a\x58\xd6\x28\x6f\x78\x5e\x32\xa8\x04\x44\x3a\x56\xaf\x0b\x4d\xf6\xab\xc5\x7e\xd5\xc2\xb1\x85\xdd\xee\x84\x89\xea\x08\x0d\xee\xee\x66\xaa\x33\xc2\xe6\xda\xb3\x62\x51\xc4\x02\x68\x2b\x68\x24\x82\x1f\x99\x8c\x32\x16\x31\x64\x29\x8e\x1f\xaf\xd3\x1b\xab\xbc\xff\xb5\x94\xc9\x18\x88\xc6\x21\x90\x79\xd9\x07\xfd\xb4\x38\xed\x89\x52\x9d\x6d\x96\x21\x2f\xd5\x5a\xbe\x20\x39\x9d\xbe\xfd\x34\x22\x48\x50\x74\x36\x93\x1c\xde\xad\x49\x6e\xb6\xe4\xa8\x03\x58\xac\xc7\x86\x47\xd0\x43",
+       "\x4e\xe2\xf9\x3c\x18\x97\x4d\x97\x8d\xd3\xa1\xcb\xf8\xb1\xda\xc4\x73\x80\x70\x67\xb8\x80\x7d\x02\x61\x82\xb9\x01",
+       204 },
+      { GCRY_MD_SHA3_224,
+       "\xee\xcb\xb8\xfd\xfa\x4d\xa6\x21\x70\xfd\x06\x72\x7f\x69\x7d\x81\xf8\x3f\x60\x1f\xf6\x1e\x47\x81\x05\xd3\xcb\x75\x02\xf2\xc8\x9b\xf3\xe8\xf5\x6e\xdd\x46\x9d\x04\x98\x07\xa3\x88\x82\xa7\xee\xfb\xc8\x5f\xc9\xa9\x50\x95\x2e\x9f\xa8\x4b\x8a\xfe\xbd\x3c\xe7\x82\xd4\xda\x59\x80\x02\x82\x7b\x1e\xb9\x88\x82\xea\x1f\x0a\x8f\x7a\xa9\xce\x01\x3a\x6e\x9b\xc4\x62\xfb\x66\xc8\xd4\xa1\x8d\xa2\x14\x01\xe1\xb9\x33\x56\xeb\x12\xf3\x72\x5b\x6d\xb1\x68\x4f\x23\x00\xa9\x8b\x9a\x11\x9e\x5d\x27\xff\x70\x4a\xff\xb6\x18\xe1\x27\x08\xe7\x7e\x6e\x5f\x34\x13\x9a\x5a\x41\x13\x1f\xd1\xd6\x33\x6c\x27\x2a\x8f\xc3\x70\x80\xf0\x41\xc7\x13\x41\xbe\xe6\xab\x55\x0c\xb4\xa2\x0a\x6d\xdb\x6a\x8e\x02\x99\xf2\xb1\x4b\xc7\x30\xc5\x4b\x8b\x1c\x1c\x48\x7b\x49\x4b\xdc\xcf\xd3\xa5\x35\x35\xab\x2f\x23\x15\x90\xbf\x2c\x40\x62\xfd\x2a\xd5\x8f\x90\x6a\x2d\x0d",
+       "\xd6\x4a\xee\x17\xed\x8e\x2b\x85\xe6\xb0\x97\xdb\x49\x55\x4d\x35\x6f\x03\x2a\x34\xa1\x5b\x7e\x84\x4e\xc8\xd8\x89",
+       205 },
+      { GCRY_MD_SHA3_224,
+       "\xe6\x4f\x3e\x4a\xce\x5c\x84\x18\xd6\x5f\xec\x2b\xc5\xd2\xa3\x03\xdd\x45\x80\x34\x73\x6e\x3b\x0d\xf7\x19\x09\x8b\xe7\xa2\x06\xde\xaf\x52\xd6\xba\x82\x31\x6c\xaf\x33\x0e\xf8\x52\x37\x51\x88\xcd\xe2\xb3\x9c\xc9\x4a\xa4\x49\x57\x8a\x7e\x2a\x8e\x3f\x5a\x9d\x68\xe8\x16\xb8\xd1\x68\x89\xfb\xc0\xeb\xf0\x93\x9d\x04\xf6\x30\x33\xae\x9a\xe2\xbd\xab\x73\xb8\x8c\x26\xd6\xbd\x25\xee\x46\x0e\xe1\xef\x58\xfb\x0a\xfa\x92\xcc\x53\x9f\x8c\x76\xd3\xd0\x97\xe7\xa6\xa6\x3e\xbb\x9b\x58\x87\xed\xf3\xcf\x07\x60\x28\xc5\xbb\xd5\xb9\xdb\x32\x11\x37\x1a\xd3\xfe\x12\x1d\x4e\x9b\xf4\x42\x29\xf4\xe1\xec\xf5\xa0\xf9\xf0\xeb\xa4\xd5\xce\xb7\x28\x78\xab\x22\xc3\xf0\xeb\x5a\x62\x53\x23\xac\x66\xf7\x06\x1f\x4a\x81\xfa\xc8\x34\x47\x1e\x0c\x59\x55\x3f\x10\x84\x75\xfe\x29\x0d\x43\xe6\xa0\x55\xae\x3e\xe4\x6f\xb6\x74\x22\xf8\x14\xa6\x8c\x4b\xe3\xe8\xc9",
+       "\x1b\xdd\xc9\x2b\xe8\x9a\x67\x2c\x1b\xd9\x56\xb4\x50\xb9\xd7\xb4\x7b\x4b\xb0\xbc\x58\xac\x51\xf1\x5f\x7e\x05\x4d",
+       206 },
+      { GCRY_MD_SHA3_224,
+       "\xd2\xcb\x2d\x73\x30\x33\xf9\xe9\x13\x95\x31\x28\x08\x38\x3c\xc4\xf0\xca\x97\x4e\x87\xec\x68\x40\x0d\x52\xe9\x6b\x3f\xa6\x98\x4a\xc5\x8d\x9a\xd0\x93\x8d\xde\x5a\x97\x30\x08\xd8\x18\xc4\x96\x07\xd9\xde\x22\x84\xe7\x61\x8f\x1b\x8a\xed\x83\x72\xfb\xd5\x2e\xd5\x45\x57\xaf\x42\x20\xfa\xc0\x9d\xfa\x84\x43\x01\x16\x99\xb9\x7d\x74\x3f\x8f\x2b\x1a\xef\x35\x37\xeb\xb4\x5d\xcc\x9e\x13\xdf\xb4\x38\x42\x8e\xe1\x90\xa4\xef\xdb\x3c\xae\xb7\xf3\x93\x31\x17\xbf\x63\xab\xdc\x7e\x57\xbe\xb4\x17\x1c\x7e\x1a\xd2\x60\xab\x05\x87\x80\x6c\x4d\x13\x7b\x63\x16\xb5\x0a\xbc\x9c\xce\x0d\xff\x3a\xca\xda\x47\xbb\xb8\x6b\xe7\x77\xe6\x17\xbb\xe5\x78\xff\x45\x19\x84\x4d\xb3\x60\xe0\xa9\x6c\x67\x01\x29\x0e\x76\xbb\x95\xd2\x6f\x0f\x80\x4c\x8a\x4f\x27\x17\xea\xc4\xe7\xde\x9f\x2c\xff\x3b\xbc\x55\xa1\x7e\x77\x6c\x0d\x02\x85\x60\x32\xa6\xcd\x10\xad\x28\x38",
+       "\x0c\x8a\xc2\x40\x17\x0c\x65\x46\xde\xbf\x4b\xfb\x5b\x38\xf8\xf3\x0e\xa5\xdc\x6e\xf8\x6c\x16\x6e\x8e\x13\x6d\x6b",
+       207 },
+      { GCRY_MD_SHA3_224,
+       "\xf2\x99\x89\x55\x61\x3d\xd4\x14\xcc\x11\x1d\xf5\xce\x30\xa9\x95\xbb\x79\x2e\x26\x0b\x0e\x37\xa5\xb1\xd9\x42\xfe\x90\x17\x1a\x4a\xc2\xf6\x6d\x49\x28\xd7\xad\x37\x7f\x4d\x05\x54\xcb\xf4\xc5\x23\xd2\x1f\x6e\x5f\x37\x9d\x6f\x4b\x02\x8c\xdc\xb9\xb1\x75\x8d\x3b\x39\x66\x32\x42\xff\x3c\xb6\xed\xe6\xa3\x6a\x6f\x05\xdb\x3b\xc4\x1e\x0d\x86\x1b\x38\x4b\x6d\xec\x58\xbb\x09\x6d\x0a\x42\x2f\xd5\x42\xdf\x17\x5e\x1b\xe1\x57\x1f\xb5\x2a\xe6\x6f\x2d\x86\xa2\xf6\x82\x4a\x8c\xfa\xac\xba\xc4\xa7\x49\x2a\xd0\x43\x3e\xeb\x15\x45\x4a\xf8\xf3\x12\xb3\xb2\xa5\x77\x75\x0e\x3e\xfb\xd3\x70\xe8\xa8\xca\xc1\x58\x25\x81\x97\x1f\xba\x3b\xa4\xbd\x0d\x76\xe7\x18\xda\xcf\x84\x33\xd3\x3a\x59\xd2\x87\xf8\xcc\x92\x23\x4e\x7a\x27\x10\x41\xb5\x26\xe3\x89\xef\xb0\xe4\x0b\x6a\x18\xb3\xaa\xf6\x58\xe8\x2e\xd1\xc7\x86\x31\xfd\x23\xb4\xc3\xeb\x27\xc3\xfa\xec\x86\x85",
+       "\x2f\xd9\xfd\xfd\x24\x4b\x0a\x73\x42\xf8\x86\xb8\x7b\x3d\xdd\xce\x54\xc8\x87\x0f\xb2\x6a\x71\xa8\xf6\x52\x02\x31",
+       208 },
+      { GCRY_MD_SHA3_224,
+       "\x44\x77\x97\xe2\x89\x9b\x72\xa3\x56\xba\x55\xbf\x4d\xf3\xac\xca\x6c\xdb\x10\x41\xeb\x47\x7b\xd1\x83\x4a\x9f\x9a\xcb\xc3\x40\xa2\x94\xd7\x29\xf2\xf9\x7d\xf3\xa6\x10\xbe\x0f\xf1\x5e\xdb\x9c\x6d\x5d\xb4\x16\x44\xb9\x87\x43\x60\x14\x0f\xc6\x4f\x52\xaa\x03\xf0\x28\x6c\x8a\x64\x06\x70\x06\x7a\x84\xe0\x17\x92\x6a\x70\x43\x8d\xb1\xbb\x36\x1d\xef\xee\x73\x17\x02\x14\x25\xf8\x82\x1d\xef\x26\xd1\xef\xd7\x7f\xc8\x53\xb8\x18\x54\x5d\x05\x5a\xdc\x92\x84\x79\x6e\x58\x3c\x76\xe6\xfe\x74\xc9\xac\x25\x87\xaa\x46\xaa\x8f\x88\x04\xf2\xfe\xb5\x83\x6c\xc4\xb3\xab\xab\xab\x84\x29\xa5\x78\x3e\x17\xd5\x99\x9f\x32\x24\x2e\xb5\x9e\xf3\x0c\xd7\xad\xab\xc1\x6d\x72\xdb\xdb\x09\x76\x23\x04\x7c\x98\x98\x9f\x88\xd1\x4e\xaf\x02\xa7\x21\x2b\xe1\x6e\xc2\xd0\x79\x81\xaa\xa9\x99\x49\xdd\xf8\x9e\xcd\x90\x33\x3a\x77\xbc\x4e\x19\x88\xa8\x2a\xbf\x7c\x7c\xaf\x32\x91",
+       "\x1b\x6b\xe1\x9d\x72\x19\x9b\xf7\x5f\xd4\x07\x5e\x54\x97\x5a\xfa\x04\x33\xb9\xbf\x51\x5b\xd3\x00\xce\x54\x3d\x41",
+       209 },
+      { GCRY_MD_SHA3_224,
+       "\x9f\x2c\x18\xad\xe9\xb3\x80\xc7\x84\xe1\x70\xfb\x76\x3e\x9a\xa2\x05\xf6\x43\x03\x06\x7e\xb1\xbc\xea\x93\xdf\x5d\xac\x4b\xf5\xa2\xe0\x0b\x78\x19\x5f\x80\x8d\xf2\x4f\xc7\x6e\x26\xcb\x7b\xe3\x1d\xc3\x5f\x08\x44\xcd\xed\x15\x67\xbb\xa2\x98\x58\xcf\xfc\x97\xfb\x29\x01\x03\x31\xb0\x1d\x6a\x3f\xb3\x15\x9c\xc1\xb9\x73\xd2\x55\xda\x98\x43\xe3\x4a\x0a\x40\x61\xca\xbd\xb9\xed\x37\xf2\x41\xbf\xab\xb3\xc2\x0d\x32\x74\x3f\x40\x26\xb5\x9a\x4c\xcc\x38\x5a\x23\x01\xf8\x3c\x0b\x0a\x19\x0b\x0f\x2d\x01\xac\xb8\xf0\xd4\x11\x11\xe1\x0f\x2f\x4e\x14\x93\x79\x27\x55\x99\xa5\x2d\xc0\x89\xb3\x5f\xdd\x52\x34\xb0\xcf\xb7\xb6\xd8\xae\xbd\x56\x3c\xa1\xfa\x65\x3c\x5c\x02\x1d\xfd\x6f\x59\x20\xe6\xf1\x8b\xfa\xfd\xbe\xcb\xf0\xab\x00\x28\x13\x33\xed\x50\xb9\xa9\x99\x54\x9c\x1c\x8f\x8c\x63\xd7\x62\x6c\x48\x32\x2e\x97\x91\xd5\xff\x72\x29\x40\x49\xbd\xe9\x1e\x73\xf8",
+       "\xa4\x6b\x89\xb6\x4b\x0c\x79\x30\xdd\x45\xf5\xb2\x58\x2f\xd7\x9c\x7a\xd9\x0a\x58\xc9\x4c\x52\xf9\xbf\xa5\x5c\xfc",
+       210 },
+      { GCRY_MD_SHA3_224,
+       "\xae\x15\x9f\x3f\xa3\x36\x19\x00\x2a\xe6\xbc\xce\x8c\xbb\xdd\x7d\x28\xe5\xed\x9d\x61\x53\x45\x95\xc4\xc9\xf4\x3c\x40\x2a\x9b\xb3\x1f\x3b\x30\x1c\xbf\xd4\xa4\x3c\xe4\xc2\x4c\xd5\xc9\x84\x9c\xc6\x25\x9e\xca\x90\xe2\xa7\x9e\x01\xff\xba\xc0\x7b\xa0\xe1\x47\xfa\x42\x67\x6a\x1d\x66\x85\x70\xe0\x39\x63\x87\xb5\xbc\xd5\x99\xe8\xe6\x6a\xae\xd1\xb8\xa1\x91\xc5\xa4\x75\x47\xf6\x13\x73\x02\x1f\xa6\xde\xad\xcb\x55\x36\x3d\x23\x3c\x24\x44\x0f\x2c\x73\xdb\xb5\x19\xf7\xc9\xfa\x5a\x89\x62\xef\xd5\xf6\x25\x2c\x04\x07\xf1\x90\xdf\xef\xad\x70\x7f\x3c\x70\x07\xd6\x9f\xf3\x6b\x84\x89\xa5\xb6\xb7\xc5\x57\xe7\x9d\xd4\xf5\x0c\x06\x51\x1f\x59\x9f\x56\xc8\x96\xb3\x5c\x91\x7b\x63\xba\x35\xc6\xff\x80\x92\xba\xf7\xd1\x65\x8e\x77\xfc\x95\xd8\xa6\xa4\x3e\xeb\x4c\x01\xf3\x3f\x03\x87\x7f\x92\x77\x4b\xe8\x9c\x11\x14\xdd\x53\x1c\x01\x1e\x53\xa3\x4d\xc2\x48\xa2\xf0\xe6",
+       "\x21\xf0\xd8\x85\x53\x87\x24\x1d\x71\xa7\x12\xe5\xf5\x68\x2c\x15\x6b\x9f\xd2\xaa\x62\x84\x29\x47\x18\x85\x3f\x0a",
+       211 },
+      { GCRY_MD_SHA3_224,
+       "\x3b\x8e\x97\xc5\xff\xc2\xd6\xa4\x0f\xa7\xde\x7f\xce\xfc\x90\xf3\xb1\x2c\x94\x0e\x7a\xb4\x15\x32\x1e\x29\xee\x69\x2d\xfa\xc7\x99\xb0\x09\xc9\x9d\xcd\xdb\x70\x8f\xce\x5a\x17\x8c\x5c\x35\xee\x2b\x86\x17\x14\x3e\xdc\x4c\x40\xb4\xd3\x13\x66\x1f\x49\xab\xdd\x93\xce\xa7\x9d\x11\x75\x18\x80\x54\x96\xfe\x6a\xcf\x29\x2c\x4c\x2a\x1f\x76\xb4\x03\xa9\x7d\x7c\x39\x9d\xaf\x85\xb4\x6a\xd8\x4e\x16\x24\x6c\x67\xd6\x83\x67\x57\xbd\xe3\x36\xc2\x90\xd5\xd4\x01\xe6\xc1\x38\x6a\xb3\x27\x97\xaf\x6b\xb2\x51\xe9\xb2\xd8\xfe\x75\x4c\x47\x48\x2b\x72\xe0\xb3\x94\xea\xb7\x69\x16\x12\x6f\xd6\x8e\xa7\xd6\x5e\xb9\x3d\x59\xf5\xb4\xc5\xac\x40\xf7\xc3\xb3\x7e\x7f\x36\x94\xf2\x94\x24\xc2\x4a\xf8\xc8\xf0\xef\x59\xcd\x9d\xbf\x1d\x28\xe0\xe1\x0f\x79\x9a\x6f\x78\xca\xd1\xd4\x5b\x9d\xb3\xd7\xde\xe4\xa7\x05\x9a\xbe\x99\x18\x27\x14\x98\x3b\x9c\x9d\x44\xd7\xf5\x64\x35\x96\xd4\xf3",
+       "\x82\xee\x85\x54\x1d\x7a\x5b\x2a\x2b\x29\x00\x03\xc3\xee\x46\x57\x4d\x58\xa7\xdd\xd5\x4f\xbc\x21\x0f\x8f\xea\x57",
+       212 },
+      { GCRY_MD_SHA3_224,
+       "\x34\x34\xec\x31\xb1\x0f\xaf\xdb\xfe\xec\x0d\xd6\xbd\x94\xe8\x0f\x7b\xa9\xdc\xa1\x9e\xf0\x75\xf7\xeb\x01\x75\x12\xaf\x66\xd6\xa4\xbc\xf7\xd1\x6b\xa0\x81\x9a\x18\x92\xa6\x37\x2f\x9b\x35\xbc\xc7\xca\x81\x55\xee\x19\xe8\x42\x8b\xc2\x2d\x21\x48\x56\xed\x5f\xa9\x37\x4c\x3c\x09\xbd\xe1\x69\x60\x2c\xc2\x19\x67\x9f\x65\xa1\x56\x6f\xc7\x31\x6f\x4c\xc3\xb6\x31\xa1\x8f\xb4\x44\x9f\xa6\xaf\xa1\x6a\x3d\xb2\xbc\x42\x12\xef\xf5\x39\xc6\x7c\xf1\x84\x68\x08\x26\x53\x55\x89\xc7\x11\x1d\x73\xbf\xfc\xe4\x31\xb4\xc4\x04\x92\xe7\x63\xd9\x27\x95\x60\xaa\xa3\x8e\xb2\xdc\x14\xa2\x12\xd7\x23\xf9\x94\xa1\xfe\x65\x6f\xf4\xdd\x14\x55\x1c\xe4\xe7\xc6\x21\xb2\xaa\x56\x04\xa1\x00\x01\xb2\x87\x8a\x89\x7a\x28\xa0\x80\x95\xc3\x25\xe1\x0a\x26\xd2\xfb\x1a\x75\xbf\xd6\x4c\x25\x03\x09\xbb\x55\xa4\x4f\x23\xbb\xac\x0d\x55\x16\xa1\xc6\x87\xd3\xb4\x1e\xf2\xfb\xbf\x9c\xc5\x6d\x47\x39",
+       "\x27\x8d\xd8\xa3\xf3\x20\x81\x91\xcf\xf6\x58\xb8\xd6\xdb\x35\xe1\x33\xa1\x6e\x47\xaa\x37\x5e\xdb\x92\xc6\xa7\x37",
+       213 },
+      { GCRY_MD_SHA3_224,
+       "\x7c\x79\x53\xd8\x1c\x8d\x20\x8f\xd1\xc9\x76\x81\xd4\x8f\x49\xdd\x00\x34\x56\xde\x60\x47\x5b\x84\x07\x0e\xf4\x84\x7c\x33\x3b\x74\x57\x5b\x1f\xc8\xd2\xa1\x86\x96\x44\x85\xa3\xb8\x63\x4f\xea\xa3\x59\x5a\xaa\x1a\x2f\x45\x95\xa7\xd6\xb6\x15\x35\x63\xde\xe3\x1b\xba\xc4\x43\xc8\xa3\x3e\xed\x6d\x5d\x95\x6a\x98\x0a\x68\x36\x6c\x25\x27\xb5\x50\xee\x95\x02\x50\xdf\xb6\x91\xea\xcb\xd5\xd5\x6a\xe1\x4b\x97\x06\x68\xbe\x17\x4c\x89\xdf\x2f\xea\x43\xae\x52\xf1\x31\x42\x63\x9c\x88\x4f\xd6\x2a\x36\x83\xc0\xc3\x79\x2f\x0f\x24\xab\x13\x18\xbc\xb2\x7e\x21\xf4\x73\x7f\xab\x62\xc7\x7e\xa3\x8b\xc8\xfd\x1c\xf4\x1f\x7d\xab\x64\xc1\x3f\xeb\xe7\x15\x2b\xf5\xbb\x7a\xb5\xa7\x8f\x53\x46\xd4\x3c\xc7\x41\xcb\x6f\x72\xb7\xb8\x98\x0f\x26\x8b\x68\xbf\x62\xab\xdf\xb1\x57\x7a\x52\x43\x8f\xe1\x4b\x59\x14\x98\xcc\x95\xf0\x71\x22\x84\x60\xc7\xc5\xd5\xce\xb4\xa7\xbd\xe5\x88\xe7\xf2\x1c",
+       "\xb5\x05\x27\x71\x1c\x04\x7d\xef\x70\xb1\x7c\xf2\x0f\x97\x0b\xed\x79\xc1\xc1\xb9\x52\x75\xc2\x78\x4c\x39\x03\xde",
+       214 },
+      { GCRY_MD_SHA3_224,
+       "\x7a\x6a\x4f\x4f\xdc\x59\xa1\xd2\x23\x38\x1a\xe5\xaf\x49\x8d\x74\xb7\x25\x2e\xcf\x59\xe3\x89\xe4\x91\x30\xc7\xea\xee\x62\x6e\x7b\xd9\x89\x7e\xff\xd9\x20\x17\xf4\xcc\xde\x66\xb0\x44\x04\x62\xcd\xed\xfd\x35\x2d\x81\x53\xe6\xa4\xc8\xd7\xa0\x81\x2f\x70\x1c\xc7\x37\xb5\x17\x8c\x25\x56\xf0\x71\x11\x20\x0e\xb6\x27\xdb\xc2\x99\xca\xa7\x92\xdf\xa5\x8f\x35\x93\x52\x99\xfa\x3a\x35\x19\xe9\xb0\x31\x66\xdf\xfa\x15\x91\x03\xff\xa3\x5e\x85\x77\xf7\xc0\xa8\x6c\x6b\x46\xfe\x13\xdb\x8e\x2c\xdd\x9d\xcf\xba\x85\xbd\xdd\xcc\xe0\xa7\xa8\xe1\x55\xf8\x1f\x71\x2d\x8e\x9f\xe6\x46\x15\x3d\x3d\x22\xc8\x11\xbd\x39\xf8\x30\x43\x3b\x22\x13\xdd\x46\x30\x19\x41\xb5\x92\x93\xfd\x0a\x33\xe2\xb6\x3a\xdb\xd9\x52\x39\xbc\x01\x31\x5c\x46\xfd\xb6\x78\x87\x5b\x3c\x81\xe0\x53\xa4\x0f\x58\x1c\xfb\xec\x24\xa1\x40\x4b\x16\x71\xa1\xb8\x8a\x6d\x06\x12\x02\x29\x51\x8f\xb1\x3a\x74\xca\x0a\xc5\xae",
+       "\xf7\x7c\xb5\x27\x52\x12\xc9\x2f\xa0\xda\xd9\x21\xb6\x5f\x50\x81\x48\x22\xe3\xd6\xd5\x84\xc8\x95\x28\x99\x0f\x02",
+       215 },
+      { GCRY_MD_SHA3_224,
+       "\xd9\xfa\xa1\x4c\xeb\xe9\xb7\xde\x55\x1b\x6c\x07\x65\x40\x9a\x33\x93\x85\x62\x01\x3b\x5e\x8e\x0e\x1e\x0a\x64\x18\xdf\x73\x99\xd0\xa6\xa7\x71\xfb\x81\xc3\xca\x9b\xd3\xbb\x8e\x29\x51\xb0\xbc\x79\x25\x25\xa2\x94\xeb\xd1\x08\x36\x88\x80\x6f\xe5\xe7\xf1\xe1\x7f\xd4\xe3\xa4\x1d\x00\xc8\x9e\x8f\xcf\x4a\x36\x3c\xae\xdb\x1a\xcb\x55\x8e\x3d\x56\x2f\x13\x02\xb3\xd8\x3b\xb8\x86\xed\x27\xb7\x60\x33\x79\x81\x31\xda\xb0\x5b\x42\x17\x38\x1e\xaa\xa7\xba\x15\xec\x82\x0b\xb5\xc1\x3b\x51\x6d\xd6\x40\xea\xec\x5a\x27\xd0\x5f\xdf\xca\x0f\x35\xb3\xa5\x31\x21\x46\x80\x6b\x4c\x02\x75\xbc\xd0\xaa\xa3\xb2\x01\x7f\x34\x69\x75\xdb\x56\x6f\x9b\x4d\x13\x7f\x4e\xe1\x06\x44\xc2\xa2\xda\x66\xde\xec\xa5\x34\x2e\x23\x64\x95\xc3\xc6\x28\x05\x28\xbf\xd3\x2e\x90\xaf\x4c\xd9\xbb\x90\x8f\x34\x01\x2b\x52\xb4\xbc\x56\xd4\x8c\xc8\xa6\xb5\x9b\xab\x01\x49\x88\xea\xbd\x12\xe1\xa0\xa1\xc2\xe1\x70\xe7",
+       "\x76\xca\x9e\x68\x5d\xfa\xdc\x67\x57\x6d\x44\xe8\xc1\xa8\x2e\x8c\xf7\xe9\x2f\xb0\xa8\x1f\xe4\x9e\x21\x10\x8e\x09",
+       216 },
+      { GCRY_MD_SHA3_224,
+       "\x2d\x84\x27\x43\x3d\x0c\x61\xf2\xd9\x6c\xfe\x80\xcf\x1e\x93\x22\x65\xa1\x91\x36\x5c\x3b\x61\xaa\xa3\xd6\xdc\xc0\x39\xf6\xba\x2a\xd5\x2a\x6a\x8c\xc3\x0f\xc1\x0f\x70\x5e\x6b\x77\x05\x10\x59\x77\xfa\x49\x6c\x1c\x70\x8a\x27\x7a\x12\x43\x04\xf1\xfc\x40\x91\x1e\x74\x41\xd1\xb5\xe7\x7b\x95\x1a\xad\x7b\x01\xfd\x5d\xb1\xb3\x77\xd1\x65\xb0\x5b\xbf\x89\x80\x42\xe3\x96\x60\xca\xf8\xb2\x79\xfe\x52\x29\xd1\xa8\xdb\x86\xc0\x99\x9e\xd6\x5e\x53\xd0\x1c\xcb\xc4\xb4\x31\x73\xcc\xf9\x92\xb3\xa1\x45\x86\xf6\xba\x42\xf5\xfe\x30\xaf\xa8\xae\x40\xc5\xdf\x29\x96\x6f\x93\x46\xda\x5f\x8b\x35\xf1\x6a\x1d\xe3\xab\x6d\xe0\xf4\x77\xd8\xd8\x66\x09\x18\x06\x0e\x88\xb9\xb9\xe9\xca\x6a\x42\x07\x03\x3b\x87\xa8\x12\xdb\xf5\x54\x4d\x39\xe4\x88\x20\x10\xf8\x2b\x6c\xe0\x05\xf8\xe8\xff\x6f\xe3\xc3\x80\x6b\xc2\xb7\x3c\x2b\x83\xaf\xb7\x04\x34\x56\x29\x30\x4f\x9f\x86\x35\x87\x12\xe9\xfa\xe3\xca\x3e",
+       "\xab\xd3\x13\xbc\x70\xb7\xfa\xb0\xeb\xc1\x67\xd7\x39\xb5\x4c\x97\x38\x9e\x75\x2e\xe1\xa3\x13\xb1\x26\x73\xf5\x1c",
+       217 },
+      { GCRY_MD_SHA3_224,
+       "\x5e\x19\xd9\x78\x87\xfc\xaa\xc0\x38\x7e\x22\xc6\xf8\x03\xc3\x4a\x3d\xac\xd2\x60\x41\x72\x43\x3f\x7a\x8a\x7a\x52\x6c\xa4\xa2\xa1\x27\x1e\xcf\xc5\xd5\xd7\xbe\x5a\xc0\xd8\x5d\x92\x10\x95\x35\x0d\xfc\x65\x99\x7d\x44\x3c\x21\xc8\x09\x4e\x0a\x3f\xef\xd2\x96\x1b\xcb\x94\xae\xd0\x32\x91\xae\x31\x0c\xcd\xa7\x5d\x8a\xce\x4b\xc7\xd8\x9e\x7d\x3e\x5d\x16\x50\xbd\xa5\xd6\x68\xb8\xb5\x0b\xfc\x8e\x60\x8e\x18\x4f\x4d\x3a\x9a\x2b\xad\xc4\xff\x5f\x07\xe0\xc0\xbc\x8a\x9f\x2e\x0b\x2a\x26\xfd\x6d\x8c\x55\x00\x08\xfa\xaa\xb7\x5f\xd7\x1a\xf2\xa4\x24\xbe\xc9\xa7\xcd\x9d\x83\xfa\xd4\xc8\xe9\x31\x91\x15\x65\x6a\x87\x17\xd3\xb5\x23\xa6\x8f\xf8\x00\x42\x58\xb9\x99\x0e\xd3\x62\x30\x84\x61\x80\x4b\xa3\xe3\xa7\xe9\x2d\x8f\x2f\xfa\xe5\xc2\xfb\xa5\x5b\xa5\xa3\xc2\x7c\x0a\x2f\x71\xbd\x71\x1d\x2f\xe1\x79\x9c\x2a\xdb\x31\xb2\x00\x03\x54\x81\xe9\xee\x5c\x4a\xdf\x2a\xb9\xc0\xfa\x50\xb2\x39\x75\xcf",
+       "\xf7\x9f\x63\x56\x32\x8c\x58\x0b\x81\x1f\xea\x81\xc5\xed\x90\xa3\x03\xca\xf3\x4a\x09\xbe\xb1\x43\xbe\x45\x0d\x42",
+       218 },
+      { GCRY_MD_SHA3_224,
+       "\xc8\xe9\x76\xab\x46\x38\x90\x93\x87\xce\x3b\x8d\x4e\x51\x0c\x32\x30\xe5\x69\x0e\x02\xc4\x50\x93\xb1\xd2\x97\x91\x0a\xbc\x48\x1e\x56\xee\xa0\xf2\x96\xf9\x83\x79\xdf\xc9\x08\x0a\xf6\x9e\x73\xb2\x39\x9d\x1c\x14\x3b\xee\x80\xae\x13\x28\x16\x2c\xe1\xba\x7f\x6a\x83\x74\x67\x9b\x20\xaa\xcd\x38\x0e\xb4\xe6\x13\x82\xc9\x99\x98\x70\x4d\x62\x70\x1a\xfa\x91\x4f\x9a\x27\x05\xcd\xb0\x65\x88\x5f\x50\xd0\x86\xc3\xeb\x57\x53\x70\x0c\x38\x71\x18\xbb\x14\x2f\x3e\x6d\xa1\xe9\x88\xdf\xb3\x1a\xc7\x5d\x73\x68\x93\x1e\x45\xd1\x39\x1a\x27\x4b\x22\xf8\x3c\xeb\x07\x2f\x9b\xca\xbc\x0b\x21\x66\x85\xbf\xd7\x89\xf5\x02\x39\x71\x02\x4b\x18\x78\xa2\x05\x44\x25\x22\xf9\xea\x7d\x87\x97\xa4\x10\x2a\x3d\xf4\x17\x03\x76\x82\x51\xfd\x5e\x01\x7c\x85\xd1\x20\x0a\x46\x41\x18\xaa\x35\x65\x4e\x7c\xa3\x9f\x3c\x37\x5b\x8e\xf8\xcb\xe7\x53\x4d\xbc\x64\xbc\x20\xbe\xfb\x41\x7c\xf6\x0e\xc9\x2f\x63\xd9\xee\x73\x97",
+       "\x29\x9d\x62\xf8\xdf\x5e\xad\xe6\x87\x18\x83\xb0\x33\xb8\x30\xa9\x95\x2a\x74\xb1\x2f\x3d\x55\xaf\x79\x8c\x69\x97",
+       219 },
+      { GCRY_MD_SHA3_224,
+       "\x71\x45\xfa\x12\x4b\x74\x29\xa1\xfc\x22\x31\x23\x7a\x94\x9b\xa7\x20\x1b\xcc\x18\x22\xd3\x27\x2d\xe0\x05\xb6\x82\x39\x81\x96\xc2\x5f\x7e\x5c\xc2\xf2\x89\xfb\xf4\x44\x15\xf6\x99\xcb\x7f\xe6\x75\x77\x91\xb1\x44\x34\x10\x23\x4a\xe0\x61\xed\xf6\x23\x35\x9e\x2b\x4e\x32\xc1\x9b\xf8\x84\x50\x43\x2d\xd0\x1c\xaa\x5e\xb1\x6a\x1d\xc3\x78\xf3\x91\xca\x5e\x3c\x4e\x5f\x35\x67\x28\xbd\xdd\x49\x75\xdb\x7c\x89\x0d\xa8\xbb\xc8\x4c\xc7\x3f\xf2\x44\x39\x4d\x0d\x48\x95\x49\x78\x76\x5e\x4a\x00\xb5\x93\xf7\x0f\x2c\xa0\x82\x67\x3a\x26\x1e\xd8\x8d\xbc\xef\x11\x27\x72\x8d\x8c\xd8\x9b\xc2\xc5\x97\xe9\x10\x2c\xed\x60\x10\xf6\x5f\xa7\x5a\x14\xeb\xe4\x67\xfa\x57\xce\x3b\xd4\x94\x8b\x68\x67\xd7\x4a\x9d\xf5\xc0\xec\x6f\x53\x0c\xbf\x2e\xe6\x1c\xe6\xf0\x6b\xc8\xf2\x86\x4d\xff\x55\x83\x77\x6b\x31\xdf\x8c\x7f\xfc\xb6\x14\x28\xa5\x6b\xf7\xbd\x37\x18\x8b\x4a\x51\x23\xbb\xf3\x38\x39\x3a\xf4\x6e\xda\x85\xe6",
+       "\x82\xba\x2b\x8d\x65\xe1\x4f\xda\xc5\x1f\x60\x9f\x88\x88\x81\xdb\x80\x70\xa0\xb7\x0d\x78\x92\xc0\x09\xa1\xad\x28",
+       220 },
+      { GCRY_MD_SHA3_224,
+       "\x7f\xdf\xad\xcc\x9d\x29\xba\xd2\x3a\xe0\x38\xc6\xc6\x5c\xda\x1a\xef\x75\x72\x21\xb8\x87\x2e\xd3\xd7\x5f\xf8\xdf\x7d\xa0\x62\x7d\x26\x6e\x22\x4e\x81\x2c\x39\xf7\x98\x3e\x45\x58\xbf\xd0\xa1\xf2\xbe\xf3\xfe\xb5\x6b\xa0\x91\x20\xef\x76\x29\x17\xb9\xc0\x93\x86\x79\x48\x54\x7a\xee\x98\x60\x0d\x10\xd8\x7b\x20\x10\x68\x78\xa8\xd2\x2c\x64\x37\x8b\xf6\x34\xf7\xf7\x59\x00\xc0\x39\x86\xb0\x77\xb0\xbf\x8b\x74\x0a\x82\x44\x7b\x61\xb9\x9f\xee\x53\x76\xc5\xeb\x66\x80\xec\x9e\x30\x88\xf0\xbd\xd0\xc5\x68\x83\x41\x3d\x60\xc1\x35\x7d\x3c\x81\x19\x50\xe5\x89\x0e\x76\x00\x10\x3c\x91\x63\x41\xb8\x0c\x74\x3c\x6a\x85\x2b\x7b\x4f\xb6\x0c\x3b\xa2\x1f\x3b\xc1\x5b\x83\x82\x43\x7a\x68\x45\x47\x79\xcf\x3c\xd7\xf9\xf9\x0c\xcc\x8e\xf2\x8d\x0b\x70\x65\x35\xb1\xe4\x10\x8e\xb5\x62\x7b\xb4\x5d\x71\x9c\xb0\x46\x83\x9a\xee\x31\x1c\xa1\xab\xdc\x83\x19\xe0\x50\xd6\x79\x72\xcb\x35\xa6\xb1\x60\x1b\x25\xdb\xf4\x87",
+       "\xf8\xe5\x21\x8d\xb0\x87\xd3\x8b\x1c\x77\x32\x47\xfc\x22\x70\x4c\x1f\xbd\xb2\x0b\x15\x00\xe2\x6a\xfa\x0b\x75\x72",
+       221 },
+      { GCRY_MD_SHA3_224,
+       "\x98\x86\x38\x21\x9f\xd3\x09\x54\x21\xf8\x26\xf5\x6e\x4f\x09\xe3\x56\x29\x6b\x62\x8c\x3c\xe6\x93\x0c\x9f\x2e\x75\x8f\xd1\xa8\x0c\x82\x73\xf2\xf6\x1e\x4d\xaa\xe6\x5c\x4f\x11\x0d\x3e\x7c\xa0\x96\x5a\xc7\xd2\x4e\x34\xc0\xdc\x4b\xa2\xd6\xff\x0b\xf5\xbb\xe9\x3b\x35\x85\xf3\x54\xd7\x54\x3c\xb5\x42\xa1\xaa\x54\x67\x4d\x37\x50\x77\xf2\xd3\x60\xa8\xf4\xd4\x2f\x3d\xb1\x31\xc3\xb7\xab\x73\x06\x26\x7b\xa1\x07\x65\x98\x64\xa9\x0c\x8c\x90\x94\x60\xa7\x36\x21\xd1\xf5\xd9\xd3\xfd\x95\xbe\xb1\x9b\x23\xdb\x1c\xb6\xc0\xd0\xfb\xa9\x1d\x36\x89\x15\x29\xb8\xbd\x82\x63\xca\xa1\xba\xb5\x6a\x4a\xff\xae\xd4\x49\x62\xdf\x09\x6d\x8d\x5b\x1e\xb8\x45\xef\x31\x18\x8b\x3e\x10\xf1\xaf\x81\x1a\x13\xf1\x56\xbe\xb7\xa2\x88\xaa\xe5\x93\xeb\xd1\x47\x1b\x62\x4a\xa1\xa7\xc6\xad\xf0\x1e\x22\x00\xb3\xd7\x2d\x88\xa3\xae\xd3\x10\x0c\x88\x23\x1e\x41\xef\xc3\x76\x90\x6f\x0b\x58\x0d\xc8\x95\xf0\x80\xfd\xa5\x74\x1d\xb1\xcb",
+       "\xfa\x60\x2f\x09\xb2\x8f\x86\x79\x77\x1e\x9c\x39\x66\x03\x2b\x80\xfa\x2f\x0f\x33\xe8\x4f\x3e\xd6\x9b\xe7\xae\x9c",
+       222 },
+      { GCRY_MD_SHA3_224,
+       "\x5a\xab\x62\x75\x6d\x30\x7a\x66\x9d\x14\x6a\xba\x98\x8d\x90\x74\xc5\xa1\x59\xb3\xde\x85\x15\x1a\x81\x9b\x11\x7c\xa1\xff\x65\x97\xf6\x15\x6e\x80\xfd\xd2\x8c\x9c\x31\x76\x83\x51\x64\xd3\x7d\xa7\xda\x11\xd9\x4e\x09\xad\xd7\x70\xb6\x8a\x6e\x08\x1c\xd2\x2c\xa0\xc0\x04\xbf\xe7\xcd\x28\x3b\xf4\x3a\x58\x8d\xa9\x1f\x50\x9b\x27\xa6\x58\x4c\x47\x4a\x4a\x2f\x3e\xe0\xf1\xf5\x64\x47\x37\x92\x40\xa5\xab\x1f\xb7\x7f\xdc\xa4\x9b\x30\x5f\x07\xba\x86\xb6\x27\x56\xfb\x9e\xfb\x4f\xc2\x25\xc8\x68\x45\xf0\x26\xea\x54\x20\x76\xb9\x1a\x0b\xc2\xcd\xd1\x36\xe1\x22\xc6\x59\xbe\x25\x9d\x98\xe5\x84\x1d\xf4\xc2\xf6\x03\x30\xd4\xd8\xcd\xee\x7b\xf1\xa0\xa2\x44\x52\x4e\xec\xc6\x8f\xf2\xae\xf5\xbf\x00\x69\xc9\xe8\x7a\x11\xc6\xe5\x19\xde\x1a\x40\x62\xa1\x0c\x83\x83\x73\x88\xf7\xef\x58\x59\x8a\x38\x46\xf4\x9d\x49\x96\x82\xb6\x83\xc4\xa0\x62\xb4\x21\x59\x4f\xaf\xbc\x13\x83\xc9\x43\xba\x83\xbd\xef\x51\x5e\xfc\xf1\x0d",
+       "\xc8\xd7\x56\x88\x89\xdd\x6f\xcb\xc3\xb8\x87\x4e\xd7\x90\x51\x87\x5d\x3c\xe2\x91\x02\xdf\x0c\x5d\xac\x8a\xeb\x8a",
+       223 },
+      { GCRY_MD_SHA3_224,
+       "\x47\xb8\x21\x6a\xa0\xfb\xb5\xd6\x79\x66\xf2\xe8\x2c\x17\xc0\x7a\xa2\xd6\x32\x7e\x96\xfc\xd8\x3e\x3d\xe7\x33\x36\x89\xf3\xee\x79\x99\x4a\x1b\xf4\x50\x82\xc4\xd7\x25\xed\x8d\x41\x20\x5c\xb5\xbc\xdf\x5c\x34\x1f\x77\xfa\xcb\x1d\xa4\x6a\x5b\x9b\x2c\xbc\x49\xea\xdf\x78\x6b\xcd\x88\x1f\x37\x1a\x95\xfa\x17\xdf\x73\xf6\x06\x51\x9a\xea\x0f\xf7\x9d\x5a\x11\x42\x7b\x98\xee\x7f\x13\xa5\xc0\x06\x37\xe2\x85\x41\x34\x69\x10\x59\x83\x91\x21\xfe\xa9\xab\xe2\xcd\x1b\xcb\xbb\xf2\x7c\x74\xca\xf3\x67\x8e\x05\xbf\xb1\xc9\x49\x89\x7e\xa0\x1f\x56\xff\xa4\xda\xfb\xe8\x64\x46\x11\x68\x5c\x61\x7a\x32\x06\xc7\xa7\x03\x6e\x4a\xc8\x16\x79\x9f\x69\x3d\xaf\xe7\xf1\x9f\x30\x3c\xe4\xeb\xa0\x9d\x21\xe0\x36\x10\x20\x1b\xfc\x66\x5b\x72\x40\x0a\x54\x7a\x1e\x00\xfa\x9b\x7a\xd8\xd8\x4f\x84\xb3\x4a\xef\x11\x85\x15\xe7\x4d\xef\x11\xb9\x18\x8b\xd1\xe1\xf9\x7d\x9a\x12\xc3\x01\x32\xec\x28\x06\x33\x9b\xda\xda\xcd\xa2\xfd\x8b\x78",
+       "\xd8\x3b\x06\xd5\x09\xd3\x32\x16\x40\x87\xc0\xc3\xfa\x50\xb2\x26\x4c\xb2\x7f\x66\xd7\x46\xb0\x47\x01\x66\xcb\xc2",
+       224 },
+      { GCRY_MD_SHA3_224,
+       "\x8c\xff\x1f\x67\xfe\x53\xc0\x98\x89\x6d\x91\x36\x38\x9b\xd8\x88\x18\x16\xcc\xab\x34\x86\x2b\xb6\x7a\x65\x6e\x3d\x98\x89\x6f\x3c\xe6\xff\xd4\xda\x73\x97\x58\x09\xfc\xdf\x96\x66\x76\x0d\x6e\x56\x1c\x55\x23\x8b\x20\x5d\x80\x49\xc1\xce\xde\xef\x37\x4d\x17\x35\xda\xa5\x33\x14\x7b\xfa\x96\x0b\x2c\xce\x4a\x4f\x25\x41\x76\xbb\x4d\x1b\xd1\xe8\x96\x54\x43\x2b\x8d\xbe\x1a\x13\x5c\x42\x11\x5b\x39\x4b\x02\x48\x56\xa2\xa8\x3d\xc8\x5d\x67\x82\xbe\x4b\x44\x42\x39\x56\x7c\xce\xc4\xb1\x84\xd4\x54\x8e\xae\x3f\xf6\xa1\x92\xf3\x43\x29\x2b\xa2\xe3\x2a\x0f\x26\x7f\x31\xcc\x26\x71\x9e\xb8\x52\x45\xd4\x15\xfb\x89\x7a\xc2\xda\x43\x3e\xe9\x1a\x99\x42\x4c\x9d\x7f\x17\x66\xa4\x41\x71\xd1\x65\x10\x01\xc3\x8f\xc7\x92\x94\xac\xcc\x68\xce\xb5\x66\x5d\x36\x21\x84\x54\xd3\xba\x16\x9a\xe0\x58\xa8\x31\x33\x8c\x17\x74\x36\x03\xf8\x1e\xe1\x73\xbf\xc0\x92\x74\x64\xf9\xbd\x72\x8d\xee\x94\xc6\xae\xab\x7a\xae\x6e\xe3\xa6\x27\xe8",
+       "\x38\x61\x47\xb0\xcf\x23\x65\x34\x6e\x98\x46\xd3\xf3\xa7\xdc\xee\xb6\xe3\x66\x5b\xa7\xd1\x59\x3c\x08\xb2\xb5\x82",
+       225 },
+      { GCRY_MD_SHA3_224,
+       "\xea\xcd\x07\x97\x1c\xff\x9b\x99\x39\x90\x3f\x8c\x1d\x8c\xbb\x5d\x4d\xb1\xb5\x48\xa8\x5d\x04\xe0\x37\x51\x4a\x58\x36\x04\xe7\x87\xf3\x29\x92\xbf\x21\x11\xb9\x7a\xc5\xe8\xa9\x38\x23\x35\x52\x73\x13\x21\x52\x2a\xb5\xe8\x58\x35\x61\x26\x0b\x7d\x13\xeb\xee\xf7\x85\xb2\x3a\x41\xfd\x85\x76\xa6\xda\x76\x4a\x8e\xd6\xd8\x22\xd4\x95\x7a\x54\x5d\x52\x44\x75\x6c\x18\xaa\x80\xe1\xaa\xd4\xd1\xf9\xc2\x0d\x25\x9d\xee\x17\x11\xe2\xcc\x8f\xd0\x13\x16\x9f\xb7\xcc\x4c\xe3\x8b\x36\x2f\x8e\x09\x36\xae\x91\x98\xb7\xe8\x38\xdc\xea\x4f\x7a\x5b\x94\x29\xbb\x3f\x6b\xbc\xf2\xdc\x92\x56\x5e\x36\x76\xc1\xc5\xe6\xeb\x3d\xd2\xa0\xf8\x6a\xa2\x3e\xdd\x3d\x08\x91\xf1\x97\x44\x76\x92\x79\x4b\x3d\xfa\x26\x96\x11\xad\x97\xf7\x2b\x79\x56\x02\xb4\xfd\xb1\x98\xf3\xfd\x3e\xb4\x1b\x41\x50\x64\x25\x6e\x34\x5e\x8d\x8c\x51\xc5\x55\xdc\x8a\x21\x90\x4a\x9b\x0f\x1a\xd0\xef\xfa\xb7\x78\x6a\xac\x2d\xa3\xb1\x96\x50\x7e\x9f\x33\xca\x35\x64\x27",
+       "\xa6\x9c\x0c\x18\xa7\x12\x40\x8d\x8f\xa2\x38\x9a\xca\xbc\x3b\xf6\xf6\x41\x2f\x69\x78\x3e\x9f\x37\x96\x0d\x0b\x56",
+       226 },
+      { GCRY_MD_SHA3_224,
+       "\x23\xac\x4e\x9a\x42\xc6\xef\x45\xc3\x33\x6c\xe6\xdf\xc2\xff\x7d\xe8\x88\x4c\xd2\x3d\xc9\x12\xfe\xf0\xf7\x75\x6c\x09\xd3\x35\xc1\x89\xf3\xad\x3a\x23\x69\x7a\xbd\xa8\x51\xa8\x18\x81\xa0\xc8\xcc\xaf\xc9\x80\xab\x2c\x70\x25\x64\xc2\xbe\x15\xfe\x4c\x4b\x9f\x10\xdf\xb2\x24\x8d\x0d\x0c\xb2\xe2\x88\x7f\xd4\x59\x8a\x1d\x4a\xcd\xa8\x97\x94\x4a\x2f\xfc\x58\x0f\xf9\x27\x19\xc9\x5c\xf2\xaa\x42\xdc\x58\x46\x74\xcb\x5a\x9b\xc5\x76\x5b\x9d\x6d\xdf\x57\x89\x79\x1d\x15\xf8\xdd\x92\x5a\xa1\x2b\xff\xaf\xbc\xe6\x08\x27\xb4\x90\xbb\x7d\xf3\xdd\xa6\xf2\xa1\x43\xc8\xbf\x96\xab\xc9\x03\xd8\x3d\x59\xa7\x91\xe2\xd6\x28\x14\xa8\x9b\x80\x80\xa2\x80\x60\x56\x8c\xf2\x4a\x80\xae\x61\x17\x9f\xe8\x4e\x0f\xfa\xd0\x03\x88\x17\x8c\xb6\xa6\x17\xd3\x7e\xfd\x54\xcc\x01\x97\x0a\x4a\x41\xd1\xa8\xd3\xdd\xce\x46\xed\xbb\xa4\xab\x7c\x90\xad\x56\x53\x98\xd3\x76\xf4\x31\x18\x9c\xe8\xc1\xc3\x3e\x13\x2f\xea\xe6\xa8\xcd\x17\xa6\x1c\x63\x00\x12",
+       "\x06\x99\xfd\x35\x41\x6d\x83\x79\x1d\xc8\xe6\x56\xf2\x27\x18\xb0\x9d\xa9\xe3\xdf\x6e\x7f\x37\xa2\x50\xe2\x2d\xcd",
+       227 },
+      { GCRY_MD_SHA3_224,
+       "\x01\x72\xdf\x73\x22\x82\xc9\xd4\x88\x66\x9c\x35\x8e\x34\x92\x26\x0c\xbe\x91\xc9\x5c\xfb\xc1\xe3\xfe\xa6\xc4\xb0\xec\x12\x9b\x45\xf2\x42\xac\xe0\x9f\x15\x2f\xc6\x23\x4e\x1b\xee\x8a\xab\x8c\xd5\x6e\x8b\x48\x6e\x1d\xcb\xa9\xc0\x54\x07\xc2\xf9\x5d\xa8\xd8\xf1\xc0\xaf\x78\xee\x2e\xd8\x2a\x3a\x79\xec\x0c\xb0\x70\x93\x96\xee\x62\xaa\xdb\x84\xf8\xa4\xee\x8a\x7c\xcc\xa3\xc1\xee\x84\xe3\x02\xa0\x9e\xa8\x02\x20\x4a\xfe\xcf\x04\x09\x7e\x67\xd0\xf8\xe8\xa9\xd2\x65\x11\x26\xc0\xa5\x98\xa3\x70\x81\xe4\x2d\x16\x8b\x0a\xe8\xa7\x19\x51\xc5\x24\x25\x9e\x4e\x20\x54\xe5\x35\xb7\x79\x67\x9b\xda\xde\x56\x6f\xe5\x57\x00\x85\x86\x18\xe6\x26\xb4\xa0\xfa\xf8\x95\xbc\xce\x90\x11\x50\x4a\x49\xe0\x5f\xd5\x61\x27\xea\xe3\xd1\xf8\x91\x7a\xfb\x54\x8e\xca\xda\xbd\xa1\x02\x01\x11\xfe\xc9\x31\x4c\x41\x34\x98\xa3\x60\xb0\x86\x40\x54\x9a\x22\xcb\x23\xc7\x31\xac\xe7\x43\x25\x2a\x82\x27\xa0\xd2\x68\x9d\x4c\x60\x01\x60\x66\x78\xdf\xb9\x21",
+       "\xbf\x6a\x35\x98\xa1\x5e\x28\xb7\x76\x22\x9f\x4d\x12\x4d\x40\x3f\xad\x9d\x0f\xbc\x2b\x76\x68\xc9\x5d\x8b\x50\x46",
+       228 },
+      { GCRY_MD_SHA3_224,
+       "\x38\x75\xb9\x24\x0c\xf3\xe0\xa8\xb5\x9c\x65\x85\x40\xf2\x6a\x70\x1c\xf1\x88\x49\x6e\x2c\x21\x74\x78\x8b\x12\x6f\xd2\x94\x02\xd6\xa7\x54\x53\xba\x06\x35\x28\x4d\x08\x83\x5f\x40\x05\x1a\x2a\x96\x83\xdc\x92\xaf\xb9\x38\x37\x19\x19\x12\x31\x17\x03\x79\xba\x6f\x4a\xdc\x81\x6f\xec\xbb\x0f\x9c\x44\x6b\x78\x5b\xf5\x20\x79\x68\x41\xe5\x88\x78\xb7\x3c\x58\xd3\xeb\xb0\x97\xce\x47\x61\xfd\xea\xbe\x15\xde\x2f\x31\x9d\xfb\xaf\x17\x42\xcd\xeb\x38\x95\x59\xc7\x88\x13\x1a\x67\x93\xe1\x93\x85\x66\x61\x37\x6c\x81\xce\x95\x68\xda\x19\xaa\x69\x25\xb4\x7f\xfd\x77\xa4\x3c\x7a\x0e\x75\x8c\x37\xd6\x92\x54\x90\x9f\xf0\xfb\xd4\x15\xef\x8e\xb9\x37\xbc\xd4\x9f\x91\x46\x8b\x49\x97\x4c\x07\xdc\x81\x9a\xbd\x67\x39\x5d\xb0\xe0\x58\x74\xff\x83\xdd\xda\xb8\x95\x34\x4a\xbd\x0e\x71\x11\xb2\xdf\x9e\x58\xd7\x6d\x85\xad\x98\x10\x6b\x36\x29\x58\x26\xbe\x04\xd4\x35\x61\x55\x95\x60\x5e\x4b\x4b\xb8\x24\xb3\x3c\x4a\xfe\xb5\xe7\xbb\x0d\x19\xf9\x09",
+       "\x56\xf8\xe9\xf6\x9a\x39\x9e\x52\x89\x96\xc4\x63\xd6\x5f\x20\xdb\x41\x40\x65\x33\xc7\xdf\x2b\xa1\xaf\xa2\x49\x4a",
+       229 },
+      { GCRY_MD_SHA3_224,
+       "\x74\x7c\xc1\xa5\x9f\xef\xba\x94\xa9\xc7\x5b\xa8\x66\xc3\x0d\xc5\xc1\xcb\x0c\x0f\x8e\x93\x61\xd9\x84\x84\x95\x6d\xd5\xd1\xa4\x0f\x61\x84\xaf\xbe\x3d\xac\x9f\x76\x02\x8d\x1c\xae\xcc\xfb\xf6\x91\x99\xc6\xce\x2b\x4c\x09\x2a\x3f\x4d\x2a\x56\xfe\x5a\x33\xa0\x07\x57\xf4\xd7\xde\xe5\xdf\xb0\x52\x43\x11\xa9\x7a\xe0\x66\x8a\x47\x97\x1b\x95\x76\x6e\x2f\x6d\xd4\x8c\x3f\x57\x84\x1f\x91\xf0\x4a\x00\xad\x5e\xa7\x0f\x2d\x47\x9a\x26\x20\xdc\x5c\xd7\x8e\xaa\xb3\xa3\xb0\x11\x71\x9b\x7e\x78\xd1\x9d\xdf\x70\xd9\x42\x37\x98\xaf\x77\x51\x7e\xbc\x55\x39\x2f\xcd\x01\xfc\x60\x0d\x8d\x46\x6b\x9e\x7a\x7a\x85\xbf\x33\xf9\xcc\x54\x19\xe9\xbd\x87\x4d\xdf\xd6\x09\x81\x15\x0d\xda\xf8\xd7\xfe\xba\xa4\x37\x4f\x08\x72\xa5\x62\x8d\x31\x80\x00\x31\x1e\x2f\x56\x55\x36\x5a\xd4\xd4\x07\xc2\x0e\x5c\x04\xdf\x17\xa2\x22\xe7\xde\xec\x79\xc5\xab\x11\x16\xd8\x57\x2f\x91\xcd\x06\xe1\xcc\xc7\xce\xd5\x37\x36\xfc\x86\x7f\xd4\x9e\xce\xbe\x6b\xf8\x08\x2e\x8a",
+       "\x99\x04\xd5\x7d\xed\xb9\x35\x42\x7f\x23\x5a\x00\x09\x61\x22\x35\xf1\x4e\x94\x26\xb2\x18\xe0\x28\xf8\x7b\x3c\x0c",
+       230 },
+      { GCRY_MD_SHA3_224,
+       "\x57\xaf\x97\x1f\xcc\xae\xc9\x74\x35\xdc\x2e\xc9\xef\x04\x29\xbc\xed\xc6\xb6\x47\x72\x9e\xa1\x68\x85\x8a\x6e\x49\xac\x10\x71\xe7\x06\xf4\xa5\xa6\x45\xca\x14\xe8\xc7\x74\x6d\x65\x51\x16\x20\x68\x2c\x90\x6c\x8b\x86\xec\x90\x1f\x3d\xde\xd4\x16\x7b\x3f\x00\xb0\x6c\xbf\xac\x6a\xee\x37\x28\x05\x1b\x3e\x5f\xf1\x0b\x4f\x9e\xd8\xbd\x0b\x8d\xa9\x43\x03\xc8\x33\x75\x5b\x3c\xa3\xae\xdd\xf0\xb5\x4b\xc8\xd6\x63\x21\x38\xb5\xd2\x5b\xab\x03\xd1\x7b\x34\x58\xa9\xd7\x82\x10\x80\x06\xf5\xbb\x7d\xe7\x5b\x5c\x0b\xa8\x54\xb4\x23\xd8\xbb\x80\x1e\x70\x1e\x99\xdc\x4f\xea\xad\x59\xbc\x1c\x71\x12\x45\x3b\x04\xd3\x3e\xa3\x63\x56\x39\xfb\x80\x2c\x73\xc2\xb7\x1d\x58\xa5\x6b\xbd\x67\x1b\x18\xfe\x34\xed\x2e\x3d\xca\x38\x82\x7d\x63\xfd\xb1\xd4\xfb\x32\x85\x40\x50\x04\xb2\xb3\xe2\x60\x81\xa8\xff\x08\xcd\x6d\x2b\x08\xf8\xe7\xb7\xe9\x0a\x2a\xb1\xed\x7a\x41\xb1\xd0\x12\x85\x22\xc2\xf8\xbf\xf5\x6a\x7f\xe6\x79\x69\x42\x2c\xe8\x39\xa9\xd4\x60\x8f\x03",
+       "\xff\x70\x13\x67\x9a\xb2\xbe\x65\xae\xdd\x09\x73\x9f\x56\xf8\xdd\x00\x72\x73\x8b\x86\xe7\x1a\x24\x70\x47\x6c\x8c",
+       231 },
+      { GCRY_MD_SHA3_224,
+       "\x04\xe1\x6d\xed\xc1\x22\x79\x02\xba\xaf\x33\x2d\x3d\x08\x92\x36\x01\xbd\xd6\x4f\x57\x3f\xaa\x1b\xb7\x20\x19\x18\xcf\xe1\x6b\x1e\x10\x15\x1d\xae\x87\x5d\xa0\xc0\xd6\x3c\x59\xc3\xdd\x05\x0c\x4c\x6a\x87\x40\x11\xb0\x18\x42\x1a\xfc\x46\x23\xab\x03\x81\x83\x1b\x2d\xa2\xa8\xba\x42\xc9\x6e\x4f\x70\x86\x4a\xc4\x4e\x10\x6f\x94\x31\x10\x51\xe7\x4c\x77\xc1\x29\x1b\xf5\xdb\x95\x39\xe6\x95\x67\xbf\x6a\x11\xcf\x69\x32\xbb\xba\xd3\x3f\x89\x46\xbf\x58\x14\xc0\x66\xd8\x51\x63\x3d\x1a\x51\x35\x10\x03\x9b\x34\x99\x39\xbf\xd4\x2b\x85\x8c\x21\x82\x7c\x8f\xf0\x5f\x1d\x09\xb1\xb0\x76\x5d\xc7\x8a\x13\x5b\x5c\xa4\xdf\xba\x08\x01\xbc\xad\xdf\xa1\x75\x62\x3c\x8b\x64\x7e\xac\xfb\x44\x44\xb8\x5a\x44\xf7\x38\x90\x60\x7d\x06\xd5\x07\xa4\xf8\x39\x36\x58\x78\x86\x69\xf6\xef\x4d\xeb\x58\xd0\x8c\x50\xca\x07\x56\xd5\xe2\xf4\x9d\x1a\x7a\xd7\x3e\x0f\x0b\x3d\x3b\x5f\x09\x0a\xcf\x62\x2b\x18\x78\xc5\x91\x33\xe4\xa8\x48\xe0\x51\x53\x59\x2e\xa8\x1c\x6f\xbf",
+       "\x9d\xfb\x6a\x85\x4a\x33\x91\x4e\xae\x15\x96\xdc\xd2\xbe\x36\x3a\x96\xe7\xe0\x88\xbe\x52\x0f\x60\xe5\xa6\x5c\x7f",
+       232 },
+      { GCRY_MD_SHA3_224,
+       "\x7c\x81\x5c\x38\x4e\xee\x0f\x28\x8e\xce\x27\xcc\xed\x52\xa0\x16\x03\x12\x7b\x07\x9c\x00\x73\x78\xbc\x5d\x1e\x6c\x5e\x9e\x6d\x1c\x73\x57\x23\xac\xbb\xd5\x80\x1a\xc4\x98\x54\xb2\xb5\x69\xd4\x47\x2d\x33\xf4\x0b\xbb\x88\x82\x95\x62\x45\xc3\x66\xdc\x35\x82\xd7\x16\x96\xa9\x7a\x4e\x19\x55\x7e\x41\xe5\x4d\xee\x48\x2a\x14\x22\x90\x05\xf9\x3a\xfd\x2c\x4a\x7d\x86\x14\xd1\x0a\x97\xa9\xdf\xa0\x7f\x7c\xd9\x46\xfa\x45\x26\x30\x63\xdd\xd2\x9d\xb8\xf9\xe3\x4d\xb6\x0d\xaa\x32\x68\x4f\x00\x72\xea\x2a\x94\x26\xec\xeb\xfa\x52\x39\xfb\x67\xf2\x9c\x18\xcb\xaa\x2a\xf6\xed\x4b\xf4\x28\x39\x36\x82\x3a\xc1\x79\x01\x64\xfe\xc5\x45\x7a\x9c\xba\x7c\x76\x7c\xa5\x93\x92\xd9\x4c\xab\x74\x48\xf5\x0e\xb3\x4e\x9a\x93\xa8\x00\x27\x47\x1c\xe5\x97\x36\xf0\x99\xc8\x86\xde\xa1\xab\x4c\xba\x4d\x89\xf5\xfc\x7a\xe2\xf2\x1c\xcd\x27\xf6\x11\xec\xa4\x62\x6b\x2d\x08\xdc\x22\x38\x2e\x92\xc1\xef\xb2\xf6\xaf\xdc\x8f\xdc\x3d\x21\x72\x60\x4f\x50\x35\xc4\x6b\x81\x97\xd3",
+       "\xc2\x7e\x80\xc3\x73\xb2\x16\x70\x3d\x3d\x9e\x67\x22\x3c\xfc\x54\x97\xc3\xe7\x44\x55\xd4\x9b\x04\x9a\xe3\xf5\xf4",
+       233 },
+      { GCRY_MD_SHA3_224,
+       "\xe2\x9d\x50\x51\x58\xdb\xdd\x93\x7d\x9e\x3d\x21\x45\x65\x8e\xe6\xf5\x99\x2a\x2f\xc7\x90\xf4\xf6\x08\xd9\xcd\xb4\x4a\x09\x1d\x5b\x94\xb8\x8e\x81\xfa\xc4\xfd\xf5\xc4\x94\x42\xf1\x3b\x91\x1c\x55\x88\x64\x69\x62\x95\x51\x18\x9e\xaf\xf6\x24\x88\xf1\xa4\x79\xb7\xdb\x11\xa1\x56\x0e\x19\x8d\xdc\xcc\xcf\x50\x15\x90\x93\x42\x5f\xf7\xf1\xcb\x8d\x1d\x12\x46\xd0\x97\x87\x64\x08\x7d\x6b\xac\x25\x70\x26\xb0\x90\xef\xae\x8c\xec\x5f\x22\xb6\xf2\x1c\x59\xac\xe1\xac\x73\x86\xf5\xb8\x83\x7c\xa6\xa1\x2b\x6f\xbf\x55\x34\xdd\x05\x60\xef\x05\xca\x78\x10\x4d\x3b\x94\x3d\xdb\x22\x0f\xea\xec\x89\xaa\x5e\x69\x2a\x00\xf8\x22\xa2\xab\x9a\x2f\xe6\x03\x50\xd7\x5e\x7b\xe1\x6f\xf2\x52\x6d\xc6\x43\x87\x25\x02\xd0\x1f\x42\xf1\x88\xab\xed\x0a\x6e\x9a\x6f\x5f\xd0\xd1\xce\x7d\x57\x55\xc9\xff\xa6\x6b\x0a\xf0\xb2\x0b\xd8\x06\xf0\x8e\x06\x15\x66\x90\xd8\x1a\xc8\x11\x77\x8c\xa3\xda\xc2\xc2\x49\xb9\x60\x02\x01\x7f\xce\x93\xe5\x07\xe3\xb9\x53\xac\xf9\x99\x64\xb8\x47",
+       "\x3a\x18\x96\x30\xf5\x3c\x56\x7b\x1c\x18\x25\x79\x4d\x50\xde\xf9\x01\xa0\x0e\x7f\x37\x28\xec\xf2\xbb\xe0\x0d\x90",
+       234 },
+      { GCRY_MD_SHA3_224,
+       "\xd8\x55\x88\x69\x6f\x57\x6e\x65\xec\xa0\x15\x5f\x39\x5f\x0c\xfa\xcd\x83\xf3\x6a\x99\x11\x1e\xd5\x76\x8d\xf2\xd1\x16\xd2\x12\x1e\x32\x35\x7b\xa4\xf5\x4e\xde\x92\x7f\x18\x9f\x29\x7d\x3a\x97\xfa\xd4\xe9\xa0\xf5\xb4\x1d\x8d\x89\xdd\x7f\xe2\x01\x56\x79\x9c\x2b\x7b\x6b\xf9\xc9\x57\xba\x0d\x67\x63\xf5\xc3\xbc\x51\x29\x74\x7b\xbb\x53\x65\x2b\x49\x29\x0c\xff\x1c\x87\xe2\xcd\xf2\xc4\xb9\x5d\x8a\xae\xe0\x9b\xc8\xfb\xfa\x68\x83\xe6\x2d\x23\x78\x85\x81\x04\x91\xbf\xc1\x01\xf1\xd8\xc6\x36\xe3\xd0\xed\xe8\x38\xad\x05\xc2\x07\xa3\xdf\x4f\xad\x76\x45\x29\x79\xeb\x99\xf2\x9a\xfa\xec\xed\xd1\xc6\x3b\x8d\x36\xcf\x37\x84\x54\xa1\xbb\x67\xa7\x41\xc7\x7a\xc6\xb6\xb3\xf9\x5f\x4f\x02\xb6\x4d\xab\xc1\x54\x38\x61\x3e\xa4\x97\x50\xdf\x42\xee\x90\x10\x1f\x11\x5a\xa9\xab\xb9\xff\x64\x32\x4d\xde\x9d\xab\xbb\x01\x05\x4e\x1b\xd6\xb4\xbc\xdc\x79\x30\xa4\x4c\x23\x00\xd8\x7c\xa7\x8c\x06\x92\x4d\x03\x23\xad\x78\x87\xe4\x6c\x90\xe8\xc4\xd1\x00\xac\xd9\xee\xd2\x1e",
+       "\x25\x85\xbd\x8d\x91\x58\xd6\x95\x2b\xee\x95\xb0\x04\xf5\xfe\xd7\x0f\xaf\x06\x1b\x68\xab\x2d\x6a\x40\x46\x9b\xe7",
+       235 },
+      { GCRY_MD_SHA3_224,
+       "\x3a\x12\xf8\x50\x8b\x40\xc3\x2c\x74\x49\x2b\x66\x32\x33\x75\xdc\xfe\x49\x18\x4c\x78\xf7\x31\x79\xf3\x31\x4b\x79\xe6\x33\x76\xb8\xac\x68\x3f\x5a\x51\xf1\x53\x4b\xd7\x29\xb0\x2b\x04\xd0\x02\xf5\x5c\xbd\x8e\x8f\xc9\xb5\xec\x1e\xa6\xbb\xe6\xa0\xd0\xe7\x43\x15\x18\xe6\xba\x45\xd1\x24\x03\x5f\x9d\x3d\xce\x0a\x8b\xb7\xbf\x14\x30\xa9\xf6\x57\xe0\xb4\xea\x9f\x20\xeb\x20\xc7\x86\xa5\x81\x81\xa1\xe2\x0a\x96\xf1\x62\x8f\x87\x28\xa1\x3b\xdf\x7a\x4b\x4b\x32\xfc\x8a\xa7\x05\x4c\xc4\x88\x1a\xe7\xfa\x19\xaf\xa6\x5c\x6c\x3e\xe1\xb3\xad\xe3\x19\x2a\xf4\x20\x54\xa8\xa9\x11\xb8\xec\x18\x26\x86\x5d\x46\xd9\x3f\x1e\x7c\x5e\x2b\x78\x13\xc9\x2a\x50\x6e\x53\x88\x6f\x3d\x47\x01\xbb\x93\xd2\xa6\x81\xad\x10\x9c\x84\x59\x04\xbb\x86\x1a\xf8\xaf\x06\x46\xb6\xe3\x99\xb3\x8b\x61\x40\x51\xd3\x4f\x68\x42\x56\x3a\x0f\x37\xec\x00\xcb\x3d\x86\x5f\xc5\xd7\x46\xc4\x98\x7d\xe2\xa6\x50\x71\x10\x08\x83\xa2\xa9\xc7\xa2\xbf\xe1\xe2\xdd\x60\x3d\x9e\xa2\x4d\xc7\xc5\xfd\x06\xbe",
+       "\x7e\x64\xf3\xc5\x89\x5d\x05\x86\xcc\x5b\x54\x3b\x27\xde\x1b\x66\xa9\x35\x17\x1e\x2e\x7f\x3c\xa4\x8d\xd3\x71\x8e",
+       236 },
+      { GCRY_MD_SHA3_224,
+       "\x18\x61\xed\xce\x46\xfa\x5a\xd1\x7e\x1f\xf1\xde\xae\x08\x4d\xec\x58\x0f\x97\xd0\xa6\x78\x85\xdf\xe8\x34\xb9\xdf\xac\x1a\xe0\x76\x74\x2c\xe9\xe2\x67\x51\x2c\xa5\x1f\x6d\xf5\xa4\x55\xaf\x0c\x5f\xd6\xab\xf9\x4a\xce\xa1\x03\xa3\x37\x0c\x35\x44\x85\xa7\x84\x6f\xb8\x4f\x3a\xc7\xc2\x90\x4b\x5b\x2f\xbf\x22\x70\x02\xce\x51\x21\x33\xbb\x7e\x1c\x4e\x50\x05\x7b\xfd\x1e\x44\xdb\x33\xc7\xcd\xb9\x69\xa9\x9e\x28\x4b\x18\x4f\x50\xa1\x4b\x06\x8a\x1f\xc5\x00\x9d\x9b\x29\x8d\xbe\x92\x23\x95\x72\xa7\x62\x7a\xac\x02\xab\xe8\xf3\xe3\xb4\x73\x41\x7f\x36\xd4\xd2\x50\x5d\x16\xb7\x57\x7f\x45\x26\xc9\xd9\x4a\x27\x0a\x2d\xfe\x45\x0d\x06\xda\x8f\x6f\xa9\x56\x87\x9a\x0a\x55\xcf\xe9\x9e\x74\x2e\xa5\x55\xea\x47\x7b\xa3\xe9\xb4\x4c\xcd\x50\x8c\x37\x54\x23\x61\x1a\xf9\x2e\x55\x34\x5d\xc2\x15\x77\x9b\x2d\x51\x19\xeb\xa4\x9c\x71\xd4\x9b\x9f\xe3\xf1\x56\x9f\xa2\x4e\x5c\xa3\xe3\x32\xd0\x42\x42\x2a\x8b\x81\x58\xd3\xec\x66\xa8\x00\x12\x97\x6f\x31\xff\xdf\x30\x5f\x0c\x9c\x5e",
+       "\x0f\x83\x77\x08\xe0\x10\x37\x5a\xf8\x7f\x75\x41\x5e\xd6\x99\x88\xfe\x60\xeb\x2f\x26\x69\xad\x05\x1f\xa9\x97\x27",
+       237 },
+      { GCRY_MD_SHA3_224,
+       "\x08\xd0\xff\xde\x3a\x6e\x4e\xf6\x56\x08\xea\x67\x2e\x48\x30\xc1\x29\x43\xd7\x18\x7c\xcf\xf0\x8f\x49\x41\xcf\xc1\x3e\x54\x5f\x3b\x9c\x7a\xd5\xee\xbb\xe2\xb0\x16\x42\xb4\x86\xca\xf8\x55\xc2\xc7\x3f\x58\xc1\xe4\xe3\x39\x1d\xa8\xe2\xd6\x3d\x96\xe1\x5f\xd8\x49\x53\xae\x5c\x23\x19\x11\xb0\x0a\xd6\x05\x0c\xd7\xaa\xfd\xaa\xc9\xb0\xf6\x63\xae\x6a\xab\x45\x51\x9d\x0f\x53\x91\xa5\x41\x70\x7d\x47\x90\x34\xe7\x3a\x6a\xd8\x05\xae\x35\x98\x09\x6a\xf0\x78\xf1\x39\x33\x01\x49\x3d\x66\x3d\xd7\x1f\x83\x86\x9c\xa2\x7b\xa5\x08\xb7\xe9\x1e\x81\xe1\x28\xc1\x71\x6d\xc3\xac\xfe\x30\x84\xb2\x20\x1e\x04\xcf\x80\x06\x61\x7e\xec\xf1\xb6\x40\x47\x4a\x5d\x45\xcf\xde\x9f\x4d\x3e\xf9\x2d\x6d\x05\x5b\x90\x98\x92\x19\x4d\x8a\x82\x18\xdb\x6d\x82\x03\xa8\x42\x61\xd2\x00\xd7\x14\x73\xd7\x48\x8f\x34\x27\x41\x6b\x68\x96\xc1\x37\xd4\x55\xf2\x31\x07\x1c\xac\xbc\x86\xe0\x41\x5a\xb8\x8a\xec\x84\x1d\x96\xb7\xb8\xaf\x41\xe0\x5b\xb4\x61\xa4\x06\x45\xbf\x17\x66\x01\xf1\xe7\x60\xde\x5f",
+       "\xc7\x9d\xe3\x97\x78\x59\x38\x10\xc0\x35\x83\xd5\x96\x2b\x36\xe0\x4f\x34\x36\x53\x07\x47\x66\xd1\x57\xa1\x59\x93",
+       238 },
+      { GCRY_MD_SHA3_224,
+       "\xd7\x82\xab\xb7\x2a\x5b\xe3\x39\x27\x57\xbe\x02\xd3\xe4\x5b\xe6\xe2\x09\x9d\x6f\x00\x0d\x04\x2c\x8a\x54\x3f\x50\xed\x6e\xbc\x05\x5a\x7f\x13\x3b\x0d\xd8\xe9\xbc\x34\x85\x36\xed\xca\xae\x2e\x12\xec\x18\xe8\x83\x7d\xf7\xa1\xb3\xc8\x7e\xc4\x6d\x50\xc2\x41\xde\xe8\x20\xfd\x58\x61\x97\x55\x2d\xc2\x0b\xee\xa5\x0f\x44\x5a\x07\xa3\x8f\x17\x68\xa3\x9e\x2b\x2f\xf0\x5d\xdd\xed\xf7\x51\xf1\xde\xf6\x12\xd2\xe4\xd8\x10\xda\xa3\xa0\xcc\x90\x45\x16\xf9\xa4\x3a\xf6\x60\x31\x53\x85\x17\x8a\x52\x9e\x51\xf8\xaa\xe1\x41\x80\x8c\x8b\xc5\xd7\xb6\x0c\xac\x26\xbb\x98\x4a\xc1\x89\x0d\x04\x36\xef\x78\x04\x26\xc5\x47\xe9\x4a\x7b\x08\xf0\x1a\xcb\xfc\x4a\x38\x25\xea\xe0\x4f\x52\x0a\x90\x16\xf2\xfb\x8b\xf5\x16\x5e\xd1\x27\x36\xfc\x71\xe3\x6a\x49\xa7\x36\x14\x73\x9e\xaa\x3e\xc8\x34\x06\x9b\x1b\x40\xf1\x35\x0c\x2b\x3a\xb8\x85\xc0\x2c\x64\x0b\x9f\x76\x86\xed\x5f\x99\x52\x7e\x41\xcf\xcd\x79\x6f\xe4\xc2\x56\xc9\x17\x31\x86\xc2\x26\x16\x9f\xf2\x57\x95\x4e\xbd\xa8\x1c\x0e\x5f\x99",
+       "\x95\xcc\x81\x1c\xc5\x65\x21\xa4\x0e\x3c\xed\x8d\x9a\x23\x0e\x21\x01\xe8\x06\x1f\xb0\x1e\x38\x8b\x99\x64\xbf\x29",
+       239 },
+      { GCRY_MD_SHA3_224,
+       "\x5f\xce\x81\x09\xa3\x58\x57\x0e\x40\x98\x3e\x11\x84\xe5\x41\x83\x3b\xb9\x09\x1e\x28\x0f\x25\x8c\xfb\x14\x43\x87\xb0\x5d\x19\x0e\x43\x1c\xb1\x9b\xaa\x67\x27\x3b\xa0\xc5\x8a\xbe\x91\x30\x8e\x18\x44\xdc\xd0\xb3\x67\x8b\xaa\x42\xf3\x35\xf2\xfa\x05\x26\x7a\x02\x40\xb3\xc7\x18\xa5\x94\x2b\x3b\x3e\x3b\xfa\x98\xa5\x5c\x25\xa1\x46\x6e\x8d\x7a\x60\x37\x22\xcb\x2b\xbf\x03\xaf\xa5\x4c\xd7\x69\xa9\x9f\x31\x07\x35\xee\x5a\x05\xda\xe2\xc2\x2d\x39\x7b\xd9\x56\x35\xf5\x8c\x48\xa6\x7f\x90\xe1\xb7\x3a\xaf\xcd\x3f\x82\x11\x7f\x01\x66\x65\x78\x38\x69\x10\x05\xb1\x8d\xa6\xf3\x41\xd6\xe9\x0f\xc1\xcd\xb3\x52\xb3\x0f\xae\x45\xd3\x48\x29\x4e\x50\x1b\x63\x25\x2d\xe1\x47\x40\xf2\xb8\x5a\xe5\x29\x9d\xde\xc3\x17\x2d\xe8\xb6\xd0\xba\x21\x9a\x20\xa2\x3b\xb5\xe1\x0f\xf4\x34\xd3\x9d\xb3\xf5\x83\x30\x5e\x9f\x5c\x03\x9d\x98\x56\x9e\x37\x7b\x75\xa7\x0a\xb8\x37\xd1\xdf\x26\x9b\x8a\x4b\x56\x6f\x40\xbb\x91\xb5\x77\x45\x5f\xd3\xc3\x56\xc9\x14\xfa\x06\xb9\xa7\xce\x24\xc7\x31\x7a\x17\x2d",
+       "\x2e\xbe\x13\xf1\x2e\xc4\x3e\x3f\x6b\x05\x06\xd7\xab\x21\x6e\x1c\x31\x13\x94\xf7\xc8\x9d\x69\xa9\x20\xcd\x00\xc0",
+       240 },
+      { GCRY_MD_SHA3_224,
+       "\x61\x72\xf1\x97\x1a\x6e\x1e\x4e\x61\x70\xaf\xba\xd9\x5d\x5f\xec\x99\xbf\x69\xb2\x4b\x67\x4b\xc1\x7d\xd7\x80\x11\x61\x5e\x50\x2d\xe6\xf5\x6b\x86\xb1\xa7\x1d\x3f\x43\x48\x08\x72\x18\xac\x7b\x7d\x09\x30\x29\x93\xbe\x27\x2e\x4a\x59\x19\x68\xae\xf1\x8a\x12\x62\xd6\x65\x61\x0d\x10\x70\xee\x91\xcc\x8d\xa3\x6e\x1f\x84\x1a\x69\xa7\xa6\x82\xc5\x80\xe8\x36\x94\x1d\x21\xd9\x09\xa3\xaf\xc1\xf0\xb9\x63\xe1\xca\x5a\xb1\x93\xe1\x24\xa1\xa5\x3d\xf1\xc5\x87\x47\x0e\x58\x81\xfb\x54\xda\xe1\xb0\xd8\x40\xf0\xc8\xf9\xd1\xb0\x4c\x64\x5b\xa1\x04\x1c\x7d\x8d\xbf\x22\x03\x0a\x62\x3a\xa1\x56\x38\xb3\xd9\x9a\x2c\x40\x0f\xf7\x6f\x32\x52\x07\x9a\xf8\x8d\x2b\x37\xf3\x5e\xe6\x6c\x1a\xd7\x80\x1a\x28\xd3\xd3\x88\xac\x45\x0b\x97\xd5\xf0\xf7\x9e\x45\x41\x75\x53\x56\xb3\xb1\xa5\x69\x6b\x02\x3f\x39\xab\x7a\xb5\xf2\x8d\xf4\x20\x29\x36\xbc\x97\x39\x3b\x93\xbc\x91\x5c\xb1\x59\xea\x1b\xd7\xa0\xa4\x14\xcb\x4b\x7a\x1a\xc3\xaf\x68\xf5\x0d\x79\xf0\xc9\xc7\x31\x4e\x75\x0f\x7d\x02\xfa\xa5\x8b\xfa",
+       "\x82\x01\x01\xf5\x43\x5d\x86\xe1\x9b\xec\x58\xed\x0e\x1c\x7e\x63\x0f\xe8\x2d\xd9\x2d\x77\x04\xe4\x14\x80\x2a\x16",
+       241 },
+      { GCRY_MD_SHA3_224,
+       "\x56\x68\xec\xd9\x9d\xfb\xe2\x15\xc4\x11\x83\x98\xac\x9c\x9e\xaf\x1a\x14\x33\xfa\xb4\xcc\xdd\x39\x68\x06\x47\x52\xb6\x25\xea\x94\x47\x31\xf7\x5d\x48\xa2\x7d\x04\x7d\x67\x54\x7f\x14\xdd\x0f\xfa\xa5\x5f\xa5\xe2\x9f\x7a\xf0\xd1\x61\xd8\x5e\xaf\xc4\xf2\x02\x9b\x71\x7c\x91\x8e\xab\x9d\x30\x45\x43\x29\x0b\xdb\xa7\x15\x8b\x68\x02\x0c\x0b\xa4\xe0\x79\xbc\x95\xb5\xbc\x0f\xc0\x44\xa9\x92\xb9\x4b\x4c\xcd\x3b\xd6\x6d\x0e\xab\xb5\xdb\xba\xb9\x04\xd6\x2e\x00\x75\x2c\x4e\x3b\x00\x91\xd7\x73\xbc\xf4\xc1\x4b\x43\x77\xda\x3e\xff\xf8\x24\xb1\xcb\x2f\xa0\x1b\x32\xd1\xe4\x6c\x90\x9e\x62\x6e\xd2\xda\xe9\x20\xf4\xc7\xdb\xeb\x63\x5b\xc7\x54\xfa\xcb\xd8\xd4\x9b\xeb\xa3\xf2\x3c\x1c\x41\xcc\xbf\xcd\x0e\xe0\xc1\x14\xe6\x97\x37\xf5\x59\x7c\x0b\xf1\xd8\x59\xf0\xc7\x67\xe1\x80\x02\xae\x8e\x39\xc2\x62\x61\xff\xde\x29\x20\xd3\xd0\xba\xf0\xe9\x06\x13\x86\x96\xcf\xe5\xb7\xe3\x2b\x60\x0f\x45\xdf\x3a\xaa\x39\x93\x2f\x3a\x7d\xf9\x5b\x60\xfa\x87\x12\xa2\x27\x1f\xca\xf3\x91\x1c\xe7\xb5\x11\xb1",
+       "\xb1\xcf\x54\xf5\x1f\x81\xfd\xb5\xb6\x49\xbb\x61\x15\x12\x61\x49\x29\x62\x78\xbf\xf3\xd5\x39\x5c\xf5\xf1\x12\xd4",
+       242 },
+      { GCRY_MD_SHA3_224,
+       "\x03\xd6\x25\x48\x83\x54\xdf\x30\xe3\xf8\x75\xa6\x8e\xdf\xcf\x34\x0e\x83\x66\xa8\xe1\xab\x67\xf9\xd5\xc5\x48\x6a\x96\x82\x9d\xfa\xc0\x57\x82\x89\x08\x2b\x2a\x62\x11\x7e\x1c\xf4\x18\xb4\x3b\x90\xe0\xad\xc8\x81\xfc\x6a\xe8\x10\x5c\x88\x8e\x9e\xcd\x21\xae\xa1\xc9\xae\x1a\x40\x38\xdf\xd1\x73\x78\xfe\xd7\x1d\x02\xae\x49\x20\x87\xd7\xcd\xcd\x98\xf7\x46\x85\x52\x27\x96\x7c\xb1\xab\x47\x14\x26\x1e\xe3\xbe\xad\x3f\x4d\xb1\x18\x32\x9d\x3e\xbe\xf4\xbc\x48\xa8\x75\xc1\x9b\xa7\x63\x96\x6d\xa0\xeb\xea\x80\x0e\x01\xb2\xf5\x0b\x00\xe9\xdd\x4c\xac\xa6\xdc\xb3\x14\xd0\x01\x84\xef\x71\xea\x23\x91\xd7\x60\xc9\x50\x71\x0d\xb4\xa7\x0f\x92\x12\xff\xc5\x48\x61\xf9\xdc\x75\x2c\xe1\x88\x67\xb8\xad\x0c\x48\xdf\x84\x66\xef\x72\x31\xe7\xac\x56\x7f\x0e\xb5\x50\x99\xe6\x22\xeb\xb8\x6c\xb2\x37\x52\x01\x90\xa6\x1c\x66\xad\x34\xf1\xf4\xe2\x89\xcb\x32\x82\xae\x3e\xaa\xc6\x15\x2e\xd2\x4d\x2c\x92\xba\xe5\xa7\x65\x82\x52\xa5\x3c\x49\xb7\xb0\x2d\xfe\x54\xfd\xb2\xe9\x00\x74\xb6\xcf\x31\x0a\xc6\x61",
+       "\xb6\x02\x72\x2d\x1b\x9f\x31\xb9\xc5\x09\x1e\x0f\xf7\x20\xf1\xd1\xa8\xa5\x1e\xb6\xf9\x5e\xd3\xb4\x12\xde\x06\x3d",
+       243 },
+      { GCRY_MD_SHA3_224,
+       "\x2e\xdc\x28\x2f\xfb\x90\xb9\x71\x18\xdd\x03\xaa\xa0\x3b\x14\x5f\x36\x39\x05\xe3\xcb\xd2\xd5\x0e\xcd\x69\x2b\x37\xbf\x00\x01\x85\xc6\x51\xd3\xe9\x72\x6c\x69\x0d\x37\x73\xec\x1e\x48\x51\x0e\x42\xb1\x77\x42\xb0\xb0\x37\x7e\x7d\xe6\xb8\xf5\x5e\x00\xa8\xa4\xdb\x47\x40\xce\xe6\xdb\x08\x30\x52\x9d\xd1\x96\x17\x50\x1d\xc1\xe9\x35\x9a\xa3\xbc\xf1\x47\xe0\xa7\x6b\x3a\xb7\x0c\x49\x84\xc1\x3e\x33\x9e\x68\x06\xbb\x35\xe6\x83\xaf\x85\x27\x09\x36\x70\x85\x9f\x3d\x8a\x0f\xc7\xd4\x93\xbc\xba\x6b\xb1\x2b\x5f\x65\xe7\x1e\x70\x5c\xa5\xd6\xc9\x48\xd6\x6e\xd3\xd7\x30\xb2\x6d\xb3\x95\xb3\x44\x77\x37\xc2\x6f\xad\x08\x9a\xa0\xad\x0e\x30\x6c\xb2\x8b\xf0\xac\xf1\x06\xf8\x9a\xf3\x74\x5f\x0e\xc7\x2d\x53\x49\x68\xcc\xa5\x43\xcd\x2c\xa5\x0c\x94\xb1\x45\x67\x43\x25\x4e\x35\x8c\x13\x17\xc0\x7a\x07\xbf\x2b\x0e\xca\x43\x8a\x70\x93\x67\xfa\xfc\x89\xa5\x72\x39\x02\x8f\xc5\xfe\xcf\xd5\x3b\x8e\xf9\x58\xef\x10\xee\x06\x08\xb7\xf5\xcb\x99\x23\xad\x97\x05\x8e\xc0\x67\x70\x0c\xc7\x46\xc1\x27\xa6\x1e\xe3",
+       "\x13\x68\x45\x4e\x84\x9f\x2d\x22\x99\x07\x7f\x40\x82\x6b\x40\x72\xe6\xfe\xe4\x9b\x20\x62\xcb\x8e\x3b\x45\x23\xc9",
+       244 },
+      { GCRY_MD_SHA3_224,
+       "\x90\xb2\x8a\x6a\xa1\xfe\x53\x39\x15\xbc\xb8\xe8\x1e\xd6\xca\xcd\xc1\x09\x62\xb7\xff\x82\x47\x4f\x84\x5e\xeb\x86\x97\x76\x00\xcf\x70\xb0\x7b\xa8\xe3\x79\x61\x41\xee\x34\x0e\x3f\xce\x84\x2a\x38\xa5\x0a\xfb\xe9\x03\x01\xa3\xbd\xcc\x59\x1f\x2e\x7d\x9d\xe5\x3e\x49\x55\x25\x56\x0b\x90\x8c\x89\x24\x39\x99\x0a\x2c\xa2\x67\x9c\x55\x39\xff\xdf\x63\x67\x77\xad\x9c\x1c\xde\xf8\x09\xcd\xa9\xe8\xdc\xdb\x45\x1a\xbb\x9e\x9c\x17\xef\xa4\x37\x9a\xbd\x24\xb1\x82\xbd\x98\x1c\xaf\xc7\x92\x64\x0a\x18\x3b\x61\x69\x43\x01\xd0\x4c\x5b\x3e\xaa\xd6\x94\xa6\xbd\x4c\xc0\x6e\xf5\xda\x8f\xa2\x3b\x4f\xa2\xa6\x45\x59\xc5\xa6\x83\x97\x93\x00\x79\xd2\x50\xc5\x1b\xcf\x00\xe2\xb1\x6a\x6c\x49\x17\x14\x33\xb0\xaa\xdf\xd8\x02\x31\x27\x65\x60\xb8\x04\x58\xdd\x77\x08\x9b\x7a\x1b\xbc\xc9\xe7\xe4\xb9\xf8\x81\xea\xcd\x6c\x92\xc4\x31\x83\x48\xa1\x3f\x49\x14\xeb\x27\x11\x5a\x1c\xfc\x5d\x16\xd7\xfd\x94\x95\x4c\x35\x32\xef\xac\xa2\xca\xb0\x25\x10\x3b\x2d\x02\xc6\xfd\x71\xda\x3a\x77\xf4\x17\xd7\x93\x26\x85\x88\x8a",
+       "\x57\x65\xb7\x05\x74\xf9\x33\x41\xc1\xcc\x4a\xcb\x34\xf6\x45\xb5\xd9\x7b\x81\xd4\xce\x8f\x38\xc3\x86\x2f\x6c\x19",
+       245 },
+      { GCRY_MD_SHA3_224,
+       "\x29\x69\x44\x7d\x17\x54\x90\xf2\xaa\x9b\xb0\x55\x01\x4d\xbe\xf2\xe6\x85\x4c\x95\xf8\xd6\x09\x50\xbf\xe8\xc0\xbe\x8d\xe2\x54\xc2\x6b\x2d\x31\xb9\xe4\xde\x9c\x68\xc9\xad\xf4\x9e\x4e\xe9\xb1\xc2\x85\x09\x67\xf2\x9f\x5d\x08\x73\x84\x83\xb4\x17\xbb\x96\xb2\xa5\x6f\x0c\x8a\xca\x63\x2b\x55\x20\x59\xc5\x9a\xac\x3f\x61\xf7\xb4\x5c\x96\x6b\x75\xf1\xd9\x93\x1f\xf4\xe5\x96\x40\x63\x78\xce\xe9\x1a\xaa\x72\x6a\x3a\x84\xc3\x3f\x37\xe9\xcd\xbe\x62\x6b\x57\x45\xa0\xb0\x60\x64\xa8\xa8\xd5\x6e\x53\xaa\xf1\x02\xd2\x3d\xd9\xdf\x0a\x3f\xdf\x7a\x63\x85\x09\xa6\x76\x1a\x33\xfa\x42\xfa\x8d\xdb\xd8\xe1\x61\x59\xc9\x30\x08\xb5\x37\x65\x01\x9c\x3f\x0e\x9f\x10\xb1\x44\xce\x2a\xc5\x7f\x5d\x72\x97\xf9\xc9\x94\x9e\x4f\xf6\x8b\x70\xd3\x39\xf8\x75\x01\xce\x85\x50\xb7\x72\xf3\x2c\x6d\xa8\xad\x2c\xe2\x10\x0a\x89\x5d\x8b\x08\xfa\x1e\xea\xd7\xc3\x76\xb4\x07\x70\x97\x03\xc5\x10\xb5\x0f\x87\xe7\x3e\x43\xf8\xe7\x34\x8f\x87\xc3\x83\x2a\x54\x7e\xf2\xbb\xe5\x79\x9a\xbe\xdc\xf5\xe1\xf3\x72\xea\x80\x92\x33\xf0\x06",
+       "\xb8\xfb\x31\x82\x45\xb4\x04\x22\x22\xb4\x06\x3a\x05\x3f\x15\xda\x6b\x89\x4f\x22\x73\x6f\x3f\x9e\x26\xf7\x21\x75",
+       246 },
+      { GCRY_MD_SHA3_224,
+       "\x72\x16\x45\x63\x3a\x44\xa2\xc7\x8b\x19\x02\x4e\xae\xcf\x58\x57\x5a\xb2\x3c\x27\x19\x08\x33\xc2\x68\x75\xdc\x0f\x0d\x50\xb4\x6a\xea\x9c\x34\x3d\x82\xea\x7d\x5b\x3e\x50\xec\x70\x05\x45\xc6\x15\xda\xea\xea\x64\x72\x6a\x0f\x05\x60\x75\x76\xdc\xd3\x96\xd8\x12\xb0\x3f\xb6\x55\x1c\x64\x10\x87\x85\x6d\x05\x0b\x10\xe6\xa4\xd5\x57\x7b\x82\xa9\x8a\xfb\x89\xce\xe8\x59\x4c\x9d\xc1\x9e\x79\xfe\xff\x03\x82\xfc\xfd\x12\x7f\x1b\x80\x3a\x4b\x99\x46\xf4\xac\x9a\x43\x78\xe1\xe6\xe0\x41\xb1\x38\x9a\x53\xe3\x45\x0c\xd3\x2d\x9d\x29\x41\xb0\xcb\xab\xdb\x50\xda\x8e\xa2\x51\x31\x45\x16\x4c\x3a\xb6\xbc\xbd\x25\x1c\x44\x8d\x2d\x4b\x08\x7a\xc5\x7a\x59\xc2\x28\x5d\x56\x4f\x16\xda\x4e\xd5\xe6\x07\xed\x97\x95\x92\x14\x6f\xfb\x0e\xf3\xf3\xdb\x30\x8f\xb3\x42\xdf\x5e\xb5\x92\x4a\x48\x25\x6f\xc7\x63\x14\x1a\x27\x88\x14\xc8\x2d\x6d\x63\x48\x57\x75\x45\x87\x0a\xe3\xa8\x3c\x72\x30\xac\x02\xa1\x54\x0f\xe1\x79\x8f\x7e\xf0\x9e\x33\x5a\x86\x5a\x2a\xe0\x94\x9b\x21\xe4\xf7\x48\xfb\x8a\x51\xf4\x47\x50\xe2\x13\xa8\xfb",
+       "\x35\x36\x22\xe9\x2c\x79\x07\xf5\x56\x3b\xaf\x8f\x4e\x7a\xf0\xc2\xf8\x72\xf4\xfb\x58\x3b\x01\xaf\x9e\xb3\xd9\x07",
+       247 },
+      { GCRY_MD_SHA3_224,
+       "\x6b\x86\x0d\x39\x72\x5a\x14\xb4\x98\xbb\x71\x45\x74\xb4\xd3\x7c\xa7\x87\x40\x47\x68\xf6\x4c\x64\x8b\x17\x51\xb3\x53\xac\x92\xba\xc2\xc3\xa2\x8e\xa9\x09\xfd\xf0\x42\x33\x36\x40\x1a\x02\xe6\x3e\xc2\x43\x25\x30\x0d\x82\x3b\x68\x64\xbb\x70\x1f\x9d\x7c\x7a\x1f\x8e\xc9\xd0\xae\x35\x84\xaa\x6d\xd6\x2e\xa1\x99\x7c\xd8\x31\xb4\xba\xbd\x9a\x4d\xa5\x09\x32\xd4\xef\xda\x74\x5c\x61\xe4\x13\x08\x90\xe1\x56\xae\xe6\x11\x37\x16\xda\xf9\x57\x64\x22\x2a\x91\x18\x7d\xb2\xef\xfe\xa4\x9d\x5d\x05\x96\x10\x2d\x61\x9b\xd2\x6a\x61\x6b\xbf\xda\x83\x35\x50\x5f\xbb\x0d\x90\xb4\xc1\x80\xd1\xa2\x33\x5b\x91\x53\x8e\x16\x68\xf9\xf9\x64\x27\x90\xb4\xe5\x5f\x9c\xab\x0f\xe2\xbd\xd2\x93\x5d\x00\x1e\xe6\x41\x9a\xba\xb5\x45\x78\x80\xd0\xdb\xff\x20\xed\x87\x58\xf4\xc2\x0f\xe7\x59\xef\xb3\x31\x41\xcf\x0e\x89\x25\x87\xfe\x81\x87\xe5\xfb\xc5\x77\x86\xb7\xe8\xb0\x89\x61\x2c\x93\x6d\xfc\x03\xd2\x7e\xfb\xbe\x7c\x86\x73\xf1\x60\x6b\xd5\x1d\x5f\xf3\x86\xf4\xa7\xab\x68\xed\xf5\x9f\x38\x5e\xb1\x29\x1f\x11\x7b\xfe\x71\x73\x99",
+       "\x87\x21\x5a\xf7\x3d\x5c\xde\x98\xb3\x55\x47\x9a\xfb\x82\xa5\x11\x18\x0b\x7d\xc3\xd5\x34\x2c\x88\xe1\x33\xae\xd8",
+       248 },
+      { GCRY_MD_SHA3_224,
+       "\x6a\x01\x83\x0a\xf3\x88\x9a\x25\x18\x32\x44\xde\xcb\x50\x8b\xd0\x12\x53\xd5\xb5\x08\xab\x49\x0d\x31\x24\xaf\xbf\x42\x62\x6b\x2e\x70\x89\x4e\x9b\x56\x2b\x28\x8d\x0a\x24\x50\xcf\xac\xf1\x4a\x0d\xda\xe5\xc0\x47\x16\xe5\xa0\x08\x2c\x33\x98\x1f\x60\x37\xd2\x3d\x5e\x04\x5e\xe1\xef\x22\x83\xfb\x8b\x63\x78\xa9\x14\xc5\xd9\x44\x16\x27\xa7\x22\xc2\x82\xff\x45\x2e\x25\xa7\xea\x60\x8d\x69\xce\xe4\x39\x3a\x07\x25\xd1\x79\x63\xd0\x34\x26\x84\xf2\x55\x49\x6d\x8a\x18\xc2\x96\x11\x45\x31\x51\x30\x54\x93\x11\xfc\x07\xf0\x31\x2f\xb7\x8e\x60\x77\x33\x4f\x87\xea\xa8\x73\xbe\xe8\xaa\x95\x69\x89\x96\xeb\x21\x37\x5e\xb2\xb4\xef\x53\xc1\x44\x01\x20\x7d\xeb\x45\x68\x39\x8e\x5d\xd9\xa7\xcf\x97\xe8\xc9\x66\x3e\x23\x33\x4b\x46\x91\x2f\x83\x44\xc1\x9e\xfc\xf8\xc2\xba\x6f\x04\x32\x5f\x1a\x27\xe0\x62\xb6\x2a\x58\xd0\x76\x6f\xc6\xdb\x4d\x2c\x6a\x19\x28\x60\x4b\x01\x75\xd8\x72\xd1\x6b\x79\x08\xeb\xc0\x41\x76\x11\x87\xcc\x78\x55\x26\xc2\xa3\x87\x3f\xea\xc3\xa6\x42\xbb\x39\xf5\x35\x15\x50\xaf\x97\x70\xc3\x28\xaf\x7b",
+       "\x25\xae\x85\x2d\xba\x36\xb8\xd5\x8a\x94\xdd\x5c\xfd\x83\x45\x14\x1f\xf5\x7e\x7d\xb7\xd7\x81\x6c\x4f\x72\x52\xbb",
+       249 },
+      { GCRY_MD_SHA3_224,
+       "\xb3\xc5\xe7\x4b\x69\x93\x3c\x25\x33\x10\x6c\x56\x3b\x4c\xa2\x02\x38\xf2\xb6\xe6\x75\xe8\x68\x1e\x34\xa3\x89\x89\x47\x85\xbd\xad\xe5\x96\x52\xd4\xa7\x3d\x80\xa5\xc8\x5b\xd4\x54\xfd\x1e\x9f\xfd\xad\x1c\x38\x15\xf5\x03\x8e\x9e\xf4\x32\xaa\xc5\xc3\xc4\xfe\x84\x0c\xc3\x70\xcf\x86\x58\x0a\x60\x11\x77\x8b\xbe\xda\xf5\x11\xa5\x1b\x56\xd1\xa2\xeb\x68\x39\x4a\xa2\x99\xe2\x6d\xa9\xad\xa6\xa2\xf3\x9b\x9f\xaf\xf7\xfb\xa4\x57\x68\x9b\x9c\x1a\x57\x7b\x2a\x1e\x50\x5f\xdf\x75\xc7\xa0\xa6\x4b\x1d\xf8\x1b\x3a\x35\x60\x01\xbf\x0d\xf4\xe0\x2a\x1f\xc5\x9f\x65\x1c\x9d\x58\x5e\xc6\x22\x4b\xb2\x79\xc6\xbe\xba\x29\x66\xe8\x88\x2d\x68\x37\x60\x81\xb9\x87\x46\x8e\x7a\xed\x1e\xf9\x0e\xbd\x09\x0a\xe8\x25\x79\x5c\xdc\xa1\xb4\xf0\x9a\x97\x9c\x8d\xfc\x21\xa4\x8d\x8a\x53\xcd\xbb\x26\xc4\xdb\x54\x7f\xc0\x6e\xfe\x2f\x98\x50\xed\xd2\x68\x5a\x46\x61\xcb\x49\x11\xf1\x65\xd4\xb6\x3e\xf2\x5b\x87\xd0\xa9\x6d\x3d\xff\x6a\xb0\x75\x89\x99\xaa\xd2\x14\xd0\x7b\xd4\xf1\x33\xa6\x73\x4f\xde\x44\x5f\xe4\x74\x71\x1b\x69\xa9\x8f\x7e\x2b",
+       "\xec\xe0\x39\x44\x18\xf0\x66\xf5\x50\x23\x79\x75\x51\xe0\x6f\x6a\x7d\x16\x45\x68\x2a\xa4\xd9\xdd\x75\xaf\x8e\x76",
+       250 },
+      { GCRY_MD_SHA3_224,
+       "\x83\xaf\x34\x27\x9c\xcb\x54\x30\xfe\xbe\xc0\x7a\x81\x95\x0d\x30\xf4\xb6\x6f\x48\x48\x26\xaf\xee\x74\x56\xf0\x07\x1a\x51\xe1\xbb\xc5\x55\x70\xb5\xcc\x7e\xc6\xf9\x30\x9c\x17\xbf\x5b\xef\xdd\x7c\x6b\xa6\xe9\x68\xcf\x21\x8a\x2b\x34\xbd\x5c\xf9\x27\xab\x84\x6e\x38\xa4\x0b\xbd\x81\x75\x9e\x9e\x33\x38\x10\x16\xa7\x55\xf6\x99\xdf\x35\xd6\x60\x00\x7b\x5e\xad\xf2\x92\xfe\xef\xb7\x35\x20\x7e\xbf\x70\xb5\xbd\x17\x83\x4f\x7b\xfa\x0e\x16\xcb\x21\x9a\xd4\xaf\x52\x4a\xb1\xea\x37\x33\x4a\xa6\x64\x35\xe5\xd3\x97\xfc\x0a\x06\x5c\x41\x1e\xbb\xce\x32\xc2\x40\xb9\x04\x76\xd3\x07\xce\x80\x2e\xc8\x2c\x1c\x49\xbc\x1b\xec\x48\xc0\x67\x5e\xc2\xa6\xc6\xf3\xed\x3e\x5b\x74\x1d\x13\x43\x70\x95\x70\x7c\x56\x5e\x10\xd8\xa2\x0b\x8c\x20\x46\x8f\xf9\x51\x4f\xcf\x31\xb4\x24\x9c\xd8\x2d\xce\xe5\x8c\x0a\x2a\xf5\x38\xb2\x91\xa8\x7e\x33\x90\xd7\x37\x19\x1a\x07\x48\x4a\x5d\x3f\x3f\xb8\xc8\xf1\x5c\xe0\x56\xe5\xe5\xf8\xfe\xbe\x5e\x1f\xb5\x9d\x67\x40\x98\x0a\xa0\x6c\xa8\xa0\xc2\x0f\x57\x12\xb4\xcd\xe5\xd0\x32\xe9\x2a\xb8\x9f\x0a\xe1",
+       "\x84\xa4\xbd\x2e\x3f\xa2\x6c\x4f\xb0\x1f\xe8\x19\x53\x39\x8f\x5b\x4b\x57\x04\x94\x43\x54\xb5\x1b\x88\x7f\xd9\x90",
+       251 },
+      { GCRY_MD_SHA3_224,
+       "\xa7\xed\x84\x74\x9c\xcc\x56\xbb\x1d\xfb\xa5\x71\x19\xd2\x79\xd4\x12\xb8\xa9\x86\x88\x6d\x81\x0f\x06\x7a\xf3\x49\xe8\x74\x9e\x9e\xa7\x46\xa6\x0b\x03\x74\x26\x36\xc4\x64\xfc\x1e\xe2\x33\xac\xc5\x2c\x19\x83\x91\x46\x92\xb6\x43\x09\xed\xfd\xf2\x9f\x1a\xb9\x12\xec\x3e\x8d\xa0\x74\xd3\xf1\xd2\x31\x51\x1f\x57\x56\xf0\xb6\xee\xad\x3e\x89\xa6\xa8\x8f\xe3\x30\xa1\x0f\xac\xe2\x67\xbf\xfb\xfc\x3e\x30\x90\xc7\xfd\x9a\x85\x05\x61\xf3\x63\xad\x75\xea\x88\x1e\x72\x44\xf8\x0f\xf5\x58\x02\xd5\xef\x7a\x1a\x4e\x7b\x89\xfc\xfa\x80\xf1\x6d\xf5\x4d\x1b\x05\x6e\xe6\x37\xe6\x96\x4b\x9e\x0f\xfd\x15\xb6\x19\x6b\xdd\x7d\xb2\x70\xc5\x6b\x47\x25\x14\x85\x34\x8e\x49\x81\x3b\x4e\xb9\xed\x12\x2a\x01\xb3\xea\x45\xad\x5e\x1a\x92\x9d\xf6\x1d\x5c\x0f\x3e\x77\xe1\xfd\xc3\x56\xb6\x38\x83\xa6\x0e\x9c\xbb\x9f\xc3\xe0\x0c\x2f\x32\xdb\xd4\x69\x65\x98\x83\xf6\x90\xc6\x77\x2e\x33\x5f\x61\x7b\xc3\x3f\x16\x1d\x6f\x69\x84\x25\x2e\xe1\x2e\x62\xb6\x00\x0a\xc5\x23\x1e\x0c\x9b\xc6\x5b\xe2\x23\xd8\xdf\xd9\x4c\x50\x04\xa1\x01\xaf\x9f\xd6\xc0\xfb",
+       "\x17\x0c\x41\x38\x63\xd9\xf4\xe8\xc0\xb8\x7a\x85\x32\x41\x6b\x10\xa6\x9c\x34\x8d\x3a\x14\x46\x58\xea\xee\xf0\xed",
+       252 },
+      { GCRY_MD_SHA3_224,
+       "\xa6\xfe\x30\xdc\xfc\xda\x1a\x32\x9e\x82\xab\x50\xe3\x2b\x5f\x50\xeb\x25\xc8\x73\xc5\xd2\x30\x58\x60\xa8\x35\xae\xce\xe6\x26\x4a\xa3\x6a\x47\x42\x99\x22\xc4\xb8\xb3\xaf\xd0\x0d\xa1\x60\x35\x83\x0e\xdb\x89\x78\x31\xc4\xe7\xb0\x0f\x2c\x23\xfc\x0b\x15\xfd\xc3\x0d\x85\xfb\x70\xc3\x0c\x43\x1c\x63\x8e\x1a\x25\xb5\x1c\xaf\x1d\x7e\x8b\x05\x0b\x7f\x89\xbf\xb3\x0f\x59\xf0\xf2\x0f\xec\xff\x3d\x63\x9a\xbc\x42\x55\xb3\x86\x8f\xc4\x5d\xd8\x1e\x47\xeb\x12\xab\x40\xf2\xaa\xc7\x35\xdf\x5d\x1d\xc1\xad\x99\x7c\xef\xc4\xd8\x36\xb8\x54\xce\xe9\xac\x02\x90\x00\x36\xf3\x86\x7f\xe0\xd8\x4a\xff\xf3\x7b\xde\x33\x08\xc2\x20\x6c\x62\xc4\x74\x33\x75\x09\x41\x08\x87\x7c\x73\xb8\x7b\x25\x46\xfe\x05\xea\x13\x7b\xed\xfc\x06\xa2\x79\x62\x74\x09\x9a\x0d\x55\x4d\xa8\xf7\xd7\x22\x3a\x48\xcb\xf3\x1b\x7d\xec\xaa\x1e\xbc\x8b\x14\x57\x63\xe3\x67\x31\x68\xc1\xb1\xb7\x15\xc1\xcd\x99\xec\xd3\xdd\xb2\x38\xb0\x60\x49\x88\x5e\xca\xd9\x34\x7c\x24\x36\xdf\xf3\x2c\x77\x1f\x34\xa3\x85\x87\xa4\x4a\x82\xc5\xd3\xd1\x37\xa0\x3c\xaa\x27\xe6\x6c\x8f\xf6",
+       "\xd8\xc2\x57\xdb\x76\x53\x6f\x7e\xf1\xdc\xfb\x24\x97\x6e\xb7\x16\xd9\x49\x1c\xd8\x65\x1e\x02\x54\xe7\xc4\xa5\xbb",
+       253 },
+      { GCRY_MD_SHA3_224,
+       "\x83\x16\x7f\xf5\x37\x04\xc3\xaa\x19\xe9\xfb\x33\x03\x53\x97\x59\xc4\x6d\xd4\x09\x1a\x52\xdd\xae\x9a\xd8\x64\x08\xb6\x93\x35\x98\x9e\x61\x41\x4b\xc2\x0a\xb4\xd0\x12\x20\xe3\x52\x41\xef\xf5\xc9\x52\x2b\x07\x9f\xba\x59\x76\x74\xc8\xd7\x16\xfe\x44\x1e\x56\x61\x10\xb6\x21\x15\x31\xce\xcc\xf8\xfd\x06\xbc\x8e\x51\x1d\x00\x78\x5e\x57\x78\x8e\xd9\xa1\xc5\xc7\x35\x24\xf0\x18\x30\xd2\xe1\x14\x8c\x92\xd0\xed\xc9\x71\x13\xe3\xb7\xb5\xcd\x30\x49\x62\x7a\xbd\xb8\xb3\x9d\xd4\xd6\x89\x0e\x0e\xe9\x19\x93\xf9\x2b\x03\x35\x4a\x88\xf5\x22\x51\xc5\x46\xe6\x44\x34\xd9\xc3\xd7\x45\x44\xf2\x3f\xb9\x3e\x5a\x2d\x2f\x1f\xb1\x55\x45\xb4\xe1\x36\x7c\x97\x33\x5b\x02\x91\x94\x4c\x8b\x73\x0a\xd3\xd4\x78\x92\x73\xfa\x44\xfb\x98\xd7\x8a\x36\xc3\xc3\x76\x4a\xbe\xea\xc7\xc5\x69\xc1\xe4\x3a\x35\x2e\x5b\x77\x0c\x35\x04\xf8\x70\x90\xde\xe0\x75\xa1\xc4\xc8\x5c\x0c\x39\xcf\x42\x1b\xdc\xc6\x15\xf9\xef\xf6\xcb\x4f\xe6\x46\x80\x04\xae\xce\x5f\x30\xe1\xec\xc6\xdb\x22\xad\x99\x39\xbb\x2b\x0c\xcc\x96\x52\x1d\xfb\xf4\xae\x00\x8b\x5b\x46\xbc\x00\x6e",
+       "\xf8\x1d\x8e\xe4\x08\x69\xbb\x38\xa1\x3a\x4f\x75\x58\x8f\xa3\x30\x80\x68\xdd\x1c\xdc\x27\x26\x7d\x66\xfa\xc1\x98",
+       254 },
+      { GCRY_MD_SHA3_224,
+       "\x3a\x3a\x81\x9c\x48\xef\xde\x2a\xd9\x14\xfb\xf0\x0e\x18\xab\x6b\xc4\xf1\x45\x13\xab\x27\xd0\xc1\x78\xa1\x88\xb6\x14\x31\xe7\xf5\x62\x3c\xb6\x6b\x23\x34\x67\x75\xd3\x86\xb5\x0e\x98\x2c\x49\x3a\xdb\xbf\xc5\x4b\x9a\x3c\xd3\x83\x38\x23\x36\xa1\xa0\xb2\x15\x0a\x15\x35\x8f\x33\x6d\x03\xae\x18\xf6\x66\xc7\x57\x3d\x55\xc4\xfd\x18\x1c\x29\xe6\xcc\xfd\xe6\x3e\xa3\x5f\x0a\xdf\x58\x85\xcf\xc0\xa3\xd8\x4a\x2b\x2e\x4d\xd2\x44\x96\xdb\x78\x9e\x66\x31\x70\xce\xf7\x47\x98\xaa\x1b\xbc\xd4\x57\x4e\xa0\xbb\xa4\x04\x89\xd7\x64\xb2\xf8\x3a\xad\xc6\x6b\x14\x8b\x4a\x0c\xd9\x52\x46\xc1\x27\xd5\x87\x1c\x4f\x11\x41\x86\x90\xa5\xdd\xf0\x12\x46\xa0\xc8\x0a\x43\xc7\x00\x88\xb6\x18\x36\x39\xdc\xfd\xa4\x12\x5b\xd1\x13\xa8\xf4\x9e\xe2\x3e\xd3\x06\xfa\xac\x57\x6c\x3f\xb0\xc1\xe2\x56\x67\x1d\x81\x7f\xc2\x53\x4a\x52\xf5\xb4\x39\xf7\x2e\x42\x4d\xe3\x76\xf4\xc5\x65\xcc\xa8\x23\x07\xdd\x9e\xf7\x6d\xa5\xb7\xc4\xeb\x7e\x08\x51\x72\xe3\x28\x80\x7c\x02\xd0\x11\xff\xbf\x33\x78\x53\x78\xd7\x9d\xc2\x66\xf6\xa5\xbe\x6b\xb0\xe4\xa9\x2e\xce\xeb\xae\xb1",
+       "\x94\x68\x9e\xa9\xf3\x47\xdd\xa8\xdd\x79\x8a\x85\x86\x05\x86\x87\x43\xc6\xbd\x03\xa6\xa6\x5c\x60\x85\xd5\x2b\xed",
+       255 },
diff --git a/tests/sha3-256.h b/tests/sha3-256.h
new file mode 100644 (file)
index 0000000..f787b63
--- /dev/null
@@ -0,0 +1,1025 @@
+/* Generated from https://raw.githubusercontent.com/gvanas/KeccakCodePackage/master/TestVectors/ShortMsgKAT_SHA3-256.txt */
+      { GCRY_MD_SHA3_256,
+       "",
+       "\xa7\xff\xc6\xf8\xbf\x1e\xd7\x66\x51\xc1\x47\x56\xa0\x61\xd6\x62\xf5\x80\xff\x4d\xe4\x3b\x49\xfa\x82\xd8\x0a\x4b\x80\xf8\x43\x4a",
+       0 },
+      { GCRY_MD_SHA3_256,
+       "\xcc",
+       "\x67\x70\x35\x39\x1c\xd3\x70\x12\x93\xd3\x85\xf0\x37\xba\x32\x79\x62\x52\xbb\x7c\xe1\x80\xb0\x0b\x58\x2d\xd9\xb2\x0a\xaa\xd7\xf0",
+       1 },
+      { GCRY_MD_SHA3_256,
+       "\x41\xfb",
+       "\x39\xf3\x1b\x6e\x65\x3d\xfc\xd9\xca\xed\x26\x02\xfd\x87\xf6\x1b\x62\x54\xf5\x81\x31\x2f\xb6\xee\xec\x4d\x71\x48\xfa\x2e\x72\xaa",
+       2 },
+      { GCRY_MD_SHA3_256,
+       "\x1f\x87\x7c",
+       "\xbc\x22\x34\x5e\x4b\xd3\xf7\x92\xa3\x41\xcf\x18\xac\x07\x89\xf1\xc9\xc9\x66\x71\x2a\x50\x1b\x19\xd1\xb6\x63\x2c\xcd\x40\x8e\xc5",
+       3 },
+      { GCRY_MD_SHA3_256,
+       "\xc1\xec\xfd\xfc",
+       "\xc5\x85\x9b\xe8\x25\x60\xcc\x87\x89\x13\x3f\x7c\x83\x4a\x6e\xe6\x28\xe3\x51\xe5\x04\xe6\x01\xe8\x05\x9a\x06\x67\xff\x62\xc1\x24",
+       4 },
+      { GCRY_MD_SHA3_256,
+       "\x21\xf1\x34\xac\x57",
+       "\x55\xbd\x92\x24\xaf\x4e\xed\x0d\x12\x11\x49\xe3\x7f\xf4\xd7\xdd\x5b\xe2\x4b\xd9\xfb\xe5\x6e\x01\x71\xe8\x7d\xb7\xa6\xf4\xe0\x6d",
+       5 },
+      { GCRY_MD_SHA3_256,
+       "\xc6\xf5\x0b\xb7\x4e\x29",
+       "\xae\x0c\xbc\x75\x7d\x4a\xb0\x88\xe1\x72\xab\xfd\x87\x46\x28\x99\x50\xf9\x2d\x38\xa2\x52\x95\x65\x8d\xbf\x74\x4b\x56\x35\xaf\x04",
+       6 },
+      { GCRY_MD_SHA3_256,
+       "\x11\x97\x13\xcc\x83\xee\xef",
+       "\xe3\x40\xc9\xa4\x43\x73\xef\xcc\x21\x2f\x3c\xb6\x6a\x04\x7a\xc3\x4c\x87\xff\x1c\x58\xc4\xa1\x4b\x16\xa2\xbf\xc3\x46\x98\xbb\x1d",
+       7 },
+      { GCRY_MD_SHA3_256,
+       "\x4a\x4f\x20\x24\x84\x51\x25\x26",
+       "\xba\x4f\xb0\x09\xd5\x7a\x5c\xeb\x85\xfc\x64\xd5\x4e\x5c\x55\xa5\x58\x54\xb4\x1c\xc4\x7a\xd1\x52\x94\xbc\x41\xf3\x21\x65\xdf\xba",
+       8 },
+      { GCRY_MD_SHA3_256,
+       "\x1f\x66\xab\x41\x85\xed\x9b\x63\x75",
+       "\xb9\x88\x6e\xf9\x05\xc8\xbd\xd2\x72\xed\xa8\x29\x88\x65\xe0\x76\x98\x69\xf1\xc9\x64\x46\x0d\x1a\xa9\xd7\xa0\xc6\x87\x70\x7c\xcd",
+       9 },
+      { GCRY_MD_SHA3_256,
+       "\xee\xd7\x42\x22\x27\x61\x3b\x6f\x53\xc9",
+       "\xfa\xb8\xf8\x8d\x31\x91\xe2\x1a\x72\x5b\x21\xc6\x3a\x02\xca\xd3\xfa\x7c\x45\x0e\xf8\x58\x4b\x94\xcf\xa3\x82\xf3\x93\x42\x24\x55",
+       10 },
+      { GCRY_MD_SHA3_256,
+       "\xea\xee\xd5\xcd\xff\xd8\x9d\xec\xe4\x55\xf1",
+       "\x93\x63\xac\xd3\xf4\x8b\xb9\x1a\x89\x98\xaa\x0e\x8d\xf7\x5c\x97\x17\x70\xa1\x6a\x71\xe7\xd2\x33\x44\x09\x73\x4c\xd7\xd0\xa9\xee",
+       11 },
+      { GCRY_MD_SHA3_256,
+       "\x5b\xe4\x3c\x90\xf2\x29\x02\xe4\xfe\x8e\xd2\xd3",
+       "\x16\x93\x2f\x6f\x65\xde\xaa\xd5\x78\x0e\x25\xab\x41\x0c\x66\xb0\xe4\x19\x8e\xba\x9f\x4e\xd1\xa2\x5e\xe2\x4f\x78\x79\xfa\xef\xe2",
+       12 },
+      { GCRY_MD_SHA3_256,
+       "\xa7\x46\x27\x32\x28\x12\x2f\x38\x1c\x3b\x46\xe4\xf1",
+       "\x1c\x28\x10\x0e\x0e\xf5\x06\x71\xc7\xea\x3e\x02\x4f\xa3\xba\x9d\xa2\xeb\xdd\xb4\xde\x26\x4c\x3a\x24\x26\xc3\x6a\xd3\xf9\x1c\x61",
+       13 },
+      { GCRY_MD_SHA3_256,
+       "\x3c\x58\x71\xcd\x61\x9c\x69\xa6\x3b\x54\x0e\xb5\xa6\x25",
+       "\x81\x83\xbe\x48\x75\xfa\xb7\xec\x5f\x99\xed\x94\xf5\xf9\x00\xcf\x1d\x6b\x95\x3d\x8f\x71\xe1\xe7\xcc\x00\x86\x87\x98\x0e\x61\x3a",
+       14 },
+      { GCRY_MD_SHA3_256,
+       "\xfa\x22\x87\x4b\xcc\x06\x88\x79\xe8\xef\x11\xa6\x9f\x07\x22",
+       "\x3b\x1a\x6d\x21\xfe\x44\x69\x1d\xac\x4e\xb7\xc5\x93\xa6\xd8\x52\x3c\xb6\x06\xe6\x3c\xf0\x0e\x94\xd7\x11\xa5\x74\x24\x8d\xac\xa5",
+       15 },
+      { GCRY_MD_SHA3_256,
+       "\x52\xa6\x08\xab\x21\xcc\xdd\x8a\x44\x57\xa5\x7e\xde\x78\x21\x76",
+       "\x2c\x7e\x7c\xb3\x56\xfd\xc6\x8e\xc8\x92\x7e\x49\x9d\x2a\x6b\xae\x2b\x78\x18\x17\x91\x9c\x82\x9e\xbb\xe8\x22\x5b\xae\xd4\x69\x67",
+       16 },
+      { GCRY_MD_SHA3_256,
+       "\x82\xe1\x92\xe4\x04\x3d\xdc\xd1\x2e\xcf\x52\x96\x9d\x0f\x80\x7e\xed",
+       "\xc7\xb1\x2e\xff\x69\x2d\x84\x21\x10\xcc\x39\xac\x60\x61\x67\x07\xac\xb3\xf9\xb0\xf1\xcb\x36\x1b\x94\x57\x7e\xfc\x52\x9c\xa2\x6c",
+       17 },
+      { GCRY_MD_SHA3_256,
+       "\x75\x68\x3d\xcb\x55\x61\x40\xc5\x22\x54\x3b\xb6\xe9\x09\x8b\x21\xa2\x1e",
+       "\x49\x3e\xba\xeb\xc0\x47\x76\xf4\xe0\x67\x55\x5a\xfa\x09\xb5\x8c\x85\x0f\xdf\x1b\x0e\x22\xd4\xbf\x00\x6c\xe4\x1c\x09\x1d\xc7\x62",
+       18 },
+      { GCRY_MD_SHA3_256,
+       "\x06\xe4\xef\xe4\x50\x35\xe6\x1f\xaa\xf4\x28\x7b\x4d\x8d\x1f\x12\xca\x97\xe5",
+       "\x1d\x01\xf3\x12\x0e\xcf\xbd\xd2\x8d\xce\x44\x31\x76\x66\xcf\x86\x4f\x52\x39\x1b\x9e\xca\x38\x43\xdb\x45\x66\x7c\x2e\x0a\x98\xad",
+       19 },
+      { GCRY_MD_SHA3_256,
+       "\xe2\x61\x93\x98\x9d\x06\x56\x8f\xe6\x88\xe7\x55\x40\xae\xa0\x67\x47\xd9\xf8\x51",
+       "\x2c\x1e\x61\xe5\xd4\x52\x03\xf2\x7b\x86\xf1\x29\x3a\x80\xba\xb3\x41\x92\xda\xf4\x2b\x86\x23\xb1\x20\x05\xb2\xfb\x1c\x18\xac\xb1",
+       20 },
+      { GCRY_MD_SHA3_256,
+       "\xd8\xdc\x8f\xde\xfb\xdc\xe9\xd4\x4e\x4c\xba\xfe\x78\x44\x7b\xae\x3b\x54\x36\x10\x2a",
+       "\xad\x0e\x3f\x29\x76\x70\x67\xe9\x29\xd1\xce\xcd\x95\x58\x2d\xf8\xf2\xa9\xbe\xb9\x2e\xaa\x27\xee\xb3\x15\xf6\x20\x36\x5a\x92\x44",
+       21 },
+      { GCRY_MD_SHA3_256,
+       "\x57\x08\x5f\xd7\xe1\x42\x16\xab\x10\x2d\x83\x17\xb0\xcb\x33\x8a\x78\x6d\x5f\xc3\x2d\x8f",
+       "\x2b\x4e\xb5\xde\x20\xe8\x60\x74\xca\xbb\x55\xbf\xa6\x3a\x5c\x8c\x6a\xe1\x56\x79\x30\x20\x61\x84\x5b\x9c\xf2\x33\xe1\x7c\x90\x6b",
+       22 },
+      { GCRY_MD_SHA3_256,
+       "\xa0\x54\x04\xdf\x5d\xbb\x57\x69\x7e\x2c\x16\xfa\x29\xde\xfa\xc8\xab\x35\x60\xd6\x12\x6f\xa0",
+       "\x6a\xe0\x4c\x6c\x6f\x36\x51\xf1\xf6\x4c\x0a\xd6\x97\x33\x99\x0b\x41\x74\x7c\x93\xf8\x7a\xcb\x81\x3b\xb2\x5b\xb1\xfc\x0e\xff\x07",
+       23 },
+      { GCRY_MD_SHA3_256,
+       "\xae\xcb\xb0\x27\x59\xf7\x43\x3d\x6f\xcb\x06\x96\x3c\x74\x06\x1c\xd8\x3b\x5b\x3f\xfa\x6f\x13\xc6",
+       "\x40\xf9\xf5\x5b\xc5\x5d\xa4\x66\xbc\x3d\xc1\xf8\x98\x35\xa6\x40\x94\x57\x2d\xe7\x3d\x64\xed\x66\x46\xa1\xd3\xb6\x67\xbe\x70\xa9",
+       24 },
+      { GCRY_MD_SHA3_256,
+       "\xaa\xfd\xc9\x24\x3d\x3d\x4a\x09\x65\x58\xa3\x60\xcc\x27\xc8\xd8\x62\xf0\xbe\x73\xdb\x5e\x88\xaa\x55",
+       "\xc6\x4b\xec\xf7\xb7\x5f\xc8\x85\xd5\x85\x39\x24\xf2\xb7\xd3\x7a\xbc\xef\xd3\xda\x12\x6b\xb8\x17\x69\x7e\x1a\x09\x15\x2b\x1e\xbe",
+       25 },
+      { GCRY_MD_SHA3_256,
+       "\x7b\xc8\x48\x67\xf6\xf9\xe9\xfd\xc3\xe1\x04\x6c\xae\x3a\x52\xc7\x7e\xd4\x85\x86\x0e\xe2\x60\xe3\x0b\x15",
+       "\x57\xd4\x6a\x6b\xc8\xfa\xb3\x36\x01\x53\x8d\xad\x27\xf9\x8c\x66\x44\x30\x32\xcc\x39\x12\x43\x4c\x28\xeb\x88\xd0\xaf\x44\xc5\x2c",
+       26 },
+      { GCRY_MD_SHA3_256,
+       "\xfa\xc5\x23\x57\x5a\x99\xec\x48\x27\x9a\x7a\x45\x9e\x98\xff\x90\x19\x18\xa4\x75\x03\x43\x27\xef\xb5\x58\x43",
+       "\x7c\x95\x65\x03\xd5\xb4\xdb\xb7\x64\xff\x8e\x66\xfa\x74\xce\x0f\x91\x32\xda\x90\xea\x35\x43\xf6\x69\xc9\xdd\x08\xe4\x13\xe3\x3c",
+       27 },
+      { GCRY_MD_SHA3_256,
+       "\x0f\x8b\x2d\x8f\xcf\xd9\xd6\x8c\xff\xc1\x7c\xcf\xb1\x17\x70\x9b\x53\xd2\x64\x62\xa3\xf3\x46\xfb\x7c\x79\xb8\x5e",
+       "\x6d\xe1\x64\xa9\x62\x6d\x5a\x4f\x54\xd8\x54\xac\x15\x89\x94\xf3\x5a\x8e\x36\x2e\xcc\x75\x3f\x55\x18\x27\x90\x93\x4a\x2e\x0d\x06",
+       28 },
+      { GCRY_MD_SHA3_256,
+       "\xa9\x63\xc3\xe8\x95\xff\x5a\x0b\xe4\x82\x44\x00\x51\x8d\x81\x41\x2f\x87\x5f\xa5\x05\x21\xe2\x6e\x85\xea\xc9\x0c\x04",
+       "\xb7\x60\x31\x2b\xd1\xb2\x79\xfc\x67\x24\x79\xd2\x1c\x5e\xd3\x49\xe5\xfe\x96\xf0\x89\x40\x23\x7b\x45\x15\x45\x27\x21\xc4\x9a\x16",
+       29 },
+      { GCRY_MD_SHA3_256,
+       "\x03\xa1\x86\x88\xb1\x0c\xc0\xed\xf8\x3a\xdf\x0a\x84\x80\x8a\x97\x18\x38\x3c\x40\x70\xc6\xc4\xf2\x95\x09\x86\x99\xac\x2c",
+       "\x94\xfc\x25\x5d\xe4\xef\x19\xc0\xda\x4b\x09\xb2\xe2\xfa\xc2\x1f\x20\x04\x8b\x46\xf1\x7c\x30\x68\x5a\xbe\x40\xd5\xc7\x43\xf3\x75",
+       30 },
+      { GCRY_MD_SHA3_256,
+       "\x84\xfb\x51\xb5\x17\xdf\x6c\x5a\xcc\xb5\xd0\x22\xf8\xf2\x8d\xa0\x9b\x10\x23\x2d\x42\x32\x0f\xfc\x32\xdb\xec\xc3\x83\x5b\x29",
+       "\x39\xa4\xa0\xff\xc4\x60\x36\x98\xae\x0a\x4f\x3d\x24\xb1\xbc\x42\xac\x7a\x2d\x7d\x92\x3e\x7a\x5d\x60\x24\x53\xe8\x2d\x53\x23\xc5",
+       31 },
+      { GCRY_MD_SHA3_256,
+       "\x9f\x2f\xcc\x7c\x90\xde\x09\x0d\x6b\x87\xcd\x7e\x97\x18\xc1\xea\x6c\xb2\x11\x18\xfc\x2d\x5d\xe9\xf9\x7e\x5d\xb6\xac\x1e\x9c\x10",
+       "\x2f\x1a\x5f\x71\x59\xe3\x4e\xa1\x9c\xdd\xc7\x0e\xbf\x9b\x81\xf1\xa6\x6d\xb4\x06\x15\xd7\xea\xd3\xcc\x1f\x1b\x95\x4d\x82\xa3\xaf",
+       32 },
+      { GCRY_MD_SHA3_256,
+       "\xde\x8f\x1b\x3f\xaa\x4b\x70\x40\xed\x45\x63\xc3\xb8\xe5\x98\x25\x31\x78\xe8\x7e\x4d\x0d\xf7\x5e\x4f\xf2\xf2\xde\xdd\x5a\x0b\xe0\x46",
+       "\x1c\x57\xfe\x0e\x38\xcd\x3a\x12\x4e\xaa\x6c\xd8\x7f\x70\xa0\x79\xbc\xcc\x07\x3a\x34\x1e\x8c\x0e\xb1\x97\x6f\xb3\xa3\xf7\xb7\x74",
+       33 },
+      { GCRY_MD_SHA3_256,
+       "\x62\xf1\x54\xec\x39\x4d\x0b\xc7\x57\xd0\x45\xc7\x98\xc8\xb8\x7a\x00\xe0\x65\x5d\x04\x81\xa7\xd2\xd9\xfb\x58\xd9\x3a\xed\xc6\x76\xb5\xa0",
+       "\xa9\x05\x60\x3b\x18\x6e\xf4\xf2\xd5\xb2\xd1\xbc\xfd\xa5\x04\xc6\x8e\xd5\xeb\x9b\x0c\x7b\x7e\xa2\xa0\x01\x57\x5f\x5a\xa6\x9e\x68",
+       34 },
+      { GCRY_MD_SHA3_256,
+       "\xb2\xdc\xfe\x9f\xf1\x9e\x2b\x23\xce\x7d\xa2\xa4\x20\x7d\x3e\x5e\xc7\xc6\x11\x2a\x8a\x22\xae\xc9\x67\x5a\x88\x63\x78\xe1\x4e\x5b\xfb\xad\x4e",
+       "\xff\xfd\x39\xf7\xc4\x51\x78\x8e\xb0\x31\x6f\x42\x9e\xa0\xa7\xc0\xac\x80\x91\x65\x7a\xca\x28\xf1\x56\x0e\xd5\x77\x5e\x8c\x4c\x12",
+       35 },
+      { GCRY_MD_SHA3_256,
+       "\x47\xf5\x69\x7a\xc8\xc3\x14\x09\xc0\x86\x88\x27\x34\x7a\x61\x3a\x35\x62\x04\x1c\x63\x3c\xf1\xf1\xf8\x68\x65\xa5\x76\xe0\x28\x35\xed\x2c\x24\x92",
+       "\x6f\x55\xbe\xcd\x16\x8e\x09\x39\xba\x2f\xa0\x90\x25\x7b\x17\x27\xfc\x66\x49\x1a\x44\x49\x32\x79\xa5\xbe\xac\xb9\xe3\x43\x53\x24",
+       36 },
+      { GCRY_MD_SHA3_256,
+       "\x51\x2a\x6d\x29\x2e\x67\xec\xb2\xfe\x48\x6b\xfe\x92\x66\x09\x53\xa7\x54\x84\xff\x4c\x4f\x2e\xca\x2b\x0a\xf0\xed\xcd\xd4\x33\x9c\x6b\x2e\xe4\xe5\x42",
+       "\x84\x64\x9b\xff\xcd\x48\x52\x7b\x92\x88\xe8\xda\x5f\x52\xfb\xab\x26\x04\xdc\x5a\x91\xc4\xb0\xb8\x7d\x47\x7d\xbd\x7b\x40\xb6\xae",
+       37 },
+      { GCRY_MD_SHA3_256,
+       "\x97\x3c\xf2\xb4\xdc\xf0\xbf\xa8\x72\xb4\x11\x94\xcb\x05\xbb\x4e\x16\x76\x0a\x18\x40\xd8\x34\x33\x01\x80\x25\x76\x19\x7e\xc1\x9e\x2a\x14\x93\xd8\xf4\xfb",
+       "\xd4\x05\x5b\x4e\x3e\x2a\xea\x1c\x67\xcc\x99\xfd\x40\x9d\x57\x4e\x53\xe1\xe2\x96\xcf\x9e\xef\x73\xc4\x72\xab\x92\xa6\xcb\x66\x09",
+       38 },
+      { GCRY_MD_SHA3_256,
+       "\x80\xbe\xeb\xcd\x2e\x3f\x8a\x94\x51\xd4\x49\x99\x61\xc9\x73\x1a\xe6\x67\xcd\xc2\x4e\xa0\x20\xce\x3b\x9a\xa4\xbb\xc0\xa7\xf7\x9e\x30\xa9\x34\x46\x7d\xa4\xb0",
+       "\x56\x94\xca\x2f\x3b\x99\x62\x22\x6a\x87\x16\x3a\xb3\x83\x25\xbc\xdc\x89\x8a\x73\x2d\xfe\xb2\xc3\x6d\xb4\xeb\x88\x61\x6b\x87\x41",
+       39 },
+      { GCRY_MD_SHA3_256,
+       "\x7a\xba\xa1\x2e\xc2\xa7\x34\x76\x74\xe4\x44\x14\x0a\xe0\xfb\x65\x9d\x08\xe1\xc6\x6d\xec\xd8\xd6\xea\xe9\x25\xfa\x45\x1d\x65\xf3\xc0\x30\x8e\x29\x44\x6b\x8e\xd3",
+       "\x8c\xf2\x87\xad\x03\xab\x4a\x74\x08\x66\x20\xcf\xa4\xcc\xe7\x4f\x48\xfa\x5c\xdb\x15\xec\x02\xb1\xf7\x21\x73\x6a\x4f\x84\x9e\x60",
+       40 },
+      { GCRY_MD_SHA3_256,
+       "\xc8\x8d\xee\x99\x27\x67\x9b\x8a\xf4\x22\xab\xcb\xac\xf2\x83\xb9\x04\xff\x31\xe1\xca\xc5\x8c\x78\x19\x80\x9f\x65\xd5\x80\x7d\x46\x72\x3b\x20\xf6\x7b\xa6\x10\xc2\xb7",
+       "\xc5\xd5\xaf\x22\xa4\xdf\x9a\xcd\x0c\x05\x6f\xa3\x0d\x8e\x24\x0b\x67\x9a\x20\xd4\xd2\x63\x02\x60\xf7\x79\xff\x81\x5c\xa8\x2d\x7d",
+       41 },
+      { GCRY_MD_SHA3_256,
+       "\x01\xe4\x3f\xe3\x50\xfc\xec\x45\x0e\xc9\xb1\x02\x05\x3e\x6b\x5d\x56\xe0\x98\x96\xe0\xdd\xd9\x07\x4f\xe1\x38\xe6\x03\x82\x10\x27\x0c\x83\x4c\xe6\xea\xdc\x2b\xb8\x6b\xf6",
+       "\x0a\xc7\x52\x79\xad\xff\x65\x66\x04\x64\x55\x0a\x28\x3f\xec\xd4\xe0\x61\x0d\x88\xf3\x55\x74\xc3\xd7\xac\x5d\x22\x26\x2a\x2f\xe8",
+       42 },
+      { GCRY_MD_SHA3_256,
+       "\x33\x70\x23\x37\x0a\x48\xb6\x2e\xe4\x35\x46\xf1\x7c\x4e\xf2\xbf\x8d\x7e\xcd\x1d\x49\xf9\x0b\xab\x60\x4b\x83\x9c\x2e\x6e\x5b\xd2\x15\x40\xd2\x9b\xa2\x7a\xb8\xe3\x09\xa4\xb7",
+       "\x81\x91\x7a\xe2\x90\xdb\xba\x17\x28\x9a\x8a\x67\xe5\xc2\xe8\xb1\x2d\x3d\xde\x0e\xfe\x9f\x99\x01\x98\xa1\x76\x3f\xf4\xf3\xdd\xa7",
+       43 },
+      { GCRY_MD_SHA3_256,
+       "\x68\x92\x54\x0f\x96\x4c\x8c\x74\xbd\x2d\xb0\x2c\x0a\xd8\x84\x51\x0c\xb3\x8a\xfd\x44\x38\xaf\x31\xfc\x91\x27\x56\xf3\xef\xec\x6b\x32\xb5\x8e\xbc\x38\xfc\x2a\x6b\x91\x35\x96\xa8",
+       "\x13\x8e\x75\xe7\x2f\xdd\xd9\x27\xe5\x91\x31\x5a\xf8\xd3\xab\xa2\x80\xef\xa3\x62\x30\xa3\x30\x9a\x97\xbc\xde\x5a\x78\xc3\x15\x89",
+       44 },
+      { GCRY_MD_SHA3_256,
+       "\xf5\x96\x1d\xfd\x2b\x1f\xff\xfd\xa4\xff\xbf\x30\x56\x0c\x16\x5b\xfe\xda\xb8\xce\x0b\xe5\x25\x84\x5d\xeb\x8d\xc6\x10\x04\xb7\xdb\x38\x46\x72\x05\xf5\xdc\xfb\x34\xa2\xac\xfe\x96\xc0",
+       "\x21\xbc\xda\xd3\xfe\xf3\xe5\xb8\x59\xcb\x09\x12\xa2\x99\x1e\xfa\x66\x1b\xad\x81\x27\x47\x29\x2e\xf0\xf7\x9a\x8f\xcc\x6b\x4e\x98",
+       45 },
+      { GCRY_MD_SHA3_256,
+       "\xca\x06\x1a\x2e\xb6\xce\xed\x88\x81\xce\x20\x57\x17\x2d\x86\x9d\x73\xa1\x95\x1e\x63\xd5\x72\x61\x38\x4b\x80\xce\xb5\x45\x1e\x77\xb0\x6c\xf0\xf5\xa0\xea\x15\xca\x90\x7e\xe1\xc2\x7e\xba",
+       "\x8d\x6f\xd9\xc5\x59\xb0\xb4\x94\x8f\x91\x33\x79\x16\x08\x4c\x00\x82\xa1\x6a\x07\x55\xb0\xa0\x08\x11\x09\x6e\x97\x3e\x48\xb3\xc8",
+       46 },
+      { GCRY_MD_SHA3_256,
+       "\x17\x43\xa7\x72\x51\xd6\x92\x42\x75\x0c\x4f\x11\x40\x53\x2c\xd3\xc3\x3f\x9b\x5c\xcd\xf7\x51\x4e\x85\x84\xd4\xa5\xf9\xfb\xd7\x30\xbc\xf8\x4d\x0d\x47\x26\x36\x4b\x9b\xf9\x5a\xb2\x51\xd9\xbb",
+       "\x1d\xd2\x3a\xe7\xaa\xdd\x61\xe7\x12\xbd\xd8\x2b\xd6\x0a\x70\xdd\x9d\x66\xc9\xfd\x79\xdb\xfd\x86\x69\xe3\xea\xab\xf7\x90\x1c\xdc",
+       47 },
+      { GCRY_MD_SHA3_256,
+       "\xd8\xfa\xba\x1f\x51\x94\xc4\xdb\x5f\x17\x6f\xab\xff\xf8\x56\x92\x4e\xf6\x27\xa3\x7c\xd0\x8c\xf5\x56\x08\xbb\xa8\xf1\xe3\x24\xd7\xc7\xf1\x57\x29\x8e\xab\xc4\xdc\xe7\xd8\x9c\xe5\x16\x24\x99\xf9",
+       "\x34\xf8\x60\x7e\xc1\x0c\x09\x2c\x1b\xa0\xb6\x56\x5c\xe6\x19\x70\x62\xc4\xe1\xa3\x5a\x8e\x8c\x72\x3e\x48\xa2\xd2\x41\x6c\x37\x90",
+       48 },
+      { GCRY_MD_SHA3_256,
+       "\xbe\x96\x84\xbe\x70\x34\x08\x60\x37\x3c\x9c\x48\x2b\xa5\x17\xe8\x99\xfc\x81\xba\xaa\x12\xe5\xc6\xd7\x72\x79\x75\xd1\xd4\x1b\xa8\xbe\xf7\x88\xcd\xb5\xcf\x46\x06\xc9\xc1\xc7\xf6\x1a\xed\x59\xf9\x7d",
+       "\x19\xa8\x57\x7f\xc9\x0f\xae\x5d\x6a\x6b\x2e\x0c\x1f\xf1\x55\x51\x55\x02\xcf\xa1\x75\x70\x29\xc0\x9b\xeb\xbf\xa2\x63\xd9\xa3\x63",
+       49 },
+      { GCRY_MD_SHA3_256,
+       "\x7e\x15\xd2\xb9\xea\x74\xca\x60\xf6\x6c\x8d\xfa\xb3\x77\xd9\x19\x8b\x7b\x16\xde\xb6\xa1\xba\x0e\xa3\xc7\xee\x20\x42\xf8\x9d\x37\x86\xe7\x79\xcf\x05\x3c\x77\x78\x5a\xa9\xe6\x92\xf8\x21\xf1\x4a\x7f\x51",
+       "\x9d\x9d\xbb\x4c\xe7\xd0\x1d\x00\x9e\x72\xa6\x60\x51\xac\xc1\x68\x05\xe4\x9f\x59\x8c\xbe\x43\x0c\x5d\x4c\x22\xa8\x81\xa6\x4b\x3f",
+       50 },
+      { GCRY_MD_SHA3_256,
+       "\x9a\x21\x9b\xe4\x37\x13\xbd\x57\x80\x15\xe9\xfd\xa6\x6c\x0f\x2d\x83\xca\xc5\x63\xb7\x76\xab\x9f\x38\xf3\xe4\xf7\xef\x22\x9c\xb4\x43\x30\x4f\xba\x40\x1e\xfb\x2b\xdb\xd7\xec\xe9\x39\x10\x22\x98\x65\x1c\x86",
+       "\x13\xf0\xd9\x51\xb6\x44\x81\x13\x54\x66\xcf\xcc\xbe\x52\x41\x8c\xc1\xd0\x3f\xb1\x6b\x5b\x69\x6c\x35\xd7\x24\xf6\xf5\x5c\xbb\x6d",
+       51 },
+      { GCRY_MD_SHA3_256,
+       "\xc8\xf2\xb6\x93\xbd\x0d\x75\xef\x99\xca\xeb\xdc\x22\xad\xf4\x08\x8a\x95\xa3\x54\x2f\x63\x72\x03\xe2\x83\xbb\xc3\x26\x87\x80\xe7\x87\xd6\x8d\x28\xcc\x38\x97\x45\x2f\x6a\x22\xaa\x85\x73\xcc\xeb\xf2\x45\x97\x2a",
+       "\xfb\x2f\xe7\xb0\x0b\x75\xc4\x23\x05\xcf\x31\xde\x14\xd9\x8f\x90\x4e\x8c\x46\xdc\x57\xbb\x6f\x94\xc2\x82\xca\x8c\x13\xdc\x45\xdb",
+       52 },
+      { GCRY_MD_SHA3_256,
+       "\xec\x0f\x99\x71\x10\x16\xc6\xa2\xa0\x7a\xd8\x0d\x16\x42\x75\x06\xce\x6f\x44\x10\x59\xfd\x26\x94\x42\xba\xaa\x28\xc6\xca\x03\x7b\x22\xee\xac\x49\xd5\xd8\x94\xc0\xbf\x66\x21\x9f\x2c\x08\xe9\xd0\xe8\xab\x21\xde\x52",
+       "\xd5\x4c\xbf\x7d\x5c\x80\xae\x11\xa0\xd0\xba\xd4\xe9\x5a\xb1\x8b\x5f\x07\xc9\x70\x62\x1f\x39\x36\x44\x7a\x48\xee\xf8\x18\xd0\x6e",
+       53 },
+      { GCRY_MD_SHA3_256,
+       "\x0d\xc4\x51\x81\x33\x7c\xa3\x2a\x82\x22\xfe\x7a\x3b\xf4\x2f\xc9\xf8\x97\x44\x25\x9c\xff\x65\x35\x04\xd6\x05\x1f\xe8\x4b\x1a\x7f\xfd\x20\xcb\x47\xd4\x69\x6c\xe2\x12\xa6\x86\xbb\x9b\xe9\xa8\xab\x1c\x69\x7b\x6d\x6a\x33",
+       "\xff\x05\x0a\x45\xad\xee\xf4\xcf\xc7\xd9\x64\x10\x2b\xa8\x77\xc8\x03\x20\xa3\x77\x94\x89\x3e\x68\x65\x96\x5e\xc2\x54\x7c\xd4\xc9",
+       54 },
+      { GCRY_MD_SHA3_256,
+       "\xde\x28\x6b\xa4\x20\x6e\x8b\x00\x57\x14\xf8\x0f\xb1\xcd\xfa\xeb\xde\x91\xd2\x9f\x84\x60\x3e\x4a\x3e\xbc\x04\x68\x6f\x99\xa4\x6c\x9e\x88\x0b\x96\xc5\x74\x82\x55\x82\xe8\x81\x2a\x26\xe5\xa8\x57\xff\xc6\x57\x9f\x63\x74\x2f",
+       "\x1b\xc1\xbc\xc7\x0f\x63\x89\x58\xdb\x10\x06\xaf\x37\xb0\x2e\xbd\x89\x54\xec\x59\xb3\xac\xba\xd1\x2e\xac\xed\xbc\x5b\x21\xe9\x08",
+       55 },
+      { GCRY_MD_SHA3_256,
+       "\xee\xbc\xc1\x80\x57\x25\x2c\xbf\x3f\x9c\x07\x0f\x1a\x73\x21\x33\x56\xd5\xd4\xbc\x19\xac\x2a\x41\x1e\xc8\xcd\xee\xe7\xa5\x71\xe2\xe2\x0e\xaf\x61\xfd\x0c\x33\xa0\xff\xeb\x29\x7d\xdb\x77\xa9\x7f\x0a\x41\x53\x47\xdb\x66\xbc\xaf",
+       "\xf7\xbd\xe2\x39\xad\x08\x7a\xa7\xda\xbe\x42\xcc\x4d\x3c\x49\x38\x0a\x02\x6c\xd2\x39\xa7\xfa\xaf\x34\xa2\x23\x34\x69\xa4\x4a\x4d",
+       56 },
+      { GCRY_MD_SHA3_256,
+       "\x41\x6b\x5c\xdc\x9f\xe9\x51\xbd\x36\x1b\xd7\xab\xfc\x12\x0a\x50\x54\x75\x8e\xba\x88\xfd\xd6\x8f\xd8\x4e\x39\xd3\xb0\x9a\xc2\x54\x97\xd3\x6b\x43\xcb\xe7\xb8\x5a\x6a\x3c\xeb\xda\x8d\xb4\xe5\x54\x9c\x3e\xe5\x1b\xb6\xfc\xb6\xac\x1e",
+       "\xef\x84\x5a\xac\x2a\xaf\x0a\x79\x31\x08\x20\x4f\xf3\x80\xe0\xa3\x0f\x25\x58\xe7\xac\xde\x45\x31\xab\x22\xf8\xec\x79\xe2\x6a\x69",
+       57 },
+      { GCRY_MD_SHA3_256,
+       "\x5c\x5f\xaf\x66\xf3\x2e\x0f\x83\x11\xc3\x2e\x8d\xa8\x28\x4a\x4e\xd6\x08\x91\xa5\xa7\xe5\x0f\xb2\x95\x6b\x3c\xba\xa7\x9f\xc6\x6c\xa3\x76\x46\x0e\x10\x04\x15\x40\x1f\xc2\xb8\x51\x8c\x64\x50\x2f\x18\x7e\xa1\x4b\xfc\x95\x03\x75\x97\x05",
+       "\x26\xdb\x51\x4e\x01\xe0\x34\xc6\x78\xb6\x36\xd4\x0b\xa3\x67\xda\x2f\x37\xf6\x70\x78\xbb\x57\x6f\xf2\xb8\x55\x9b\x35\x17\x48\x4d",
+       58 },
+      { GCRY_MD_SHA3_256,
+       "\x71\x67\xe1\xe0\x2b\xe1\xa7\xca\x69\xd7\x88\x66\x6f\x82\x3a\xe4\xee\xf3\x92\x71\xf3\xc2\x6a\x5c\xf7\xce\xe0\x5b\xca\x83\x16\x10\x66\xdc\x2e\x21\x7b\x33\x0d\xf8\x21\x10\x37\x99\xdf\x6d\x74\x81\x0e\xed\x36\x3a\xdc\x4a\xb9\x9f\x36\x04\x6a",
+       "\x5d\xbd\x4b\x55\x84\x63\x19\x62\x11\x46\x5c\x1f\xc3\x24\x01\xfc\x2d\x8e\x41\xeb\xc5\xe6\xba\xdd\x1d\x8f\x7c\x4f\x09\x0f\x72\x8f",
+       59 },
+      { GCRY_MD_SHA3_256,
+       "\x2f\xda\x31\x1d\xbb\xa2\x73\x21\xc5\x32\x95\x10\xfa\xe6\x94\x8f\x03\x21\x0b\x76\xd4\x3e\x74\x48\xd1\x68\x9a\x06\x38\x77\xb6\xd1\x4c\x4f\x6d\x0e\xaa\x96\xc1\x50\x05\x13\x71\xf7\xdd\x8a\x41\x19\xf7\xda\x5c\x48\x3c\xc3\xe6\x72\x3c\x01\xfb\x7d",
+       "\x35\x5c\x79\xfd\x6e\x6f\xa8\x8e\xd4\x02\xb6\x97\x9f\xde\x1e\xd8\x05\x49\x8a\xbe\xb1\x01\xf4\x23\x1b\x5d\x64\xd1\x43\x9d\x55\x2d",
+       60 },
+      { GCRY_MD_SHA3_256,
+       "\x95\xd1\x47\x4a\x5a\xab\x5d\x24\x22\xac\xa6\xe4\x81\x18\x78\x33\xa6\x21\x2b\xd2\xd0\xf9\x14\x51\xa6\x7d\xd7\x86\xdf\xc9\x1d\xfe\xd5\x1b\x35\xf4\x7e\x1d\xeb\x8a\x8a\xb4\xb9\xcb\x67\xb7\x01\x79\xcc\x26\xf5\x53\xae\x7b\x56\x99\x69\xce\x15\x1b\x8d",
+       "\x3d\x9c\x9b\xf0\x9d\x88\x21\x1c\x7e\x00\x56\x11\x2d\x07\x3e\xe8\x5d\x00\xac\xaa\x4d\xa7\xa6\x68\xfa\x01\x7b\x32\x73\xcd\x4d\x4b",
+       61 },
+      { GCRY_MD_SHA3_256,
+       "\xc7\x1b\xd7\x94\x1f\x41\xdf\x04\x4a\x29\x27\xa8\xff\x55\xb4\xb4\x67\xc3\x3d\x08\x9f\x09\x88\xaa\x25\x3d\x29\x4a\xdd\xbd\xb3\x25\x30\xc0\xd4\x20\x8b\x10\xd9\x95\x98\x23\xf0\xc0\xf0\x73\x46\x84\x00\x6d\xf7\x9f\x70\x99\x87\x0f\x6b\xf5\x32\x11\xa8\x8d",
+       "\x67\x98\x0d\x28\xe2\xe6\x58\xe7\xa2\x4a\x25\x93\xa2\x81\x67\xa1\x3d\x90\x7d\x06\xf4\x77\x29\xd4\x7c\xa4\xfe\x17\x72\xf8\xb3\xdf",
+       62 },
+      { GCRY_MD_SHA3_256,
+       "\xf5\x7c\x64\x00\x6d\x9e\xa7\x61\x89\x2e\x14\x5c\x99\xdf\x1b\x24\x64\x08\x83\xda\x79\xd9\xed\x52\x62\x85\x9d\xcd\xa8\xc3\xc3\x2e\x05\xb0\x3d\x98\x4f\x1a\xb4\xa2\x30\x24\x2a\xb6\xb7\x8d\x36\x8d\xc5\xaa\xa1\xe6\xd3\x49\x8d\x53\x37\x1e\x84\xb0\xc1\xd4\xba",
+       "\xa8\xdf\x6b\x76\xdf\x41\x99\x4f\x75\x93\xf1\xa8\x19\x67\xe7\x7e\xe1\x80\xe3\x11\x83\xd1\xc4\xa5\x69\xdb\x85\x4e\x61\xe9\x9b\x05",
+       63 },
+      { GCRY_MD_SHA3_256,
+       "\xe9\x26\xae\x8b\x0a\xf6\xe5\x31\x76\xdb\xff\xcc\x2a\x6b\x88\xc6\xbd\x76\x5f\x93\x9d\x3d\x17\x8a\x9b\xde\x9e\xf3\xaa\x13\x1c\x61\xe3\x1c\x1e\x42\xcd\xfa\xf4\xb4\xdc\xde\x57\x9a\x37\xe1\x50\xef\xbe\xf5\x55\x5b\x4c\x1c\xb4\x04\x39\xd8\x35\xa7\x24\xe2\xfa\xe7",
+       "\x27\xa6\x44\x1e\xe9\x39\xb4\x6e\x2c\x37\x8d\x7a\xfe\xb0\xe8\x91\xc4\x7a\x28\x12\x0e\x48\x8e\xff\x0a\xb7\x1a\xf0\x87\x88\xce\xb3",
+       64 },
+      { GCRY_MD_SHA3_256,
+       "\x16\xe8\xb3\xd8\xf9\x88\xe9\xbb\x04\xde\x9c\x96\xf2\x62\x78\x11\xc9\x73\xce\x4a\x52\x96\xb4\x77\x2c\xa3\xee\xfe\xb8\x0a\x65\x2b\xdf\x21\xf5\x0d\xf7\x9f\x32\xdb\x23\xf9\xf7\x3d\x39\x3b\x2d\x57\xd9\xa0\x29\x7f\x7a\x2f\x2e\x79\xcf\xda\x39\xfa\x39\x3d\xf1\xac\x00",
+       "\xc4\xbb\x06\x73\x83\x00\x2d\xb4\x4c\xa7\x73\x91\x8b\xb7\x41\x04\xb6\x04\xa5\x83\xe1\x2b\x06\xbe\x56\xc2\x70\xf8\xb4\x35\x12\xf2",
+       65 },
+      { GCRY_MD_SHA3_256,
+       "\xfc\x42\x4e\xeb\x27\xc1\x8a\x11\xc0\x1f\x39\xc5\x55\xd8\xb7\x8a\x80\x5b\x88\xdb\xa1\xdc\x2a\x42\xed\x5e\x2c\x0e\xc7\x37\xff\x68\xb2\x45\x6d\x80\xeb\x85\xe1\x17\x14\xfa\x3f\x8e\xab\xfb\x90\x6d\x3c\x17\x96\x4c\xb4\xf5\xe7\x6b\x29\xc1\x76\x5d\xb0\x3d\x91\xbe\x37\xfc",
+       "\xae\x77\x39\x15\xca\x64\x2d\x80\x41\x33\x30\xc9\xe0\xee\x9b\xd0\x66\x53\xc0\x02\x3c\x5c\x02\x77\x10\x0f\x3b\x15\x26\xea\xa5\x1d",
+       66 },
+      { GCRY_MD_SHA3_256,
+       "\xab\xe3\x47\x2b\x54\xe7\x27\x34\xbd\xba\x7d\x91\x58\x73\x64\x64\x25\x1c\x4f\x21\xb3\x3f\xbb\xc9\x2d\x7f\xac\x9a\x35\xc4\xe3\x32\x2f\xf0\x1d\x23\x80\xcb\xaa\x4e\xf8\xfb\x07\xd2\x1a\x21\x28\xb7\xb9\xf5\xb6\xd9\xf3\x4e\x13\xf3\x9c\x7f\xfc\x2e\x72\xe4\x78\x88\x59\x9b\xa5",
+       "\x1c\xf9\xd6\xce\x9c\xb6\x58\x55\x6b\x76\xcd\x7e\xba\x3e\x51\x39\x36\x99\xad\x50\x0b\x1a\xb3\xf5\x61\x72\x74\x8d\xb7\xf5\x96\x67",
+       67 },
+      { GCRY_MD_SHA3_256,
+       "\x36\xf9\xf0\xa6\x5f\x2c\xa4\x98\xd7\x39\xb9\x44\xd6\xef\xf3\xda\x5e\xbb\xa5\x7e\x7d\x9c\x41\x59\x8a\x2b\x0e\x43\x80\xf3\xcf\x4b\x47\x9e\xc2\x34\x8d\x01\x5f\xfe\x62\x56\x27\x35\x11\x15\x4a\xfc\xf3\xb4\xb4\xbf\x09\xd6\xc4\x74\x4f\xdd\x0f\x62\xd7\x50\x79\xd4\x40\x70\x6b\x05",
+       "\x8d\x60\xe8\x89\xe2\xb1\x02\x0d\xad\x4b\x52\x33\x01\xf5\xf6\xbb\xab\x6c\x78\x1a\xf2\x76\x08\x5a\xf6\x76\x55\x46\xfc\xfb\x95\xac",
+       68 },
+      { GCRY_MD_SHA3_256,
+       "\xab\xc8\x77\x63\xca\xe1\xca\x98\xbd\x8c\x5b\x82\xca\xba\x54\xac\x83\x28\x6f\x87\xe9\x61\x01\x28\xae\x4d\xe6\x8a\xc9\x5d\xf5\xe3\x29\xc3\x60\x71\x7b\xd3\x49\xf2\x6b\x87\x25\x28\x49\x2c\xa7\xc9\x4c\x2c\x1e\x1e\xf5\x6b\x74\xdb\xb6\x5c\x2a\xc3\x51\x98\x1f\xdb\x31\xd0\x6c\x77\xa4",
+       "\xdd\x4f\xf4\xb5\x30\x55\x2f\x48\xaf\x9a\x75\x30\xa6\x46\x48\x19\xed\x1a\x5b\x73\x30\x84\xf7\x09\xe4\x1d\xaf\x1a\xcb\x35\xec\xfd",
+       69 },
+      { GCRY_MD_SHA3_256,
+       "\x94\xf7\xca\x8e\x1a\x54\x23\x4c\x6d\x53\xcc\x73\x4b\xb3\xd3\x15\x0c\x8b\xa8\xc5\xf8\x80\xea\xb8\xd2\x5f\xed\x13\x79\x3a\x97\x01\xeb\xe3\x20\x50\x92\x86\xfd\x8e\x42\x2e\x93\x1d\x99\xc9\x8d\xa4\xdf\x7e\x70\xae\x44\x7b\xab\x8c\xff\xd9\x23\x82\xd8\xa7\x77\x60\xa2\x59\xfc\x4f\xbd\x72",
+       "\x7a\xc8\xd4\xbb\x53\xfc\x43\x4d\xd8\x71\x2d\xae\xfe\xb4\x74\x66\x8f\x54\x14\x18\xe6\xf6\x17\xdb\xa5\x23\xd8\x39\x2e\xb0\x76\x6e",
+       70 },
+      { GCRY_MD_SHA3_256,
+       "\x13\xbd\x28\x11\xf6\xed\x2b\x6f\x04\xff\x38\x95\xac\xee\xd7\xbe\xf8\xdc\xd4\x5e\xb1\x21\x79\x1b\xc1\x94\xa0\xf8\x06\x20\x6b\xff\xc3\xb9\x28\x1c\x2b\x30\x8b\x1a\x72\x9c\xe0\x08\x11\x9d\xd3\x06\x6e\x93\x78\xac\xdc\xc5\x0a\x98\xa8\x2e\x20\x73\x88\x00\xb6\xcd\xdb\xe5\xfe\x96\x94\xad\x6d",
+       "\xf7\xb0\xe1\x5a\x63\x23\x2a\x2b\x80\x0b\x23\xb3\x11\xd3\x57\x61\x7d\xdf\xd1\x29\x3e\x1f\xfe\x3f\x77\x26\x92\xad\xe3\x42\x71\x52",
+       71 },
+      { GCRY_MD_SHA3_256,
+       "\x1e\xed\x9c\xba\x17\x9a\x00\x9e\xc2\xec\x55\x08\x77\x3d\xd3\x05\x47\x7c\xa1\x17\xe6\xd5\x69\xe6\x6b\x5f\x64\xc6\xbc\x64\x80\x1c\xe2\x5a\x84\x24\xce\x4a\x26\xd5\x75\xb8\xa6\xfb\x10\xea\xd3\xfd\x19\x92\xed\xdd\xee\xc2\xeb\xe7\x15\x0d\xc9\x8f\x63\xad\xc3\x23\x7e\xf5\x7b\x91\x39\x7a\xa8\xa7",
+       "\xb3\xd0\x5a\xf7\xe8\xc4\x06\xa7\xc2\x70\x92\x23\x79\x1d\x3f\x5f\x4b\x31\x29\x32\x99\x93\x22\x00\x53\xa3\x62\x93\xac\x2b\x0e\x06",
+       72 },
+      { GCRY_MD_SHA3_256,
+       "\xba\x5b\x67\xb5\xec\x3a\x3f\xfa\xe2\xc1\x9d\xd8\x17\x6a\x2e\xf7\x5c\x0c\xd9\x03\x72\x5d\x45\xc9\xcb\x70\x09\xa9\x00\xc0\xb0\xca\x7a\x29\x67\xa9\x5a\xe6\x82\x69\xa6\xdb\xf8\x46\x6c\x7b\x68\x44\xa1\xd6\x08\xac\x66\x1f\x7e\xff\x00\x53\x8e\x32\x3d\xb5\xf2\xc6\x44\xb7\x8b\x2d\x48\xde\x1a\x08\xaa",
+       "\x6c\x47\xe2\xea\x4b\xa2\x9e\x17\x79\x2d\xef\xc4\xb7\x07\x75\x4c\x46\x64\xbd\xe1\x51\x68\xa5\x10\x0b\xf8\x81\xec\x7c\x02\xb2\x58",
+       73 },
+      { GCRY_MD_SHA3_256,
+       "\x0e\xfa\x26\xac\x56\x73\x16\x7d\xca\xca\xb8\x60\x93\x2e\xd6\x12\xf6\x5f\xf4\x9b\x80\xfa\x9a\xe6\x54\x65\xe5\x54\x2c\xb6\x20\x75\xdf\x1c\x5a\xe5\x4f\xba\x4d\xb8\x07\xbe\x25\xb0\x70\x03\x3e\xfa\x22\x3b\xdd\x5b\x1d\x3c\x94\xc6\xe1\x90\x9c\x02\xb6\x20\xd4\xb1\xb3\xa6\xc9\xfe\xd2\x4d\x70\x74\x96\x04",
+       "\x82\xa6\x6b\xed\x66\x8d\xcc\x14\xaf\x12\xc1\x4c\x97\x6c\xe6\x50\x04\x9e\x9d\x1d\x99\x69\xb8\x3d\x1d\xd3\xb6\xf1\xc0\x7d\x25\x2b",
+       74 },
+      { GCRY_MD_SHA3_256,
+       "\xbb\xfd\x93\x3d\x1f\xd7\xbf\x59\x4a\xc7\xf4\x35\x27\x7d\xc1\x7d\x8d\x5a\x5b\x8e\x4d\x13\xd9\x6d\x2f\x64\xe7\x71\xab\xbd\x51\xa5\xa8\xae\xa7\x41\xbe\xcc\xbd\xdb\x17\x7b\xce\xa0\x52\x43\xeb\xd0\x03\xcf\xde\xae\x87\x7c\xca\x4d\xa9\x46\x05\xb6\x76\x91\x91\x9d\x8b\x03\x3f\x77\xd3\x84\xca\x01\x59\x3c\x1b",
+       "\x2f\x21\xd0\x7d\x7b\x10\x68\x3b\x9a\xc7\xa6\x3e\x9f\xcc\x70\xcf\x9f\x88\x7c\xb9\x05\xf9\xbf\xf5\x33\x25\x51\x28\x8b\x28\x85\x24",
+       75 },
+      { GCRY_MD_SHA3_256,
+       "\x90\x07\x89\x99\xfd\x3c\x35\xb8\xaf\xbf\x40\x66\xcb\xde\x33\x58\x91\x36\x5f\x0f\xc7\x5c\x12\x86\xcd\xd8\x8f\xa5\x1f\xab\x94\xf9\xb8\xde\xf7\xc9\xac\x58\x2a\x5d\xbc\xd9\x58\x17\xaf\xb7\xd1\xb4\x8f\x63\x70\x4e\x19\xc2\xba\xa4\xdf\x34\x7f\x48\xd4\xa6\xd6\x03\x01\x3c\x23\xf1\xe9\x61\x1d\x59\x5e\xba\xc3\x7c",
+       "\x80\x20\x2f\x01\xe7\x14\x0d\xb4\xfe\xe4\x90\xdc\xc5\x0a\xfa\xfd\xf6\xa4\x8c\xa3\x3d\x36\x2c\x78\x75\xb8\xe8\xdb\x9c\x9d\x06\x55",
+       76 },
+      { GCRY_MD_SHA3_256,
+       "\x64\x10\x5e\xca\x86\x35\x15\xc2\x0e\x7c\xfb\xaa\x0a\x0b\x88\x09\x04\x61\x64\xf3\x74\xd6\x91\xcd\xbd\x65\x08\xaa\xab\xc1\x81\x9f\x9a\xc8\x4b\x52\xba\xfc\x1b\x0f\xe7\xcd\xdb\xc5\x54\xb6\x08\xc0\x1c\x89\x04\xc6\x69\xd8\xdb\x31\x6a\x09\x53\xa4\xc6\x8e\xce\x32\x4e\xc5\xa4\x9f\xfd\xb5\x9a\x1b\xd6\xa2\x92\xaa\x0e",
+       "\xb2\x33\x0a\x18\x90\x47\xe3\x11\x74\x79\xa2\xf2\x0b\x34\x07\xa7\xd1\x19\xe4\xad\x43\x1f\xe0\x6f\xf1\xff\x2a\x10\x6f\x2a\xb3\xa2",
+       77 },
+      { GCRY_MD_SHA3_256,
+       "\xd4\x65\x4b\xe2\x88\xb9\xf3\xb7\x11\xc2\xd0\x20\x15\x97\x8a\x8c\xc5\x74\x71\xd5\x68\x0a\x09\x2a\xa5\x34\xf7\x37\x2c\x71\xce\xaa\xb7\x25\xa3\x83\xc4\xfc\xf4\xd8\xde\xaa\x57\xfc\xa3\xce\x05\x6f\x31\x29\x61\xec\xcf\x9b\x86\xf1\x49\x81\xba\x5b\xed\x6a\xb5\xb4\x49\x8e\x1f\x6c\x82\xc6\xca\xe6\xfc\x14\x84\x5b\x3c\x8a",
+       "\xbb\x9b\x9b\xb6\x85\xc2\x41\xf8\xd6\x3f\xdb\xf0\xdb\xaa\xbc\xef\x70\x75\xad\xd7\xba\x40\x5a\x2f\xff\xe7\xad\x5b\x23\xe0\x21\xc7",
+       78 },
+      { GCRY_MD_SHA3_256,
+       "\x12\xd9\x39\x48\x88\x30\x5a\xc9\x6e\x65\xf2\xbf\x0e\x1b\x18\xc2\x9c\x90\xfe\x9d\x71\x4d\xd5\x9f\x65\x1f\x52\xb8\x8b\x30\x08\xc5\x88\x43\x55\x48\x06\x6e\xa2\xfc\x4c\x10\x11\x18\xc9\x1f\x32\x55\x62\x24\xa5\x40\xde\x6e\xfd\xdb\xca\x29\x6e\xf1\xfb\x00\x34\x1f\x5b\x01\xfe\xcf\xc1\x46\xbd\xb2\x51\xb3\xbd\xad\x55\x6c\xd2",
+       "\xf8\x31\x6a\x36\x7a\xa0\x31\x6d\xa3\x56\x2f\x31\x9d\x52\x2e\x81\xf4\xa8\xbd\x2e\x21\x08\xd2\x53\x21\x26\xf4\xa9\x03\x70\x4b\xa3",
+       79 },
+      { GCRY_MD_SHA3_256,
+       "\x87\x1a\x0d\x7a\x5f\x36\xc3\xda\x1d\xfc\xe5\x7a\xcd\x8a\xb8\x48\x7c\x27\x4f\xad\x33\x6b\xc1\x37\xeb\xd6\xff\x46\x58\xb5\x47\xc1\xdc\xfa\xb6\x5f\x03\x7a\xa5\x8f\x35\xef\x16\xaf\xf4\xab\xe7\x7b\xa6\x1f\x65\x82\x6f\x7b\xe6\x81\xb5\xb6\xd5\xa1\xea\x80\x85\xe2\xae\x9c\xd5\xcf\x09\x91\x87\x8a\x31\x1b\x54\x9a\x6d\x6a\xf2\x30",
+       "\x89\xe3\xeb\xd0\x2b\x22\x9c\xd7\x59\x61\x2a\x55\x21\xd8\x67\xab\x2a\x15\x94\xbc\x0b\x1f\xe6\xa7\x8b\x79\x54\xcc\xc8\x4c\xaf\x03",
+       80 },
+      { GCRY_MD_SHA3_256,
+       "\xe9\x0b\x4f\xfe\xf4\xd4\x57\xbc\x77\x11\xff\x4a\xa7\x22\x31\xca\x25\xaf\x6b\x2e\x20\x6f\x8b\xf8\x59\xd8\x75\x8b\x89\xa7\xcd\x36\x10\x5d\xb2\x53\x8d\x06\xda\x83\xba\xd5\xf6\x63\xba\x11\xa5\xf6\xf6\x1f\x23\x6f\xd5\xf8\xd5\x3c\x5e\x89\xf1\x83\xa3\xce\xc6\x15\xb5\x0c\x7c\x68\x1e\x77\x3d\x10\x9f\xf7\x49\x1b\x5c\xc2\x22\x96\xc5",
+       "\x2e\x7c\xc8\x75\x30\x5e\xa6\xbb\x9c\x2f\xc7\x70\xb9\xd8\x4f\xd9\x3b\x96\x40\x5d\xf9\xb9\x33\x07\xf6\xb5\xde\x26\xe1\x35\x72\x4c",
+       81 },
+      { GCRY_MD_SHA3_256,
+       "\xe7\x28\xde\x62\xd7\x58\x56\x50\x0c\x4c\x77\xa4\x28\x61\x2c\xd8\x04\xf3\x0c\x3f\x10\xd3\x6f\xb2\x19\xc5\xca\x0a\xa3\x07\x26\xab\x19\x0e\x5f\x3f\x27\x9e\x07\x33\xd7\x7e\x72\x67\xc1\x7b\xe2\x7d\x21\x65\x0a\x9a\x4d\x1e\x32\xf6\x49\x62\x76\x38\xdb\xad\xa9\x70\x2c\x7c\xa3\x03\x26\x9e\xd1\x40\x14\xb2\xf3\xcf\x8b\x89\x4e\xac\x85\x54",
+       "\xec\xab\x75\xf2\x8a\x72\x84\x29\xcb\x43\x3e\xc1\x33\x10\xd1\xb8\x50\xcc\xf5\x22\xc3\x8d\x2f\xa6\xdf\xa4\x89\x96\x3d\x6d\x6c\xa7",
+       82 },
+      { GCRY_MD_SHA3_256,
+       "\x63\x48\xf2\x29\xe7\xb1\xdf\x3b\x77\x0c\x77\x54\x4e\x51\x66\xe0\x81\x85\x0f\xa1\xc6\xc8\x81\x69\xdb\x74\xc7\x6e\x42\xeb\x98\x3f\xac\xb2\x76\xad\x6a\x0d\x1f\xa7\xb5\x0d\x3e\x3b\x6f\xcd\x79\x9e\xc9\x74\x70\x92\x0a\x7a\xbe\xd4\x7d\x28\x8f\xf8\x83\xe2\x4c\xa2\x1c\x7f\x80\x16\xb9\x3b\xb9\xb9\xe0\x78\xbd\xb9\x70\x3d\x2b\x78\x1b\x61\x6e",
+       "\x02\x1c\x94\x59\xd1\x45\x1f\x3d\xa4\xc0\x7c\x02\x9a\x86\x81\x94\x5c\x87\xc5\xbe\xbc\x6c\x30\xda\x1d\x95\xc5\xc4\x9d\x8a\xb9\x5c",
+       83 },
+      { GCRY_MD_SHA3_256,
+       "\x4b\x12\x7f\xde\x5d\xe7\x33\xa1\x68\x0c\x27\x90\x36\x36\x27\xe6\x3a\xc8\xa3\xf1\xb4\x70\x7d\x98\x2c\xae\xa2\x58\x65\x5d\x9b\xf1\x8f\x89\xaf\xe5\x41\x27\x48\x2b\xa0\x1e\x08\x84\x55\x94\xb6\x71\x30\x6a\x02\x5c\x9a\x5c\x5b\x6f\x93\xb0\xa3\x95\x22\xdc\x87\x74\x37\xbe\x5c\x24\x36\xcb\xf3\x00\xce\x7a\xb6\x74\x79\x34\xfc\xfc\x30\xae\xaa\xf6",
+       "\x46\x42\xe2\x16\x22\xf1\x5b\x09\xb9\x41\x36\x59\x68\x01\x16\xbf\x2f\x96\xca\xc2\x38\x4b\x8c\x79\xf1\x32\x8d\x5d\xd3\x6d\x7a\x01",
+       84 },
+      { GCRY_MD_SHA3_256,
+       "\x08\x46\x1f\x00\x6c\xff\x4c\xc6\x4b\x75\x2c\x95\x72\x87\xe5\xa0\xfa\xab\xc0\x5c\x9b\xff\x89\xd2\x3f\xd9\x02\xd3\x24\xc7\x99\x03\xb4\x8f\xcb\x8f\x8f\x4b\x01\xf3\xe4\xdd\xb4\x83\x59\x3d\x25\xf0\x00\x38\x66\x98\xf5\xad\xe7\xfa\xad\xe9\x61\x5f\xdc\x50\xd3\x27\x85\xea\x51\xd4\x98\x94\xe4\x5b\xaa\x3d\xc7\x07\xe2\x24\x68\x8c\x64\x08\xb6\x8b\x11",
+       "\x8d\xaa\x47\xc3\x57\x21\x57\x26\x6a\xd0\x27\x6d\x59\x26\xaf\xf2\x87\x2f\x06\xb0\xcd\x7b\x97\x4a\x80\xd7\xa6\x82\x7d\x41\xd7\x82",
+       85 },
+      { GCRY_MD_SHA3_256,
+       "\x68\xc8\xf8\x84\x9b\x12\x0e\x6e\x0c\x99\x69\xa5\x86\x6a\xf5\x91\xa8\x29\xb9\x2f\x33\xcd\x9a\x4a\x31\x96\x95\x7a\x14\x8c\x49\x13\x8e\x1e\x2f\x5c\x76\x19\xa6\xd5\xed\xeb\xe9\x95\xac\xd8\x1e\xc8\xbb\x9c\x7b\x9c\xfc\xa6\x78\xd0\x81\xea\x9e\x25\xa7\x5d\x39\xdb\x04\xe1\x8d\x47\x59\x20\xce\x82\x8b\x94\xe7\x22\x41\xf2\x4d\xb7\x25\x46\xb3\x52\xa0\xe4",
+       "\x34\x53\x65\x23\x2c\xe9\xaf\xc6\x55\xdc\xe4\xba\xc2\x3f\x43\xc8\xac\xbd\xf9\x01\x6d\x4b\xc2\x34\x4b\xe8\xd3\x96\xa4\x91\x9c\x34",
+       86 },
+      { GCRY_MD_SHA3_256,
+       "\xb8\xd5\x64\x72\x95\x4e\x31\xfb\x54\xe2\x8f\xca\x74\x3f\x84\xd8\xdc\x34\x89\x1c\xb5\x64\xc6\x4b\x08\xf7\xb7\x16\x36\xde\xbd\x64\xca\x1e\xdb\xdb\xa7\xfc\x5c\x3e\x40\x04\x9c\xe9\x82\xbb\xa8\xc7\xe0\x70\x30\x34\xe3\x31\x38\x46\x95\xe9\xde\x76\xb5\x10\x4f\x2f\xbc\x45\x35\xec\xbe\xeb\xc3\x3b\xc2\x7f\x29\xf1\x8f\x6f\x27\xe8\x02\x3b\x0f\xbb\x6f\x56\x3c",
+       "\xf5\x2e\x10\x2e\x57\x29\x38\x78\xc2\x8f\x29\xde\xb4\x77\x92\x32\x4f\xe4\x55\xa6\x2f\xa7\x44\x1a\xab\xcc\x16\xa9\xcf\xc4\x0f\xfa",
+       87 },
+      { GCRY_MD_SHA3_256,
+       "\x0d\x58\xac\x66\x5f\xa8\x43\x42\xe6\x0c\xef\xee\x31\xb1\xa4\xea\xcd\xb0\x92\xf1\x22\xdf\xc6\x83\x09\x07\x7a\xed\x1f\x3e\x52\x8f\x57\x88\x59\xee\x9e\x4c\xef\xb4\xa7\x28\xe9\x46\x32\x49\x27\xb6\x75\xcd\x4f\x4a\xc8\x4f\x64\xdb\x3d\xac\xfe\x85\x0c\x1d\xd1\x87\x44\xc7\x4c\xec\xcd\x9f\xe4\xdc\x21\x40\x85\x10\x8f\x40\x4e\xab\x6d\x8f\x45\x2b\x54\x42\xa4\x7d",
+       "\x2b\x89\xaa\x88\xb1\xb7\xf9\xf8\xea\x46\x1c\x4c\x5c\xae\x48\x29\x12\x5f\x45\xf5\x69\x7d\xea\xdb\x8d\xb2\xe9\x64\x52\x4c\x0d\x91",
+       88 },
+      { GCRY_MD_SHA3_256,
+       "\x17\x55\xe2\xd2\xe5\xd1\xc1\xb0\x15\x64\x56\xb5\x39\x75\x3f\xf4\x16\x65\x1d\x44\x69\x8e\x87\x00\x2d\xcf\x61\xdc\xfa\x2b\x4e\x72\xf2\x64\xd9\xad\x59\x1d\xf1\xfd\xee\x7b\x41\xb2\xeb\x00\x28\x3c\x5a\xeb\xb3\x41\x13\x23\xb6\x72\xea\xa1\x45\xc5\x12\x51\x85\x10\x4f\x20\xf3\x35\x80\x4b\x02\x32\x5b\x6d\xea\x65\x60\x3f\x34\x9f\x4d\x5d\x8b\x78\x2d\xd3\x46\x9c\xcd",
+       "\x3f\x30\x92\x36\x59\x82\xc0\xb4\x27\x80\x55\xbe\xee\x90\x32\xff\x9d\x10\x60\xe0\x3c\x3b\x08\x7e\x1a\x61\x97\xde\xfc\x70\x7e\x1a",
+       89 },
+      { GCRY_MD_SHA3_256,
+       "\xb1\x80\xde\x1a\x61\x11\x11\xee\x75\x84\xba\x2c\x4b\x02\x05\x98\xcd\x57\x4a\xc7\x7e\x40\x4e\x85\x3d\x15\xa1\x01\xc6\xf5\xa2\xe5\xc8\x01\xd7\xd8\x5d\xc9\x52\x86\xa1\x80\x4c\x87\x0b\xb9\xf0\x0f\xd4\xdc\xb0\x3a\xa8\x32\x82\x75\x15\x88\x19\xdc\xad\x72\x53\xf3\xe3\xd2\x37\xae\xaa\x79\x79\x26\x8a\x5d\xb1\xc6\xce\x08\xa9\xec\x7c\x25\x79\x78\x3c\x8a\xfc\x1f\x91\xa7",
+       "\x3c\x74\xaa\xe2\xf3\x40\xa2\x41\x78\xcb\xab\x51\x00\x4c\xba\x1a\xac\x3d\x91\x13\x3c\x30\x07\x15\xea\x82\xc1\x77\x26\x9c\x05\x56",
+       90 },
+      { GCRY_MD_SHA3_256,
+       "\xcf\x35\x83\xcb\xdf\xd4\xcb\xc1\x70\x63\xb1\xe7\xd9\x0b\x02\xf0\xe6\xe2\xee\x05\xf9\x9d\x77\xe2\x4e\x56\x03\x92\x53\x5e\x47\xe0\x50\x77\x15\x7f\x96\x81\x35\x44\xa1\x70\x46\x91\x4f\x9e\xfb\x64\x76\x2a\x23\xcf\x7a\x49\xfe\x52\xa0\xa4\xc0\x1c\x63\x0c\xfe\x87\x27\xb8\x1f\xb9\x9a\x89\xff\x7c\xc1\x1d\xca\x51\x73\x05\x7e\x04\x17\xb8\xfe\x7a\x9e\xfb\xa6\xd9\x5c\x55\x5f",
+       "\x01\x57\xc4\xba\x44\x61\x8d\xed\x11\xe9\x80\x0a\xfa\x07\xa0\xd5\xb6\xc7\x11\xfc\x16\xa5\x76\xc5\xed\xb7\x1c\x4c\xc6\x89\x4f\x82",
+       91 },
+      { GCRY_MD_SHA3_256,
+       "\x07\x2f\xc0\x23\x40\xef\x99\x11\x5b\xad\x72\xf9\x2c\x01\xe4\xc0\x93\xb9\x59\x9f\x6c\xfc\x45\xcb\x38\x0e\xe6\x86\xcb\x5e\xb0\x19\xe8\x06\xab\x9b\xd5\x5e\x63\x4a\xb1\x0a\xa6\x2a\x95\x10\xcc\x06\x72\xcd\x3e\xdd\xb5\x89\xc7\xdf\x2b\x67\xfc\xd3\x32\x9f\x61\xb1\xa4\x44\x1e\xca\x87\xa3\x3c\x8f\x55\xda\x4f\xbb\xad\x5c\xf2\xb2\x52\x7b\x8e\x98\x3b\xb3\x1a\x2f\xad\xec\x75\x23",
+       "\x8d\x53\xdb\xa1\x07\xaa\xac\xb8\x42\x2d\x66\x67\xf6\x77\x88\x39\xf8\x96\x5f\x8e\x4c\x8f\x4a\x85\x12\x84\xcc\x91\x16\x8a\x90\x30",
+       92 },
+      { GCRY_MD_SHA3_256,
+       "\x76\xee\xcf\x95\x6a\x52\x64\x9f\x87\x75\x28\x14\x6d\xe3\x3d\xf2\x49\xcd\x80\x0e\x21\x83\x0f\x65\xe9\x0f\x0f\x25\xca\x9d\x65\x40\xfd\xe4\x06\x03\x23\x0e\xca\x67\x60\xf1\x13\x9c\x7f\x26\x8d\xeb\xa2\x06\x06\x31\xee\xa9\x2b\x1f\xff\x05\xf9\x3f\xd5\x57\x2f\xbe\x29\x57\x9e\xcd\x48\xbc\x3a\x8d\x6c\x2e\xb4\xa6\xb2\x6e\x38\xd6\xc5\xfb\xf2\xc0\x80\x44\xae\xea\x47\x0a\x8f\x2f\x26",
+       "\x51\x63\xf0\x22\x33\xe3\x32\xad\x9b\xe3\x2c\x23\x46\xc9\xfc\xfe\x39\xaf\xa5\xfb\xe9\xbc\x1c\xfe\xb9\x2f\x49\x20\x15\x5b\x20\xec",
+       93 },
+      { GCRY_MD_SHA3_256,
+       "\x7a\xdc\x0b\x66\x93\xe6\x1c\x26\x9f\x27\x8e\x69\x44\xa5\xa2\xd8\x30\x09\x81\xe4\x00\x22\xf8\x39\xac\x64\x43\x87\xbf\xac\x90\x86\x65\x00\x85\xc2\xcd\xc5\x85\xfe\xa4\x7b\x9d\x2e\x52\xd6\x5a\x2b\x29\xa7\xdc\x37\x04\x01\xef\x5d\x60\xdd\x0d\x21\xf9\xe2\xb9\x0f\xae\x91\x93\x19\xb1\x4b\x8c\x55\x65\xb0\x42\x3c\xef\xb8\x27\xd5\xf1\x20\x33\x02\xa9\xd0\x15\x23\x49\x8a\x4d\xb1\x03\x74",
+       "\xfa\xaf\x0e\x95\x21\x7c\xa4\xb1\x56\x87\x51\xef\x2e\x4c\xd3\x41\xd9\xec\x33\xe1\x66\x00\xbf\x09\xb9\x2c\x6f\x1a\x6d\xf8\x4d\x2e",
+       94 },
+      { GCRY_MD_SHA3_256,
+       "\xe1\xff\xfa\x98\x26\xcc\xe8\xb8\x6b\xcc\xef\xb8\x79\x4e\x48\xc4\x6c\xdf\x37\x20\x13\xf7\x82\xec\xed\x1e\x37\x82\x69\xb7\xbe\x2b\x7b\xf5\x13\x74\x09\x22\x61\xae\x12\x0e\x82\x2b\xe6\x85\xf2\xe7\xa8\x36\x64\xbc\xfb\xe3\x8f\xe8\x63\x3f\x24\xe6\x33\xff\xe1\x98\x8e\x1b\xc5\xac\xf5\x9a\x58\x70\x79\xa5\x7a\x91\x0b\xda\x60\x06\x0e\x85\xb5\xf5\xb6\xf7\x76\xf0\x52\x96\x39\xd9\xcc\xe4\xbd",
+       "\xb2\xc1\x75\xd9\xd9\x2a\xaa\x9e\xe7\x26\x72\xf9\x95\xb8\xdf\xd2\xda\xaf\x65\x55\xa0\x32\x7a\x50\x82\x18\xa9\xb4\x47\xf0\x0b\xe8",
+       95 },
+      { GCRY_MD_SHA3_256,
+       "\x69\xf9\xab\xba\x65\x59\x2e\xe0\x1d\xb4\xdc\xe5\x2d\xba\xb9\x0b\x08\xfc\x04\x19\x36\x02\x79\x2e\xe4\xda\xa2\x63\x03\x3d\x59\x08\x15\x87\xb0\x9b\xbe\x49\xd0\xb4\x9c\x98\x25\xd2\x28\x40\xb2\xff\x5d\x9c\x51\x55\xf9\x75\xf8\xf2\xc2\xe7\xa9\x0c\x75\xd2\xe4\xa8\x04\x0f\xe3\x9f\x63\xbb\xaf\xb4\x03\xd9\xe2\x8c\xc3\xb8\x6e\x04\xe3\x94\xa9\xc9\xe8\x06\x5b\xd3\xc8\x5f\xa9\xf0\xc7\x89\x16\x00",
+       "\xfb\x53\x88\x12\x23\x06\xd3\x7c\xee\x79\x0c\xad\x1d\x3c\xdd\xba\x8e\x9a\x93\xd5\xf9\xd7\x82\x88\xb0\x52\x48\x27\x39\xc8\x83\xfd",
+       96 },
+      { GCRY_MD_SHA3_256,
+       "\x38\xa1\x0a\x35\x2c\xa5\xae\xdf\xa8\xe1\x9c\x64\x78\x7d\x8e\x9c\x3a\x75\xdb\xf3\xb8\x67\x4b\xfa\xb2\x9b\x5d\xbf\xc1\x5a\x63\xd1\x0f\xae\x66\xcd\x1a\x6e\x6d\x24\x52\xd5\x57\x96\x7e\xaa\xd8\x9a\x4c\x98\x44\x97\x87\xb0\xb3\x16\x4c\xa5\xb7\x17\xa9\x3f\x24\xeb\x0b\x50\x6c\xeb\x70\xcb\xbc\xb8\xd7\x2b\x2a\x72\x99\x3f\x90\x9a\xad\x92\xf0\x44\xe0\xb5\xa2\xc9\xac\x9c\xb1\x6a\x0c\xa2\xf8\x1f\x49",
+       "\x1c\x2f\x8d\x41\x8f\xf6\x71\x8b\x18\xdd\x4c\x75\x6d\xcc\x8e\xd0\xf4\x75\x5e\x8c\x22\x49\x7a\x6c\xc1\x9f\x8d\x7a\xe7\xfd\x2d\xa7",
+       97 },
+      { GCRY_MD_SHA3_256,
+       "\x6d\x8c\x6e\x44\x9b\xc1\x36\x34\xf1\x15\x74\x9c\x24\x8c\x17\xcd\x14\x8b\x72\x15\x7a\x2c\x37\xbf\x89\x69\xea\x83\xb4\xd6\xba\x8c\x0e\xe2\x71\x1c\x28\xee\x11\x49\x5f\x43\x04\x95\x96\x52\x0c\xe4\x36\x00\x4b\x02\x6b\x6c\x1f\x72\x92\xb9\xc4\x36\xb0\x55\xcb\xb7\x2d\x53\x0d\x86\x0d\x12\x76\xa1\x50\x2a\x51\x40\xe3\xc3\xf5\x4a\x93\x66\x3e\x4d\x20\xed\xec\x32\xd2\x84\xe2\x55\x64\xf6\x24\x95\x5b\x52",
+       "\x7e\xa8\x11\x6e\x64\x34\xc1\xca\xa0\x49\x06\x9d\xbb\xd9\xb6\xf0\xe9\xdc\x6c\xdf\xd6\xa8\x89\x34\x3d\x3b\x26\x52\x80\x30\x78\xfc",
+       98 },
+      { GCRY_MD_SHA3_256,
+       "\x6e\xfc\xbc\xaf\x45\x1c\x12\x9d\xbe\x00\xb9\xce\xf0\xc3\x74\x9d\x3e\xe9\xd4\x1c\x7b\xd5\x00\xad\xe4\x0c\xdc\x65\xde\xdb\xbb\xad\xb8\x85\xa5\xb1\x4b\x32\xa0\xc0\xd0\x87\x82\x52\x01\xe3\x03\x28\x8a\x73\x38\x42\xfa\x7e\x59\x9c\x0c\x51\x4e\x07\x8f\x05\xc8\x21\xc7\xa4\x49\x8b\x01\xc4\x00\x32\xe9\xf1\x87\x2a\x1c\x92\x5f\xa1\x7c\xe2\x53\xe8\x93\x5e\x4c\x3c\x71\x28\x22\x42\xcb\x71\x6b\x20\x89\xcc\xc1",
+       "\x73\x6d\x88\x87\x51\xfa\xac\x4d\x8e\x78\xb4\x5b\x95\xab\xb1\x5d\x40\xd9\x8d\x80\x38\xc7\x22\x5b\xe0\xf5\x23\xd5\x43\x9e\xa5\xb6",
+       99 },
+      { GCRY_MD_SHA3_256,
+       "\x43\x3c\x53\x03\x13\x16\x24\xc0\x02\x1d\x86\x8a\x30\x82\x54\x75\xe8\xd0\xbd\x30\x52\xa0\x22\x18\x03\x98\xf4\xca\x44\x23\xb9\x82\x14\xb6\xbe\xaa\xc2\x1c\x88\x07\xa2\xc3\x3f\x8c\x93\xbd\x42\xb0\x92\xcc\x1b\x06\xce\xdf\x32\x24\xd5\xed\x1e\xc2\x97\x84\x44\x4f\x22\xe0\x8a\x55\xaa\x58\x54\x2b\x52\x4b\x02\xcd\x3d\x5d\x5f\x69\x07\xaf\xe7\x1c\x5d\x74\x62\x22\x4a\x3f\x9d\x9e\x53\xe7\xe0\x84\x6d\xcb\xb4\xce",
+       "\x90\xe1\x0b\x1c\xa8\xd3\x52\x79\x4d\x7d\xbd\x7b\xae\x41\x0b\xef\x25\xf0\xec\x7d\x08\x0e\x05\x3f\x48\x67\x42\x37\xe3\x3e\xa4\x5f",
+       100 },
+      { GCRY_MD_SHA3_256,
+       "\xa8\x73\xe0\xc6\x7c\xa6\x39\x02\x6b\x66\x83\x00\x8f\x7a\xa6\x32\x4d\x49\x79\x55\x0e\x9b\xce\x06\x4c\xa1\xe1\xfb\x97\xa3\x0b\x14\x7a\x24\xf3\xf6\x66\xc0\xa7\x2d\x71\x34\x8e\xde\x70\x1c\xf2\xd1\x7e\x22\x53\xc3\x4d\x1e\xc3\xb6\x47\xdb\xce\xf2\xf8\x79\xf4\xeb\x88\x1c\x48\x30\xb7\x91\x37\x8c\x90\x1e\xb7\x25\xea\x5c\x17\x23\x16\xc6\xd6\x06\xe0\xaf\x7d\xf4\xdf\x7f\x76\xe4\x90\xcd\x30\xb2\xba\xdf\x45\x68\x5f",
+       "\x8a\x0a\x8d\x6d\x55\xcc\xcb\xe0\x5e\xc7\x4d\xc2\x73\xb1\x6d\x66\xc9\xb9\x00\x66\x65\xee\xcb\x5b\x60\x23\xd2\xea\x39\xc6\x45\x54",
+       101 },
+      { GCRY_MD_SHA3_256,
+       "\x00\x69\x17\xb6\x4f\x9d\xcd\xf1\xd2\xd8\x7c\x8a\x61\x73\xb6\x4f\x65\x87\x16\x8e\x80\xfa\xa8\x0f\x82\xd8\x4f\x60\x30\x1e\x56\x1e\x31\x2d\x9f\xbc\xe6\x2f\x39\xa6\xfb\x47\x6e\x01\xe9\x25\xf2\x6b\xcc\x91\xde\x62\x14\x49\xbe\x65\x04\xc5\x04\x83\x0a\xae\x39\x40\x96\xc8\xfc\x76\x94\x65\x10\x51\x36\x5d\x4e\xe9\x07\x01\x01\xec\x9b\x68\x08\x6f\x2e\xa8\xf8\xab\x7b\x81\x1e\xa8\xad\x93\x4d\x5c\x9b\x62\xc6\x0a\x47\x71",
+       "\x12\x28\x95\xd6\x3a\xa6\x03\x0f\xc8\xf2\x39\x40\xc5\x28\xe7\xa5\xd9\xc7\xfb\x17\x0a\x79\xfe\x7b\xc4\x23\x60\xce\x50\xe2\x5b\x7a",
+       102 },
+      { GCRY_MD_SHA3_256,
+       "\xf1\x3c\x97\x2c\x52\xcb\x3c\xc4\xa4\xdf\x28\xc9\x7f\x2d\xf1\x1c\xe0\x89\xb8\x15\x46\x6b\xe8\x88\x63\x24\x3e\xb3\x18\xc2\xad\xb1\xa4\x17\xcb\x10\x41\x30\x85\x98\x54\x17\x20\x19\x7b\x9b\x1c\xb5\xba\x23\x18\xbd\x55\x74\xd1\xdf\x21\x74\xaf\x14\x88\x41\x49\xba\x9b\x2f\x44\x6d\x60\x9d\xf2\x40\xce\x33\x55\x99\x95\x7b\x8e\xc8\x08\x76\xd9\xa0\x85\xae\x08\x49\x07\xbc\x59\x61\xb2\x0b\xf5\xf6\xca\x58\xd5\xda\xb3\x8a\xdb",
+       "\x3e\x04\xee\x53\x95\x05\xc5\x2d\x81\x4c\xab\x3c\x5c\xdd\x7d\xf2\xd6\xee\xe6\x27\xea\x44\x18\x81\x53\xea\x6b\x8c\x8b\xe5\xf6\xc2",
+       103 },
+      { GCRY_MD_SHA3_256,
+       "\xe3\x57\x80\xeb\x97\x99\xad\x4c\x77\x53\x5d\x4d\xdb\x68\x3c\xf3\x3e\xf3\x67\x71\x53\x27\xcf\x4c\x4a\x58\xed\x9c\xbd\xcd\xd4\x86\xf6\x69\xf8\x01\x89\xd5\x49\xa9\x36\x4f\xa8\x2a\x51\xa5\x26\x54\xec\x72\x1b\xb3\xaa\xb9\x5d\xce\xb4\xa8\x6a\x6a\xfa\x93\x82\x6d\xb9\x23\x51\x7e\x92\x8f\x33\xe3\xfb\xa8\x50\xd4\x56\x60\xef\x83\xb9\x87\x6a\xcc\xaf\xa2\xa9\x98\x7a\x25\x4b\x13\x7c\x6e\x14\x0a\x21\x69\x1e\x10\x69\x41\x38\x48",
+       "\xe3\x60\xb4\x24\xa5\xc0\x67\x04\xd1\x48\x35\x2e\x04\xf4\x65\x1f\x8d\x3b\x38\x5c\x01\xf2\x4f\xda\x09\xd2\x66\xd4\xed\x7f\xf6\x62",
+       104 },
+      { GCRY_MD_SHA3_256,
+       "\x64\xec\x02\x1c\x95\x85\xe0\x1f\xfe\x6d\x31\xbb\x50\xd4\x4c\x79\xb6\x99\x3d\x72\x67\x81\x63\xdb\x47\x49\x47\xa0\x53\x67\x46\x19\xd1\x58\x01\x6a\xdb\x24\x3f\x5c\x8d\x50\xaa\x92\xf5\x0a\xb3\x6e\x57\x9f\xf2\xda\xbb\x78\x0a\x2b\x52\x93\x70\xda\xa2\x99\x20\x7c\xfb\xcd\xd3\xa9\xa2\x50\x06\xd1\x9c\x4f\x1f\xe3\x3e\x4b\x1e\xae\xc3\x15\xd8\xc6\xee\x1e\x73\x06\x23\xfd\x19\x41\x87\x5b\x92\x4e\xb5\x7d\x6d\x0c\x2e\xdc\x4e\x78\xd6",
+       "\x0d\x3b\xec\xb9\xe1\xb4\xae\x1f\x15\xc9\xee\x98\x73\x2b\x47\x96\xe9\x9f\xd7\x99\xf7\x6e\xd7\x33\x2a\x68\xab\x36\xc7\x7a\x1e\xf9",
+       105 },
+      { GCRY_MD_SHA3_256,
+       "\x59\x54\xba\xb5\x12\xcf\x32\x7d\x66\xb5\xd9\xf2\x96\x18\x00\x80\x40\x26\x24\xad\x76\x28\x50\x6b\x55\x5e\xea\x83\x82\x56\x23\x24\xcf\x45\x2f\xba\x4a\x21\x30\xde\x3e\x16\x5d\x11\x83\x1a\x27\x0d\x9c\xb9\x7c\xe8\xc2\xd3\x2a\x96\xf5\x0d\x71\x60\x0b\xb4\xca\x26\x8c\xf9\x8e\x90\xd6\x49\x6b\x0a\x66\x19\xa5\xa8\xc6\x3d\xb6\xd8\xa0\x63\x4d\xfc\x6c\x7e\xc8\xea\x9c\x00\x6b\x6c\x45\x6f\x1b\x20\xcd\x19\xe7\x81\xaf\x20\x45\x4a\xc8\x80",
+       "\x3a\xad\xd7\xe2\x08\x6d\x38\x38\x32\x48\x9a\xa3\x08\x8e\x90\x3f\x5c\x6f\xa8\xe3\x8d\xf2\xcf\x87\x6e\x0b\x4d\xcd\xdc\xa5\xc9\x23",
+       106 },
+      { GCRY_MD_SHA3_256,
+       "\x03\xd9\xf9\x2b\x2c\x56\x57\x09\xa5\x68\x72\x4a\x0a\xff\x90\xf8\xf3\x47\xf4\x3b\x02\x33\x8f\x94\xa0\x3e\xd3\x2e\x6f\x33\x66\x6f\xf5\x80\x2d\xa4\xc8\x1b\xdc\xe0\xd0\xe8\x6c\x04\xaf\xd4\xed\xc2\xfc\x8b\x41\x41\xc2\x97\x5b\x6f\x07\x63\x9b\x19\x94\xc9\x73\xd9\xa9\xaf\xce\x3d\x9d\x36\x58\x62\x00\x34\x98\x51\x3b\xfa\x16\x6d\x26\x29\xe3\x14\xd9\x74\x41\x66\x7b\x00\x74\x14\xe7\x39\xd7\xfe\xbf\x0f\xe3\xc3\x2c\x17\xaa\x18\x8a\x86\x83",
+       "\x71\x5c\xed\x57\x76\xa8\x02\xeb\x8e\xe0\x2c\x9d\x46\x54\x3f\xf4\x6f\xe7\xa9\xcd\x19\x2f\xa7\xd4\xff\xb6\xe8\x14\x27\xfe\x1b\x71",
+       107 },
+      { GCRY_MD_SHA3_256,
+       "\xf3\x1e\x8b\x4f\x9e\x06\x21\xd5\x31\xd2\x2a\x38\x0b\xe5\xd9\xab\xd5\x6f\xae\xc5\x3c\xbd\x39\xb1\xfa\xb2\x30\xea\x67\x18\x44\x40\xe5\xb1\xd1\x54\x57\xbd\x25\xf5\x62\x04\xfa\x91\x7f\xa4\x8e\x66\x90\x16\xcb\x48\xc1\xff\xc1\xe1\xe4\x52\x74\xb3\xb4\x73\x79\xe0\x0a\x43\x84\x3c\xf8\x60\x1a\x55\x51\x41\x1e\xc1\x25\x03\xe5\xaa\xc4\x3d\x86\x76\xa1\xb2\x29\x7e\xc7\xa0\x80\x0d\xbf\xee\x04\x29\x2e\x93\x7f\x21\xc0\x05\xf1\x74\x11\x47\x30\x41",
+       "\xdd\xe6\x1f\x8b\xe2\x5b\x8b\x23\xe1\x21\x2c\x1c\x0b\x8a\x85\xa0\xd0\x2d\x85\x48\xbb\x17\xd3\x77\x13\x3e\x3c\x06\xdd\xb5\x8c\xa2",
+       108 },
+      { GCRY_MD_SHA3_256,
+       "\x75\x8e\xa3\xfe\xa7\x38\x97\x3d\xb0\xb8\xbe\x7e\x59\x9b\xbe\xf4\x51\x93\x73\xd6\xe6\xdc\xd7\x19\x5e\xa8\x85\xfc\x99\x1d\x89\x67\x62\x99\x27\x59\xc2\xa0\x90\x02\x91\x2f\xb0\x8e\x0c\xb5\xb7\x6f\x49\x16\x2a\xeb\x8c\xf8\x7b\x17\x2c\xf3\xad\x19\x02\x53\xdf\x61\x2f\x77\xb1\xf0\xc5\x32\xe3\xb5\xfc\x99\xc2\xd3\x1f\x8f\x65\x01\x16\x95\xa0\x87\xa3\x5e\xe4\xee\xe5\xe3\x34\xc3\x69\xd8\xee\x5d\x29\xf6\x95\x81\x5d\x86\x6d\xa9\x9d\xf3\xf7\x94\x03",
+       "\x05\x9f\x2b\xed\xf4\xa6\xee\xfb\x95\xfc\x5c\x0a\xe1\x75\x56\xce\x8b\xdd\xc5\xe1\x88\x0f\xab\x2f\x68\x8a\x03\xa4\x6b\xb2\x8c\x5f",
+       109 },
+      { GCRY_MD_SHA3_256,
+       "\x47\xc6\xe0\xc2\xb7\x49\x48\x46\x59\x21\x86\x88\x04\xf0\xf7\xbd\x50\xdd\x32\x35\x83\xdc\x78\x4f\x99\x8a\x93\xcd\x1c\xa4\xc6\xef\x84\xd4\x1d\xc8\x1c\x2c\x40\xf3\x4b\x5b\xee\x6a\x93\x86\x7b\x3b\xdb\xa0\x05\x2c\x5f\x59\xe6\xf3\x65\x79\x18\xc3\x82\xe7\x71\xd3\x31\x09\x12\x2c\xc8\xbb\x0e\x1e\x53\xc4\xe3\xd1\x3b\x43\xce\x44\x97\x0f\x5e\x0c\x07\x9d\x2a\xd7\xd7\xa3\x54\x9c\xd7\x57\x60\xc2\x1b\xb1\x5b\x44\x75\x89\xe8\x6e\x8d\x76\xb1\xe9\xce\xd2",
+       "\x12\x5b\x0e\xe7\x87\x0a\x6f\x7e\xb4\xfd\x96\x5d\x9e\x0b\x90\xd7\x9f\xff\xbc\x54\xa2\x01\x8f\x4c\x68\x22\x46\x82\xf3\x60\x3f\x3f",
+       110 },
+      { GCRY_MD_SHA3_256,
+       "\xf6\x90\xa1\x32\xab\x46\xb2\x8e\xdf\xa6\x47\x92\x83\xd6\x44\x4e\x37\x1c\x64\x59\x10\x8a\xfd\x9c\x35\xdb\xd2\x35\xe0\xb6\xb6\xff\x4c\x4e\xa5\x8e\x75\x54\xbd\x00\x24\x60\x43\x3b\x21\x64\xca\x51\xe8\x68\xf7\x94\x7d\x7d\x7a\x0d\x79\x2e\x4a\xbf\x0b\xe5\xf4\x50\x85\x3c\xc4\x0d\x85\x48\x5b\x2b\x88\x57\xea\x31\xb5\xea\x6e\x4c\xcf\xa2\xf3\xa7\xef\x33\x80\x06\x6d\x7d\x89\x79\xfd\xac\x61\x8a\xad\x3d\x7e\x88\x6d\xea\x4f\x00\x5a\xe4\xad\x05\xe5\x06\x5f",
+       "\x9a\x78\xe0\xb5\xa3\x4c\xbf\x17\x16\xf1\x4c\xf7\xb6\x7e\xfd\xc4\x54\x0a\x75\xcc\x64\x65\x38\xa1\x1a\x8e\xfd\x9d\x7c\xd7\x52\x9f",
+       111 },
+      { GCRY_MD_SHA3_256,
+       "\x58\xd6\xa9\x9b\xc6\x45\x88\x24\xb2\x56\x91\x67\x70\xa8\x41\x70\x40\x72\x1c\xcc\xfd\x4b\x79\xea\xcd\x8b\x65\xa3\x76\x7c\xe5\xba\x7e\x74\x10\x4c\x98\x5a\xc5\x6b\x8c\xc9\xae\xbd\x16\xfe\xbd\x4c\xda\x5a\xdb\x13\x0b\x0f\xf2\x32\x9c\xc8\xd6\x11\xeb\x14\xda\xc2\x68\xa2\xf9\xe6\x33\xc9\x9d\xe3\x39\x97\xfe\xa4\x1c\x52\xa7\xc5\xe1\x31\x7d\x5b\x5d\xae\xd3\x5e\xba\x7d\x5a\x60\xe4\x5d\x1f\xa7\xea\xab\xc3\x5f\x5c\x2b\x0a\x0f\x23\x79\x23\x19\x53\x32\x2c\x4e",
+       "\x42\x30\x5a\x25\x1a\x80\x09\xed\xfd\x62\xc7\xd9\x19\x10\xb9\x6b\x9b\x5d\xd8\xfd\xa5\xb1\x32\x6f\xe4\x1e\xf6\xee\xf9\x78\xd1\xbe",
+       112 },
+      { GCRY_MD_SHA3_256,
+       "\xbe\xfa\xb5\x74\x39\x6d\x7f\x8b\x67\x05\xe2\xd5\xb5\x8b\x2c\x1c\x82\x0b\xb2\x4e\x3f\x4b\xae\x3e\x8f\xbc\xd3\x6d\xbf\x73\x4e\xe1\x4e\x5d\x6a\xb9\x72\xae\xdd\x35\x40\x23\x54\x66\xe8\x25\x85\x0e\xe4\xc5\x12\xea\x97\x95\xab\xfd\x33\xf3\x30\xd9\xfd\x7f\x79\xe6\x2b\xbb\x63\xa6\xea\x85\xde\x15\xbe\xae\xea\x6f\x8d\x20\x4a\x28\x95\x60\x59\xe2\x63\x2d\x11\x86\x1d\xfb\x0e\x65\xbc\x07\xac\x8a\x15\x93\x88\xd5\xc3\x27\x7e\x22\x72\x86\xf6\x5f\xf5\xe5\xb5\xae\xc1",
+       "\x6b\x9e\x8f\x3e\x82\xea\x17\x4e\xbc\x88\xa5\x3c\x5d\xed\x06\x27\x1d\x38\xf7\x9e\x9c\xec\x57\x1a\x9d\x19\x5e\xf5\x49\x10\x2e\xb8",
+       113 },
+      { GCRY_MD_SHA3_256,
+       "\x8e\x58\x14\x4f\xa9\x17\x9d\x68\x64\x78\x62\x2c\xe4\x50\xc7\x48\x26\x0c\x95\xd1\xba\x43\xb8\xf9\xb5\x9a\xbe\xca\x8d\x93\x48\x8d\xa7\x34\x63\xef\x40\x19\x8b\x4d\x16\xfb\x0b\x07\x07\x20\x13\x47\xe0\x50\x6f\xf1\x9d\x01\xbe\xa0\xf4\x2b\x8a\xf9\xe7\x1a\x1f\x1b\xd1\x68\x78\x10\x69\xd4\xd3\x38\xfd\xef\x00\xbf\x41\x9f\xbb\x00\x30\x31\xdf\x67\x1f\x4a\x37\x97\x95\x64\xf6\x92\x82\xde\x9c\x65\x40\x78\x47\xdd\x0d\xa5\x05\xab\x16\x41\xc0\x2d\xea\x4f\x0d\x83\x49\x86",
+       "\x35\x8d\xe4\xc1\xed\x30\xf4\x8b\x08\x4f\x96\x1f\x65\x3f\xeb\xc6\x93\x18\xf9\x38\x83\x61\x2d\x5a\x04\xb9\x13\x9a\x14\xec\x70\x2e",
+       114 },
+      { GCRY_MD_SHA3_256,
+       "\xb5\x5c\x10\xea\xe0\xec\x68\x4c\x16\xd1\x34\x63\xf2\x92\x91\xbf\x26\xc8\x2e\x2f\xa0\x42\x2a\x99\xc7\x1d\xb4\xaf\x14\xdd\x9c\x7f\x33\xed\xa5\x2f\xd7\x3d\x01\x7c\xc0\xf2\xdb\xe7\x34\xd8\x31\xf0\xd8\x20\xd0\x6d\x5f\x89\xda\xcc\x48\x57\x39\x14\x4f\x8c\xfd\x47\x99\x22\x3b\x1a\xff\x90\x31\xa1\x05\xcb\x6a\x02\x9b\xa7\x1e\x6e\x58\x67\xd8\x5a\x55\x49\x91\xc3\x8d\xf3\xc9\xef\x8c\x1e\x1e\x9a\x76\x30\xbe\x61\xca\xab\xca\x69\x28\x0c\x39\x9c\x1f\xb7\xa1\x2d\x12\xae\xfc",
+       "\x4a\x7b\xd1\x8a\xe1\x0e\xb9\x45\x89\x24\xaa\x5c\xa0\x0d\x3f\x63\x4a\xb9\x75\x36\x28\x10\x7f\x15\xff\x2b\xf2\x4c\xcd\x3b\x94\xf4",
+       115 },
+      { GCRY_MD_SHA3_256,
+       "\x2e\xee\xa6\x93\xf5\x85\xf4\xed\x6f\x6f\x88\x65\xbb\xae\x47\xa6\x90\x8a\xec\xd7\xc4\x29\xe4\xbe\xc4\xf0\xde\x1d\x0c\xa0\x18\x3f\xa2\x01\xa0\xcb\x14\xa5\x29\xb7\xd7\xac\x0e\x6f\xf6\x60\x7a\x32\x43\xee\x9f\xb1\x1b\xcf\x3e\x23\x04\xfe\x75\xff\xcd\xdd\x6c\x5c\x2e\x2a\x4c\xd4\x5f\x63\xc9\x62\xd0\x10\x64\x50\x58\xd3\x65\x71\x40\x4a\x6d\x2b\x4f\x44\x75\x54\x34\xd7\x69\x98\xe8\x34\x09\xc3\x20\x5a\xa1\x61\x5d\xb4\x40\x57\xdb\x99\x12\x31\xd2\xcb\x42\x62\x45\x74\xf5\x45",
+       "\x98\x89\xe4\xb3\xb1\x29\x4a\x01\x55\x6f\xa9\xde\x6a\x6a\x50\x8a\x9a\x76\x3d\x51\x33\xfd\xcd\x49\x37\xb6\xbb\x23\xca\x3e\x19\x01",
+       116 },
+      { GCRY_MD_SHA3_256,
+       "\xda\xb1\x1d\xc0\xb0\x47\xdb\x04\x20\xa5\x85\xf5\x6c\x42\xd9\x31\x75\x56\x28\x52\x42\x84\x99\xf6\x6a\x0d\xb8\x11\xfc\xdd\xda\xb2\xf7\xcd\xff\xed\x15\x43\xe5\xfb\x72\x11\x0b\x64\x68\x6b\xc7\xb6\x88\x7a\x53\x8a\xd4\x4c\x05\x0f\x1e\x42\x63\x1b\xc4\xec\x8a\x9f\x2a\x04\x71\x63\xd8\x22\xa3\x89\x89\xee\x4a\xab\x01\xb4\xc1\xf1\x61\xb0\x62\xd8\x73\xb1\xcf\xa3\x88\xfd\x30\x15\x14\xf6\x22\x24\x15\x7b\x9b\xef\x42\x3c\x77\x83\xb7\xaa\xc8\xd3\x0d\x65\xcd\x1b\xba\x8d\x68\x9c\x2d",
+       "\x3d\x02\xb4\x19\x85\xbd\xd1\x83\x5c\xb4\x74\xfb\x36\x4c\x25\xc2\xcc\xa9\xda\x0e\xd2\xfb\xba\xb7\x55\x24\xb4\x10\x90\x38\x15\xb9",
+       117 },
+      { GCRY_MD_SHA3_256,
+       "\x42\xe9\x9a\x2f\x80\xae\xe0\xe0\x01\x27\x9a\x24\x34\xf7\x31\xe0\x1d\x34\xa4\x4b\x1a\x81\x01\x72\x69\x21\xc0\x59\x0c\x30\xf3\x12\x0e\xb8\x30\x59\xf3\x25\xe8\x94\xa5\xac\x95\x9d\xca\x71\xce\x22\x14\x79\x99\x16\x42\x4e\x85\x9d\x27\xd7\x89\x43\x7b\x9d\x27\x24\x0b\xf8\xc3\x5a\xdb\xaf\xce\xcc\x32\x2b\x48\xaa\x20\x5b\x29\x39\x62\xd8\x58\x65\x2a\xba\xcb\xd5\x88\xbc\xf6\xcb\xc3\x88\xd0\x99\x3b\xd6\x22\xf9\x6e\xd5\x46\x14\xc2\x5b\x6a\x9a\xa5\x27\x58\x9e\xaa\xff\xcf\x17\xdd\xf7",
+       "\x1c\xd9\x20\x39\xbe\x45\x80\xc6\x86\x79\x6d\x59\x00\xee\xd4\x31\xeb\xad\x6e\xa5\x66\xe9\x24\x4e\x76\xba\x68\x73\xef\xcb\x49\xab",
+       118 },
+      { GCRY_MD_SHA3_256,
+       "\x3c\x9b\x46\x45\x0c\x0f\x2c\xae\x8e\x38\x23\xf8\xbd\xb4\x27\x7f\x31\xb7\x44\xce\x2e\xb1\x70\x54\xbd\xdc\x6d\xff\x36\xaf\x7f\x49\xfb\x8a\x23\x20\xcc\x3b\xdf\x8e\x0a\x2e\xa2\x9a\xd3\xa5\x5d\xe1\x16\x5d\x21\x9a\xde\xdd\xb5\x17\x52\x53\xe2\xd1\x48\x9e\x9b\x6f\xdd\x02\xe2\xc3\xd3\xa4\xb5\x4d\x60\xe3\xa4\x73\x34\xc3\x79\x13\xc5\x69\x53\x78\xa6\x69\xe9\xb7\x2d\xec\x32\xaf\x54\x34\xf9\x3f\x46\x17\x6e\xbf\x04\x4c\x47\x84\x46\x7c\x70\x04\x70\xd0\xc0\xb4\x0c\x8a\x08\x8c\x81\x58\x16",
+       "\x68\x0c\x70\xb2\x43\x16\x3b\xe6\xe5\x8e\xd3\xb8\xe2\xd8\x5e\x68\x94\xe5\xe8\x95\x01\xc4\x44\xc8\xc0\xa2\xd7\x76\xac\xad\x85\x99",
+       119 },
+      { GCRY_MD_SHA3_256,
+       "\xd1\xe6\x54\xb7\x7c\xb1\x55\xf5\xc7\x79\x71\xa6\x4d\xf9\xe5\xd3\x4c\x26\xa3\xca\xd6\xc7\xf6\xb3\x00\xd3\x9d\xeb\x19\x10\x09\x46\x91\xad\xaa\x09\x5b\xe4\xba\x5d\x86\x69\x0a\x97\x64\x28\x63\x5d\x55\x26\xf3\xe9\x46\xf7\xdc\x3b\xd4\xdb\xc7\x89\x99\xe6\x53\x44\x11\x87\xa8\x1f\x9a\xdc\xd5\xa3\xc5\xf2\x54\xbc\x82\x56\xb0\x15\x8f\x54\x67\x3d\xcc\x12\x32\xf6\xe9\x18\xeb\xfc\x6c\x51\xce\x67\xea\xeb\x04\x2d\x9f\x57\xee\xc4\xbf\xe9\x10\xe1\x69\xaf\x78\xb3\xde\x48\xd1\x37\xdf\x4f\x28\x40",
+       "\xd6\x5e\x82\x3d\x2c\xe4\xef\xfb\x9b\x27\xdb\xbf\x6e\xfc\xda\x73\x8a\xd1\x52\xfb\xb1\x2d\x21\x08\xd2\xec\x6d\x05\x0a\x3f\xb2\x95",
+       120 },
+      { GCRY_MD_SHA3_256,
+       "\x62\x6f\x68\xc1\x8a\x69\xa6\x59\x01\x59\xa9\xc4\x6b\xe0\x3d\x59\x65\x69\x8f\x2d\xac\x3d\xe7\x79\xb8\x78\xb3\xd9\xc4\x21\xe0\xf2\x1b\x95\x5a\x16\xc7\x15\xc1\xec\x1e\x22\xce\x3e\xb6\x45\xb8\xb4\xf2\x63\xf6\x06\x60\xea\x30\x28\x98\x1e\xeb\xd6\xc8\xc3\xa3\x67\x28\x5b\x69\x1c\x8e\xe5\x69\x44\xa7\xcd\x12\x17\x99\x7e\x1d\x9c\x21\x62\x0b\x53\x6b\xdb\xd5\xde\x89\x25\xff\x71\xde\xc6\xfb\xc0\x66\x24\xab\x6b\x21\xe3\x29\x81\x3d\xe9\x0d\x1e\x57\x2d\xfb\x89\xa1\x81\x20\xc3\xf6\x06\x35\x5d\x25",
+       "\xce\x6d\x2d\xd8\xd5\x44\x1f\xc1\x5b\x88\x8f\xed\x72\x06\x1e\x12\x91\x25\x43\x1b\xed\xea\x32\xe0\x0e\xe0\xa7\x65\x5c\x06\xc3\x58",
+       121 },
+      { GCRY_MD_SHA3_256,
+       "\x65\x1a\x6f\xb3\xc4\xb8\x0c\x7c\x68\xc6\x01\x16\x75\xe6\x09\x4e\xb5\x6a\xbf\x5f\xc3\x05\x73\x24\xeb\xc6\x47\x78\x25\x06\x1f\x9f\x27\xe7\xa9\x46\x33\xab\xd1\xfa\x59\x8a\x74\x6e\x4a\x57\x7c\xaf\x52\x4c\x52\xec\x17\x88\x47\x1f\x92\xb8\xc3\x7f\x23\x79\x5c\xa1\x9d\x55\x9d\x44\x6c\xab\x16\xcb\xcd\xce\x90\xb7\x9f\xa1\x02\x6c\xee\x77\xbf\x4a\xb1\xb5\x03\xc5\xb9\x4c\x22\x56\xad\x75\xb3\xea\xc6\xfd\x5d\xcb\x96\xac\xa4\xb0\x3a\x83\x4b\xfb\x4e\x9a\xf9\x88\xce\xcb\xf2\xae\x59\x7c\xb9\x09\x79\x40",
+       "\x28\x07\x13\xc0\xfa\x71\x60\x28\x9f\xbf\xee\x5a\xa5\x80\xad\x82\x51\x28\x39\x15\x3d\xae\x47\xde\x0d\x15\x43\x84\xa4\xd8\xb3\xed",
+       122 },
+      { GCRY_MD_SHA3_256,
+       "\x8a\xaf\x07\x2f\xce\x8a\x2d\x96\xbc\x10\xb3\xc9\x1c\x80\x9e\xe9\x30\x72\xfb\x20\x5c\xa7\xf1\x0a\xbd\x82\xec\xd8\x2c\xf0\x40\xb1\xbc\x49\xea\x13\xd1\x85\x78\x15\xc0\xe9\x97\x81\xde\x3a\xdb\xb5\x44\x3c\xe1\xc8\x97\xe5\x51\x88\xce\xaf\x22\x1a\xa9\x68\x16\x38\xde\x05\xae\x1b\x32\x29\x38\xf4\x6b\xce\x51\x54\x3b\x57\xec\xdb\x4c\x26\x62\x72\x25\x9d\x17\x98\xde\x13\xbe\x90\xe1\x0e\xfe\xc2\xd0\x74\x84\xd9\xb2\x1a\x38\x70\xe2\xaa\x9e\x06\xc2\x1a\xa2\xd0\xc9\xcf\x42\x00\x80\xa8\x0a\x91\xde\xe1\x6f",
+       "\x72\x1f\xd8\x72\x69\x6f\x21\xde\xaa\x95\x95\xc0\xce\xe7\xbc\x07\x24\x96\x01\x92\x7c\x96\xa6\x58\x26\xb4\x88\x7c\xdb\xa1\xae\x96",
+       123 },
+      { GCRY_MD_SHA3_256,
+       "\x53\xf9\x18\xfd\x00\xb1\x70\x1b\xd5\x04\xf8\xcd\xea\x80\x3a\xcc\xa2\x1a\xc1\x8c\x56\x4a\xb9\x0c\x2a\x17\xda\x59\x2c\x7d\x69\x68\x8f\x65\x80\x57\x53\x95\x55\x1e\x8c\xd3\x3e\x0f\xef\x08\xca\x6e\xd4\x58\x8d\x4d\x14\x0b\x3e\x44\xc0\x32\x35\x5d\xf1\xc5\x31\x56\x4d\x7f\x48\x35\x75\x33\x44\x34\x5a\x67\x81\xe1\x1c\xd5\xe0\x95\xb7\x3d\xf5\xf8\x2c\x8a\xe3\xad\x00\x87\x79\x36\x89\x66\x71\xe9\x47\xcc\x52\xe2\xb2\x9d\xcd\x46\x3d\x90\xa0\xc9\x92\x91\x28\xda\x22\x2b\x5a\x21\x14\x50\xbb\xc0\xe0\x24\x48\xe2",
+       "\xb5\x3a\xf8\x62\x0b\x39\xca\xd2\xd6\x98\xa1\x76\xa0\x70\xae\xaa\x9f\xb6\x7b\xd0\x33\x5c\x34\x85\xa3\xb6\xc7\x3a\x71\xdc\x5c\x5c",
+       124 },
+      { GCRY_MD_SHA3_256,
+       "\xa6\x45\x99\xb8\xa6\x1b\x5c\xce\xc9\xe6\x7a\xed\x69\x44\x74\x59\xc8\xda\x3d\x1e\xc6\xc7\xc7\xc8\x2a\x74\x28\xb9\xb5\x84\xfa\x67\xe9\x0f\x68\xe2\xc0\x0f\xbb\xed\x46\x13\x66\x6e\x51\x68\xda\x4a\x16\xf3\x95\xf7\xa3\xc3\x83\x2b\x3b\x13\x4b\xfc\x9c\xba\xa9\x5d\x2a\x0f\xe2\x52\xf4\x4a\xc6\x68\x1e\xb6\xd4\x0a\xb9\x1c\x1d\x02\x82\xfe\xd6\x70\x1c\x57\x46\x3d\x3c\x5f\x2b\xb8\xc6\xa7\x30\x1f\xb4\x57\x6a\xa3\xb5\xf1\x55\x10\xdb\x89\x56\xff\x77\x47\x8c\x26\xa7\xc0\x9b\xea\x7b\x39\x8c\xfc\x83\x50\x3f\x53\x8e",
+       "\x78\xa1\x8b\xf0\xa5\x2e\x6f\x77\xf1\x5f\x7f\xfe\x4c\xa3\xc9\x99\xe5\x7e\x1c\x3f\x6b\xf1\x09\x50\x58\x1f\x40\x34\x50\xed\xb7\x97",
+       125 },
+      { GCRY_MD_SHA3_256,
+       "\x0e\x3a\xb0\xe0\x54\x73\x9b\x00\xcd\xb6\xa8\x7b\xd1\x2c\xae\x02\x4b\x54\xcb\x5e\x55\x0e\x6c\x42\x53\x60\xc2\xe8\x7e\x59\x40\x1f\x5e\xc2\x4e\xf0\x31\x48\x55\xf0\xf5\x6c\x47\x69\x5d\x56\xa7\xfb\x14\x17\x69\x3a\xf2\xa1\xed\x52\x91\xf2\xfe\xe9\x5f\x75\xee\xd5\x4a\x1b\x1c\x2e\x81\x22\x6f\xbf\xf6\xf6\x3a\xde\x58\x49\x11\xc7\x19\x67\xa8\xeb\x70\x93\x3b\xc3\xf5\xd1\x5b\xc9\x1b\x5c\x26\x44\xd9\x51\x6d\x3c\x3a\x8c\x15\x4e\xe4\x8e\x11\x8b\xd1\x44\x2c\x04\x3c\x7a\x0d\xba\x5a\xc5\xb1\xd5\x36\x0a\xae\x5b\x90\x65",
+       "\xa7\xf0\x15\x1e\xee\x6b\x21\xfe\x82\x7e\x69\x25\x6d\x56\x0e\x1e\xa8\xd9\x39\xb8\x09\x62\xfc\x7f\xa8\x61\x0a\xc1\x89\x40\x2a\xd2",
+       126 },
+      { GCRY_MD_SHA3_256,
+       "\xa6\x2f\xc5\x95\xb4\x09\x6e\x63\x36\xe5\x3f\xcd\xfc\x8d\x1c\xc1\x75\xd7\x1d\xac\x9d\x75\x0a\x61\x33\xd2\x31\x99\xea\xac\x28\x82\x07\x94\x4c\xea\x6b\x16\xd2\x76\x31\x91\x5b\x46\x19\xf7\x43\xda\x2e\x30\xa0\xc0\x0b\xbd\xb1\xbb\xb3\x5a\xb8\x52\xef\x3b\x9a\xec\x6b\x0a\x8d\xcc\x6e\x9e\x1a\xba\xa3\xad\x62\xac\x0a\x6c\x5d\xe7\x65\xde\x2c\x37\x11\xb7\x69\xe3\xfd\xe4\x4a\x74\x01\x6f\xff\x82\xac\x46\xfa\x8f\x17\x97\xd3\xb2\xa7\x26\xb6\x96\xe3\xde\xa5\x53\x04\x39\xac\xee\x3a\x45\xc2\xa5\x1b\xc3\x2d\xd0\x55\x65\x0b",
+       "\x0a\x09\xc4\xb1\x8f\x51\x17\xf0\xe4\x5d\x43\xe2\x35\xbb\x14\xe5\x5b\x16\x2e\x99\xeb\x37\x44\x16\x51\x96\xd0\x4a\x85\x42\x29\xf9",
+       127 },
+      { GCRY_MD_SHA3_256,
+       "\x2b\x6d\xb7\xce\xd8\x66\x5e\xbe\x9d\xeb\x08\x02\x95\x21\x84\x26\xbd\xaa\x7c\x6d\xa9\xad\xd2\x08\x89\x32\xcd\xff\xba\xa1\xc1\x41\x29\xbc\xcd\xd7\x0f\x36\x9e\xfb\x14\x92\x85\x85\x8d\x2b\x1d\x15\x5d\x14\xde\x2f\xdb\x68\x0a\x8b\x02\x72\x84\x05\x51\x82\xa0\xca\xe2\x75\x23\x4c\xc9\xc9\x28\x63\xc1\xb4\xab\x66\xf3\x04\xcf\x06\x21\xcd\x54\x56\x5f\x5b\xff\x46\x1d\x3b\x46\x1b\xd4\x0d\xf2\x81\x98\xe3\x73\x25\x01\xb4\x86\x0e\xad\xd5\x03\xd2\x6d\x6e\x69\x33\x8f\x4e\x04\x56\xe9\xe9\xba\xf3\xd8\x27\xae\x68\x5f\xb1\xd8\x17",
+       "\xb7\xd0\x31\xaa\x69\xb7\xb4\xd2\x6a\x35\xb8\x96\xd7\x61\x31\x4f\x1d\x61\xeb\x12\xdc\xc1\xe7\x2a\xaf\x61\xb9\xcd\x48\x00\x3a\xf9",
+       128 },
+      { GCRY_MD_SHA3_256,
+       "\x10\xdb\x50\x9b\x2c\xdc\xab\xa6\xc0\x62\xae\x33\xbe\x48\x11\x6a\x29\xeb\x18\xe3\x90\xe1\xbb\xad\xa5\xca\x0a\x27\x18\xaf\xbc\xd2\x34\x31\x44\x01\x06\x59\x48\x93\x04\x3c\xc7\xf2\x62\x52\x81\xbf\x7d\xe2\x65\x58\x80\x96\x6a\x23\x70\x5f\x0c\x51\x55\xc2\xf5\xcc\xa9\xf2\xc2\x14\x2e\x96\xd0\xa2\xe7\x63\xb7\x06\x86\xcd\x42\x1b\x5d\xb8\x12\xda\xce\xd0\xc6\xd6\x50\x35\xfd\xe5\x58\xe9\x4f\x26\xb3\xe6\xdd\xe5\xbd\x13\x98\x0c\xc8\x02\x92\xb7\x23\x01\x3b\xd0\x33\x28\x45\x84\xbf\xf2\x76\x57\x87\x1b\x0c\xf0\x7a\x84\x9f\x4a\xe2",
+       "\xec\x08\x58\xc9\xd0\x17\xa2\xd3\x72\x7c\xaa\xde\x7e\x48\x72\x68\x4f\x17\xb8\x22\xca\xfe\xcd\xa4\x45\xa1\x5c\xf3\x0f\xac\x8c\xf0",
+       129 },
+      { GCRY_MD_SHA3_256,
+       "\x93\x34\xde\x60\xc9\x97\xbd\xa6\x08\x61\x01\xa6\x31\x4f\x64\xe4\x45\x8f\x5f\xf9\x45\x0c\x50\x9d\xf0\x06\xe8\xc5\x47\x98\x3c\x65\x1c\xa9\x78\x79\x17\x5a\xab\xa0\xc5\x39\xe8\x2d\x05\xc1\xe0\x2c\x48\x09\x75\xcb\xb3\x01\x18\x12\x10\x61\xb1\xeb\xac\x4f\x8d\x9a\x37\x81\xe2\xdb\x6b\x18\x04\x2e\x01\xec\xf9\x01\x7a\x64\xa0\xe5\x74\x47\xec\x7f\xcb\xe6\xa7\xf8\x25\x85\xf7\x40\x3e\xe2\x22\x3d\x52\xd3\x7b\x4b\xf4\x26\x42\x86\x13\xd6\xb4\x25\x79\x80\x97\x2a\x0a\xca\xb5\x08\xa7\x62\x0c\x1c\xb2\x8e\xb4\xe9\xd3\x0f\xc4\x13\x61\xec",
+       "\x71\xe1\xd6\x10\xb5\x76\x06\x3f\x2b\x12\xf6\x91\x22\x0b\xea\xdf\x50\x6b\xec\x0a\x3a\x08\x6b\xbe\x58\x64\xfb\x54\xf9\x3d\xb5\x56",
+       130 },
+      { GCRY_MD_SHA3_256,
+       "\xe8\x8a\xb0\x86\x89\x16\x93\xaa\x53\x5c\xeb\x20\xe6\x4c\x7a\xb9\x7c\x7d\xd3\x54\x8f\x37\x86\x33\x98\x97\xa5\xf0\xc3\x90\x31\x54\x9c\xa8\x70\x16\x6e\x47\x77\x43\xcc\xfb\xe0\x16\xb4\x42\x8d\x89\x73\x8e\x42\x6f\x5f\xfe\x81\x62\x61\x37\xf1\x7a\xec\xff\x61\xb7\x2d\xbe\xe2\xdc\x20\x96\x18\x80\xcf\xe2\x81\xdf\xab\x5e\xe3\x8b\x19\x21\x88\x14\x50\xe1\x60\x32\xde\x5e\x4d\x55\xad\x8d\x4f\xca\x60\x97\x21\xb0\x69\x2b\xac\x79\xbe\x5a\x06\xe1\x77\xfe\x8c\x80\xc0\xc8\x35\x19\xfb\x33\x47\xde\x9f\x43\xd5\x56\x1c\xb8\x10\x7b\x9b\x5e\xdc",
+       "\x72\xa8\xa7\x49\x33\x09\x08\x0a\xcc\xca\x2a\x2a\x21\xd6\x41\xf2\xb9\x68\x5b\x73\x62\xbe\x49\x6d\xc7\xbc\x33\x06\x59\xf8\xcf\xe1",
+       131 },
+      { GCRY_MD_SHA3_256,
+       "\xfd\x19\xe0\x1a\x83\xeb\x6e\xc8\x10\xb9\x45\x82\xcb\x8f\xbf\xa2\xfc\xb9\x92\xb5\x36\x84\xfb\x74\x8d\x22\x64\xf0\x20\xd3\xb9\x60\xcb\x1d\x6b\x8c\x34\x8c\x2b\x54\xa9\xfc\xea\x72\x33\x0c\x2a\xaa\x9a\x24\xec\xdb\x00\xc4\x36\xab\xc7\x02\x36\x1a\x82\xbb\x88\x28\xb8\x53\x69\xb8\xc7\x2e\xce\x00\x82\xfe\x06\x55\x71\x63\x89\x9c\x2a\x0e\xfa\x46\x6c\x33\xc0\x43\x43\xa8\x39\x41\x70\x57\x39\x9a\x63\xa3\x92\x9b\xe1\xee\x48\x05\xd6\xce\x3e\x5d\x0d\x09\x67\xfe\x90\x04\x69\x6a\x56\x63\xf4\xca\xc9\x17\x90\x06\xa2\xce\xb7\x55\x42\xd7\x5d\x68",
+       "\xaf\x19\xe9\x88\xd3\x7e\x25\x77\xda\x4f\x43\x46\x37\x89\xb7\x36\x25\xd3\x54\xfc\xcc\xbd\x10\xcd\x2c\x61\xfb\xdc\x8b\xb0\x18\x27",
+       132 },
+      { GCRY_MD_SHA3_256,
+       "\x59\xae\x20\xb6\xf7\xe0\xb3\xc7\xa9\x89\xaf\xb2\x83\x24\xa4\x0f\xca\x25\xd8\x65\x1c\xf1\xf4\x6a\xe3\x83\xef\x6d\x84\x41\x58\x7a\xa1\xc0\x4c\x3e\x3b\xf8\x8e\x81\x31\xce\x61\x45\xcf\xb8\x97\x3d\x96\x1e\x84\x32\xb2\x02\xfa\x5a\xf3\xe0\x9d\x62\x5f\xaa\xd8\x25\xbc\x19\xda\x9b\x5c\x6c\x20\xd0\x2a\xbd\xa2\xfc\xc5\x8b\x5b\xd3\xfe\x50\x7b\xf2\x01\x26\x3f\x30\x54\x38\x19\x51\x0c\x12\xbc\x23\xe2\xdd\xb4\xf7\x11\xd0\x87\xa8\x6e\xdb\x1b\x35\x53\x13\x36\x3a\x2d\xe9\x96\xb8\x91\x02\x5e\x14\x70\x36\x08\x74\x01\xcc\xf3\xca\x78\x15\xbf\x3c\x49",
+       "\xf1\xe9\xb9\xce\xf2\xb3\x7e\x4e\xc3\xa0\xfc\xd5\xef\xf5\xbf\x7e\x3d\x49\x10\x0a\xeb\xf0\x18\xdc\x92\xfb\x6a\x40\xe4\x29\x77\x04",
+       133 },
+      { GCRY_MD_SHA3_256,
+       "\x77\xee\x80\x4b\x9f\x32\x95\xab\x23\x62\x79\x8b\x72\xb0\xa1\xb2\xd3\x29\x1d\xce\xb8\x13\x98\x96\x35\x58\x30\xf3\x4b\x3b\x32\x85\x61\x53\x1f\x80\x79\xb7\x9a\x6e\x99\x80\x70\x51\x50\x86\x64\x02\xfd\xc1\x76\xc0\x58\x97\xe3\x59\xa6\xcb\x1a\x7a\xb0\x67\x38\x3e\xb4\x97\x18\x2a\x7e\x5a\xef\x70\x38\xe4\xc9\x6d\x13\x3b\x27\x82\x91\x74\x17\xe3\x91\x53\x5b\x5e\x1b\x51\xf4\x7d\x8e\xd7\xe4\xd4\x02\x5f\xe9\x8d\xc8\x7b\x9c\x16\x22\x61\x4b\xff\x3d\x10\x29\xe6\x8e\x37\x2d\xe7\x19\x80\x38\x57\xca\x52\x06\x7c\xdd\xaa\xd9\x58\x95\x1c\xb2\x06\x8c\xc6",
+       "\xdd\x3e\xbe\x0c\xca\x0c\xad\x3a\xf7\x2a\xf7\x3f\xb4\x9d\x40\xdb\xdc\xc4\xb1\xf1\xff\x46\x5c\xca\xef\xe6\x72\xf7\x79\x92\xac\xa0",
+       134 },
+      { GCRY_MD_SHA3_256,
+       "\xb7\x71\xd5\xce\xf5\xd1\xa4\x1a\x93\xd1\x56\x43\xd7\x18\x1d\x2a\x2e\xf0\xa8\xe8\x4d\x91\x81\x2f\x20\xed\x21\xf1\x47\xbe\xf7\x32\xbf\x3a\x60\xef\x40\x67\xc3\x73\x4b\x85\xbc\x8c\xd4\x71\x78\x0f\x10\xdc\x9e\x82\x91\xb5\x83\x39\xa6\x77\xb9\x60\x21\x8f\x71\xe7\x93\xf2\x79\x7a\xea\x34\x94\x06\x51\x28\x29\x06\x5d\x37\xbb\x55\xea\x79\x6f\xa4\xf5\x6f\xd8\x89\x6b\x49\xb2\xcd\x19\xb4\x32\x15\xad\x96\x7c\x71\x2b\x24\xe5\x03\x2d\x06\x52\x32\xe0\x2c\x12\x74\x09\xd2\xed\x41\x46\xb9\xd7\x5d\x76\x3d\x52\xdb\x98\xd9\x49\xd3\xb0\xfe\xd6\xa8\x05\x2f\xbb",
+       "\xa1\x9e\xee\x92\xbb\x20\x97\xb6\x4e\x82\x3d\x59\x77\x98\xaa\x18\xbe\x9b\x7c\x73\x6b\x80\x59\xab\xfd\x67\x79\xac\x35\xac\x81\xb5",
+       135 },
+      { GCRY_MD_SHA3_256,
+       "\xb3\x2d\x95\xb0\xb9\xaa\xd2\xa8\x81\x6d\xe6\xd0\x6d\x1f\x86\x00\x85\x05\xbd\x8c\x14\x12\x4f\x6e\x9a\x16\x3b\x5a\x2a\xde\x55\xf8\x35\xd0\xec\x38\x80\xef\x50\x70\x0d\x3b\x25\xe4\x2c\xc0\xaf\x05\x0c\xcd\x1b\xe5\xe5\x55\xb2\x30\x87\xe0\x4d\x7b\xf9\x81\x36\x22\x78\x0c\x73\x13\xa1\x95\x4f\x87\x40\xb6\xee\x2d\x3f\x71\xf7\x68\xdd\x41\x7f\x52\x04\x82\xbd\x3a\x08\xd4\xf2\x22\xb4\xee\x9d\xbd\x01\x54\x47\xb3\x35\x07\xdd\x50\xf3\xab\x42\x47\xc5\xde\x9a\x8a\xbd\x62\xa8\xde\xce\xa0\x1e\x3b\x87\xc8\xb9\x27\xf5\xb0\x8b\xeb\x37\x67\x4c\x6f\x8e\x38\x0c\x04",
+       "\xdf\x67\x3f\x41\x05\x37\x9f\xf6\xb7\x55\xee\xab\x20\xce\xb0\xdc\x77\xb5\x28\x63\x64\xfe\x16\xc5\x9c\xc8\xa9\x07\xaf\xf0\x77\x32",
+       136 },
+      { GCRY_MD_SHA3_256,
+       "\x04\x41\x0e\x31\x08\x2a\x47\x58\x4b\x40\x6f\x05\x13\x98\xa6\xab\xe7\x4e\x4d\xa5\x9b\xb6\xf8\x5e\x6b\x49\xe8\xa1\xf7\xf2\xca\x00\xdf\xba\x54\x62\xc2\xcd\x2b\xfd\xe8\xb6\x4f\xb2\x1d\x70\xc0\x83\xf1\x13\x18\xb5\x6a\x52\xd0\x3b\x81\xca\xc5\xee\xc2\x9e\xb3\x1b\xd0\x07\x8b\x61\x56\x78\x6d\xa3\xd6\xd8\xc3\x30\x98\xc5\xc4\x7b\xb6\x7a\xc6\x4d\xb1\x41\x65\xaf\x65\xb4\x45\x44\xd8\x06\xdd\xe5\xf4\x87\xd5\x37\x3c\x7f\x97\x92\xc2\x99\xe9\x68\x6b\x7e\x58\x21\xe7\xc8\xe2\x45\x83\x15\xb9\x96\xb5\x67\x7d\x92\x6d\xac\x57\xb3\xf2\x2d\xa8\x73\xc6\x01\x01\x6a\x0d",
+       "\xd5\x24\x32\xcf\x3b\x6b\x4b\x94\x9a\xa8\x48\xe0\x58\xdc\xd6\x2d\x73\x5e\x01\x77\x27\x92\x22\xe7\xac\x0a\xf8\x50\x47\x62\xfa\xa0",
+       137 },
+      { GCRY_MD_SHA3_256,
+       "\x8b\x81\xe9\xba\xdd\xe0\x26\xf1\x4d\x95\xc0\x19\x97\x70\x24\xc9\xe1\x3d\xb7\xa5\xcd\x21\xf9\xe9\xfc\x49\x1d\x71\x61\x64\xbb\xac\xdc\x70\x60\xd8\x82\x61\x5d\x41\x14\x38\xae\xa0\x56\xc3\x40\xcd\xf9\x77\x78\x8f\x6e\x17\xd1\x18\xde\x55\x02\x68\x55\xf9\x32\x70\x47\x2d\x1f\xd1\x8b\x9e\x7e\x81\x2b\xae\x10\x7e\x0d\xfd\xe7\x06\x33\x01\xb7\x1f\x6c\xfe\x4e\x22\x5c\xab\x3b\x23\x29\x05\xa5\x6e\x99\x4f\x08\xee\x28\x91\xba\x92\x2d\x49\xc3\xda\xfe\xb7\x5f\x7c\x69\x75\x0c\xb6\x7d\x82\x2c\x96\x17\x6c\x46\xbd\x8a\x29\xf1\x70\x13\x73\xfb\x09\xa1\xa6\xe3\xc7\x15\x8f",
+       "\x07\xe6\x57\x54\xd6\x2e\x01\xb9\xa0\x49\xd1\x5d\xec\x0d\x09\xc0\x2f\x47\x9c\xa2\xae\xb4\xb1\x8e\x37\x07\x0b\x20\xf8\x5a\x1b\x26",
+       138 },
+      { GCRY_MD_SHA3_256,
+       "\xfa\x6e\xed\x24\xda\x66\x66\xa2\x22\x08\x14\x6b\x19\xa5\x32\xc2\xec\x9b\xa9\x4f\x09\xf1\xde\xf1\xe7\xfc\x13\xc3\x99\xa4\x8e\x41\xac\xc2\xa5\x89\xd0\x99\x27\x62\x96\x34\x8f\x39\x62\x53\xb5\x7c\xb0\xe4\x02\x91\xbd\x28\x27\x73\x65\x6b\x6e\x0d\x8b\xea\x1c\xda\x08\x4a\x37\x38\x81\x6a\x84\x04\x85\xfc\xf3\xfb\x30\x7f\x77\x7f\xa5\xfe\xac\x48\x69\x5c\x2a\xf4\x76\x97\x20\x25\x8c\x77\x94\x3f\xb4\x55\x6c\x36\x2d\x9c\xba\x8b\xf1\x03\xae\xb9\x03\x4b\xaa\x8e\xa8\xbf\xb9\xc4\xf8\xe6\x74\x2c\xe0\xd5\x2c\x49\xea\x8e\x97\x4f\x33\x96\x12\xe8\x30\xe9\xe7\xa9\xc2\x90\x65",
+       "\x17\xa4\x61\xb8\xee\x50\x7a\xbc\xfe\xd5\x1a\x50\xef\x14\x89\x13\x09\xfe\x40\x2c\x56\x9d\x94\x39\x4c\xa7\xa3\x03\x1b\xef\xcd\x50",
+       139 },
+      { GCRY_MD_SHA3_256,
+       "\x9b\xb4\xaf\x1b\x4f\x09\xc0\x71\xce\x3c\xaf\xa9\x2e\x4e\xb7\x3c\xe8\xa6\xf5\xd8\x2a\x85\x73\x34\x40\x36\x8d\xee\x4e\xb1\xcb\xc7\xb5\x5a\xc1\x50\x77\x3b\x6f\xe4\x7d\xbe\x03\x6c\x45\x58\x2e\xd6\x7e\x23\xf4\xc7\x45\x85\xda\xb5\x09\xdf\x1b\x83\x61\x05\x64\x54\x56\x42\xb2\xb1\xec\x46\x3e\x18\x04\x8f\xc2\x34\x77\xc6\xb2\xaa\x03\x55\x94\xec\xd3\x37\x91\xaf\x6a\xf4\xcb\xc2\xa1\x16\x6a\xba\x8d\x62\x8c\x57\xe7\x07\xf0\xb0\xe8\x70\x7c\xaf\x91\xcd\x44\xbd\xb9\x15\xe0\x29\x6e\x01\x90\xd5\x6d\x33\xd8\xdd\xe1\x0b\x5b\x60\x37\x78\x38\x97\x3c\x1d\x94\x3c\x22\xed\x33\x5e",
+       "\xa0\x3c\x6b\x5b\x51\xae\x4a\xa0\x09\x12\xaf\x1c\xfb\x6c\x7b\x96\x0e\xf5\x80\x36\x15\x64\x97\xcc\x56\x7b\x13\x69\x14\x9a\x59\x49",
+       140 },
+      { GCRY_MD_SHA3_256,
+       "\x21\x67\xf0\x21\x18\xcc\x62\x04\x3e\x90\x91\xa6\x47\xca\xdb\xed\x95\x61\x1a\x52\x1f\xe0\xd6\x4e\x85\x18\xf1\x6c\x80\x8a\xb2\x97\x72\x55\x98\xae\x29\x68\x80\xa7\x73\x60\x7a\x79\x8f\x7c\x3c\xfc\xe8\x0d\x25\x1e\xbe\xc6\x88\x50\x15\xf9\xab\xf7\xea\xab\xae\x46\x79\x8f\x82\xcb\x59\x26\xde\x5c\x23\xf4\x4a\x3f\x9f\x95\x34\xb3\xc6\xf4\x05\xb5\x36\x4c\x2f\x8a\x8b\xdc\x5c\xa4\x9c\x74\x9b\xed\x8c\xe4\xba\x48\x89\x70\x62\xae\x84\x24\xca\x6d\xde\x5f\x55\xc0\xe4\x2a\x95\xd1\xe2\x92\xca\x54\xfb\x46\xa8\x4f\xbc\x9c\xd8\x7f\x2d\x0c\x9e\x74\x48\xde\x30\x43\xae\x22\xfd\xd2\x29",
+       "\x14\xc6\x9c\x5e\xab\xde\xfc\x9e\x3a\x14\x61\xa3\x79\xec\x92\xc3\x2b\xc6\xb6\x90\x71\x02\x9c\xb3\x65\x51\x59\xdb\x1a\x52\x51\xa7",
+       141 },
+      { GCRY_MD_SHA3_256,
+       "\x94\xb7\xfa\x0b\xc1\xc4\x4e\x94\x9b\x1d\x76\x17\xd3\x1b\x47\x20\xcb\xe7\xca\x57\xc6\xfa\x4f\x40\x94\xd4\x76\x15\x67\xe3\x89\xec\xc6\x4f\x69\x68\xe4\x06\x4d\xf7\x0d\xf8\x36\xa4\x7d\x0c\x71\x33\x36\xb5\x02\x8b\x35\x93\x0d\x29\xeb\x7a\x7f\x9a\x5a\xf9\xad\x5c\xf4\x41\x74\x5b\xae\xc9\xbb\x01\x4c\xee\xff\x5a\x41\xba\x5c\x1c\xe0\x85\xfe\xb9\x80\xba\xb9\xcf\x79\xf2\x15\x8e\x03\xef\x7e\x63\xe2\x9c\x38\xd7\x81\x6a\x84\xd4\xf7\x1e\x0f\x54\x8b\x7f\xc3\x16\x08\x5a\xe3\x8a\x06\x0f\xf9\xb8\xde\xc3\x6f\x91\xad\x9e\xbc\x0a\x5b\x6c\x33\x8c\xbb\x8f\x66\x59\xd3\x42\xa2\x43\x68\xcf",
+       "\x3c\xbe\x06\x88\x7c\x8a\xe3\x60\xe9\x57\xeb\x08\xca\x57\x78\x34\xc4\x57\xfa\xdf\x41\x8d\x0c\xb7\x39\x67\xfa\x82\x7a\x22\xa4\xd7",
+       142 },
+      { GCRY_MD_SHA3_256,
+       "\xea\x40\xe8\x3c\xb1\x8b\x3a\x24\x2c\x1e\xcc\x6c\xcd\x0b\x78\x53\xa4\x39\xda\xb2\xc5\x69\xcf\xc6\xdc\x38\xa1\x9f\x5c\x90\xac\xbf\x76\xae\xf9\xea\x37\x42\xff\x3b\x54\xef\x7d\x36\xeb\x7c\xe4\xff\x1c\x9a\xb3\xbc\x11\x9c\xff\x6b\xe9\x3c\x03\xe2\x08\x78\x33\x35\xc0\xab\x81\x37\xbe\x5b\x10\xcd\xc6\x6f\xf3\xf8\x9a\x1b\xdd\xc6\xa1\xee\xd7\x4f\x50\x4c\xbe\x72\x90\x69\x0b\xb2\x95\xa8\x72\xb9\xe3\xfe\x2c\xee\x9e\x6c\x67\xc4\x1d\xb8\xef\xd7\xd8\x63\xcf\x10\xf8\x40\xfe\x61\x8e\x79\x36\xda\x3d\xca\x5c\xa6\xdf\x93\x3f\x24\xf6\x95\x4b\xa0\x80\x1a\x12\x94\xcd\x8d\x7e\x66\xdf\xaf\xec",
+       "\xe5\x8a\x94\x7e\x98\xd6\xdd\x7e\x93\x2d\x2f\xe0\x2d\x99\x92\xe6\x11\x8c\x0c\x2c\x60\x6b\xdc\xda\x06\xe7\x94\x3d\x2c\x95\xe0\xe5",
+       143 },
+      { GCRY_MD_SHA3_256,
+       "\x15\x7d\x5b\x7e\x45\x07\xf6\x6d\x9a\x26\x74\x76\xd3\x38\x31\xe7\xbb\x76\x8d\x4d\x04\xcc\x34\x38\xda\x12\xf9\x01\x02\x63\xea\x5f\xca\xfb\xde\x25\x79\xdb\x2f\x6b\x58\xf9\x11\xd5\x93\xd5\xf7\x9f\xb0\x5f\xe3\x59\x6e\x3f\xa8\x0f\xf2\xf7\x61\xd1\xb0\xe5\x70\x80\x05\x5c\x11\x8c\x53\xe5\x3c\xdb\x63\x05\x52\x61\xd7\xc9\xb2\xb3\x9b\xd9\x0a\xcc\x32\x52\x0c\xbb\xdb\xda\x2c\x4f\xd8\x85\x6d\xbc\xee\x17\x31\x32\xa2\x67\x91\x98\xda\xf8\x30\x07\xa9\xb5\xc5\x15\x11\xae\x49\x76\x6c\x79\x2a\x29\x52\x03\x88\x44\x4e\xbe\xfe\x28\x25\x6f\xb3\x3d\x42\x60\x43\x9c\xba\x73\xa9\x47\x9e\xe0\x0c\x63",
+       "\xa9\x36\xfb\x9a\xf8\x7f\xb6\x78\x57\xb3\xea\xd5\xc7\x62\x26\xad\x84\xda\x47\x67\x8f\x3c\x2f\xfe\x5a\x39\xfd\xb5\xf7\xe6\x3f\xfb",
+       144 },
+      { GCRY_MD_SHA3_256,
+       "\x83\x6b\x34\xb5\x15\x47\x6f\x61\x3f\xe4\x47\xa4\xe0\xc3\xf3\xb8\xf2\x09\x10\xac\x89\xa3\x97\x70\x55\xc9\x60\xd2\xd5\xd2\xb7\x2b\xd8\xac\xc7\x15\xa9\x03\x53\x21\xb8\x67\x03\xa4\x11\xdd\xe0\x46\x6d\x58\xa5\x97\x69\x67\x2a\xa6\x0a\xd5\x87\xb8\x48\x1d\xe4\xbb\xa5\x52\xa1\x64\x57\x79\x78\x95\x01\xec\x53\xd5\x40\xb9\x04\x82\x1f\x32\xb0\xbd\x18\x55\xb0\x4e\x48\x48\xf9\xf8\xcf\xe9\xeb\xd8\x91\x1b\xe9\x57\x81\xa7\x59\xd7\xad\x97\x24\xa7\x10\x2d\xbe\x57\x67\x76\xb7\xc6\x32\xbc\x39\xb9\xb5\xe1\x90\x57\xe2\x26\x55\x2a\x59\x94\xc1\xdb\xb3\xb5\xc7\x87\x1a\x11\xf5\x53\x70\x11\x04\x4c\x53",
+       "\x3a\x65\x4b\x88\xf8\x80\x86\xc2\x75\x1e\xda\xe6\xd3\x92\x48\x14\x3c\xf6\x23\x5c\x6b\x0b\x79\x69\x34\x2c\x45\xa3\x51\x94\xb6\x7e",
+       145 },
+      { GCRY_MD_SHA3_256,
+       "\xcc\x77\x84\xa4\x91\x2a\x7a\xb5\xad\x36\x20\xaa\xb2\x9b\xa8\x70\x77\xcd\x3c\xb8\x36\x36\xad\xc9\xf3\xdc\x94\xf5\x1e\xdf\x52\x1b\x21\x61\xef\x10\x8f\x21\xa0\xa2\x98\x55\x79\x81\xc0\xe5\x3c\xe6\xce\xd4\x5b\xdf\x78\x2c\x1e\xf2\x00\xd2\x9b\xab\x81\xdd\x64\x60\x58\x69\x64\xed\xab\x7c\xeb\xdb\xbe\xc7\x5f\xd7\x92\x50\x60\xf7\xda\x2b\x85\x3b\x2b\x08\x95\x88\xfa\x0f\x8c\x16\xec\x64\x98\xb1\x4c\x55\xdc\xee\x33\x5c\xb3\xa9\x1d\x69\x8e\x4d\x39\x3a\xb8\xe8\xea\xc0\x82\x5f\x8a\xde\xbe\xee\x19\x6d\xf4\x12\x05\xc0\x11\x67\x4e\x53\x42\x6c\xaa\x45\x3f\x8d\xe1\xcb\xb5\x79\x32\xb0\xb7\x41\xd4\xc6",
+       "\x19\xa3\xcb\x3e\x85\x51\xf0\x8f\xbb\xa5\xdb\x61\x4e\x26\x8f\x63\xd1\xf6\xa0\xc3\x68\x9b\xbe\x97\x3d\x59\xd3\x5b\xb4\xf4\x55\xd0",
+       146 },
+      { GCRY_MD_SHA3_256,
+       "\x76\x39\xb4\x61\xff\xf2\x70\xb2\x45\x5a\xc1\xd1\xaf\xce\x78\x29\x44\xae\xa5\xe9\x08\x7e\xb4\xa3\x9e\xb9\x6b\xb5\xc3\xba\xaf\x0e\x86\x8c\x85\x26\xd3\x40\x4f\x94\x05\xe7\x9e\x77\xbf\xac\x5f\xfb\x89\xbf\x19\x57\xb5\x23\xe1\x7d\x34\x1d\x73\x23\xc3\x02\xea\x70\x83\x87\x2d\xd5\xe8\x70\x56\x94\xac\xdd\xa3\x6d\x5a\x1b\x89\x5a\xaa\x16\xec\xa6\x10\x4c\x82\x68\x85\x32\xc8\xbf\xe1\x79\x0b\x5d\xc9\xf4\xec\x5f\xe9\x5b\xae\xd3\x7e\x1d\x28\x7b\xe7\x10\x43\x1f\x1e\x5e\x8e\xe1\x05\xbc\x42\xed\x37\xd7\x4b\x1e\x55\x98\x4b\xf1\xc0\x9f\xe6\xa1\xfa\x13\xef\x3b\x96\xfa\xea\xed\x6a\x2a\x19\x50\xa1\x21\x53",
+       "\xca\x8c\xfb\x13\x97\x3f\xf8\x59\x7d\x6a\xaa\x80\x6b\xd3\x2e\x82\xf4\xea\x68\xba\xc3\xfb\x54\x3f\x26\x68\x7d\xe4\xb9\xcb\xe8\xbd",
+       147 },
+      { GCRY_MD_SHA3_256,
+       "\xeb\x65\x13\xfc\x61\xb3\x0c\xfb\xa5\x8d\x4d\x7e\x80\xf9\x4d\x14\x58\x90\x90\xcf\x1d\x80\xb1\xdf\x2e\x68\x08\x8d\xc6\x10\x49\x59\xba\x0d\x58\x3d\x58\x5e\x95\x78\xab\x0a\xec\x0c\xf3\x6c\x48\x43\x5e\xb5\x2e\xd9\xab\x4b\xbc\xe7\xa5\xab\xe6\x79\xc9\x7a\xe2\xdb\xe3\x5e\x8c\xc1\xd4\x5b\x06\xdd\xa3\xcf\x41\x86\x65\xc5\x7c\xbe\xe4\xbb\xb4\x7f\xa4\xca\xf7\x8f\x4e\xe6\x56\xfe\xc2\x37\xfe\x4e\xeb\xba\xfa\x20\x6e\x1e\xf2\xbd\x0e\xe4\xae\x71\xbd\x0e\x9b\x2f\x54\xf9\x1d\xaa\xdf\x1f\xeb\xfd\x70\x32\x38\x1d\x63\x6b\x73\x3d\xcb\x3b\xf7\x6f\xb1\x4e\x23\xaf\xf1\xf6\x8e\xd3\xdb\xcf\x75\xc9\xb9\x9c\x6f\x26",
+       "\x9a\xe6\x70\xfa\x85\xab\x5c\x6b\x3b\xc7\x67\x97\xcf\x24\xcd\x38\x51\x10\x70\x81\x37\xb6\xf8\xef\xd8\xd1\xa2\x1c\x39\x88\x1c\x18",
+       148 },
+      { GCRY_MD_SHA3_256,
+       "\x15\x94\xd7\x4b\xf5\xdd\xe4\x44\x26\x5d\x4c\x04\xda\xd9\x72\x1f\xf3\xe3\x4c\xbf\x62\x2d\xaf\x34\x1f\xe1\x6b\x96\x43\x1f\x6c\x4d\xf1\xf7\x60\xd3\x4f\x29\x6e\xb9\x7d\x98\xd5\x60\xad\x52\x86\xfe\xc4\xdc\xe1\x72\x4f\x20\xb5\x4f\xd7\xdf\x51\xd4\xbf\x13\x7a\xdd\x65\x6c\x80\x54\x6f\xb1\xbf\x51\x6d\x62\xee\x82\xba\xa9\x92\x91\x0e\xf4\xcc\x18\xb7\x0f\x3f\x86\x98\x27\x6f\xcf\xb4\x4e\x0e\xc5\x46\xc2\xc3\x9c\xfd\x8e\xe9\x10\x34\xff\x93\x03\x05\x8b\x42\x52\x46\x2f\x86\xc8\x23\xeb\x15\xbf\x48\x1e\x6b\x79\xcc\x3a\x02\x21\x85\x95\xb3\x65\x8e\x8b\x37\x38\x2b\xd5\x04\x8e\xae\xd5\xfd\x02\xc3\x79\x44\xe7\x3b",
+       "\xe3\x2d\xf6\x21\x8b\xa7\x5f\xd4\x78\x8a\x7e\x57\x27\xa7\xd6\x8c\x58\x29\xc4\x93\x46\x68\x3f\xc2\x13\xe4\x33\xaf\x3d\xba\x5a\xb5",
+       149 },
+      { GCRY_MD_SHA3_256,
+       "\x4c\xfa\x12\x78\x90\x30\x26\xf6\x6f\xed\xd4\x13\x74\x55\x8b\xe1\xb5\x85\xd0\x3c\x5c\x55\xda\xc9\x43\x61\xdf\x28\x6d\x4b\xd3\x9c\x7c\xb8\x03\x7e\xd3\xb2\x67\xb0\x7c\x34\x66\x26\x44\x9d\x0c\xc5\xb0\xdd\x2c\xf2\x21\xf7\xe4\xc3\x44\x9a\x4b\xe9\x99\x85\xd2\xd5\xe6\x7b\xff\x29\x23\x35\x7d\xde\xab\x5a\xbc\xb4\x61\x9f\x3a\x3a\x57\xb2\xcf\x92\x8a\x02\x2e\xb2\x76\x76\xc6\xcf\x80\x56\x89\x00\x4f\xca\x4d\x41\xea\x6c\x2d\x0a\x47\x89\xc7\x60\x5f\x7b\xb8\x38\xdd\x88\x3b\x3a\xd3\xe6\x02\x7e\x77\x5b\xcf\x26\x28\x81\x42\x80\x99\xc7\xff\xf9\x5b\x14\xc0\x95\xea\x13\x0e\x0b\x99\x38\xa5\xe2\x2f\xc5\x26\x50\xf5\x91",
+       "\x02\x81\x73\xe3\xc6\xc3\x92\xe5\xd1\x3a\xf7\x48\xf3\x78\x8d\x43\x44\x9b\xc5\xdd\x59\x53\x12\x4e\xa5\xed\xf3\x93\x02\x75\xf6\x65",
+       150 },
+      { GCRY_MD_SHA3_256,
+       "\xd3\xe6\x5c\xb9\x2c\xfa\x79\x66\x2f\x6a\xf4\x93\xd6\x96\xa0\x7c\xcf\x32\xaa\xad\xcc\xef\xf0\x6e\x73\xe8\xd9\xf6\xf9\x09\x20\x9e\x66\x71\x5d\x6e\x97\x87\x88\xc4\x9e\xfb\x90\x87\xb1\x70\xec\xf3\xaa\x86\xd2\xd4\xd1\xa0\x65\xae\x0e\xfc\x89\x24\xf3\x65\xd6\x76\xb3\xcb\x9e\x2b\xec\x91\x8f\xd9\x6d\x0b\x43\xde\xe8\x37\x27\xc9\xa9\x3b\xf5\x6c\xa2\xb2\xe5\x9a\xdb\xa8\x56\x96\x54\x6a\x81\x50\x67\xfc\x7a\x78\x03\x96\x29\xd4\x94\x8d\x15\x7e\x7b\x0d\x82\x6d\x1b\xf8\xe8\x12\x37\xba\xb7\x32\x13\x12\xfd\xaa\x4d\x52\x17\x44\xf9\x88\xdb\x6f\xdf\x04\x54\x9d\x0f\xdc\xa3\x93\xd6\x39\xc7\x29\xaf\x71\x6e\x9c\x8b\xba\x48",
+       "\x97\x45\x0f\xc4\x6f\x2e\x5d\xf8\xf8\x16\x23\xb1\xcc\xa4\x3f\xa5\x0f\x51\xea\x73\x5e\x44\x21\xd7\xdf\xf6\x63\x14\xd8\xe2\x11\xbc",
+       151 },
+      { GCRY_MD_SHA3_256,
+       "\x84\x2c\xc5\x83\x50\x45\x39\x62\x2d\x7f\x71\xe7\xe3\x18\x63\xa2\xb8\x85\xc5\x6a\x0b\xa6\x2d\xb4\xc2\xa3\xf2\xfd\x12\xe7\x96\x60\xdc\x72\x05\xca\x29\xa0\xdc\x0a\x87\xdb\x4d\xc6\x2e\xe4\x7a\x41\xdb\x36\xb9\xdd\xb3\x29\x3b\x9a\xc4\xba\xae\x7d\xf5\xc6\xe7\x20\x1e\x17\xf7\x17\xab\x56\xe1\x2c\xad\x47\x6b\xe4\x96\x08\xad\x2d\x50\x30\x9e\x7d\x48\xd2\xd8\xde\x4f\xa5\x8a\xc3\xcf\xea\xfe\xee\x48\xc0\xa9\xee\xc8\x84\x98\xe3\xef\xc5\x1f\x54\xd3\x00\xd8\x28\xdd\xdc\xcb\x9d\x0b\x06\xdd\x02\x1a\x29\xcf\x5c\xb5\xb2\x50\x69\x15\xbe\xb8\xa1\x19\x98\xb8\xb8\x86\xe0\xf9\xb7\xa8\x0e\x97\xd9\x1a\x7d\x01\x27\x0f\x9a\x77\x17",
+       "\xab\x4e\x5a\x70\x39\x05\x77\xf8\xae\x26\x0d\x53\xcb\x0e\x70\x91\x4f\x8b\x93\x98\xab\xaa\x84\x1f\x78\x07\xf1\x47\x60\x46\xc6\x4f",
+       152 },
+      { GCRY_MD_SHA3_256,
+       "\x6c\x4b\x0a\x07\x19\x57\x3e\x57\x24\x86\x61\xe9\x8f\xeb\xe3\x26\x57\x1f\x9a\x1c\xa8\x13\xd3\x63\x85\x31\xae\x28\xb4\x86\x0f\x23\xc3\xa3\xa8\xac\x1c\x25\x00\x34\xa6\x60\xe2\xd7\x1e\x16\xd3\xac\xc4\xbf\x9c\xe2\x15\xc6\xf1\x5b\x1c\x0f\xc7\xe7\x7d\x3d\x27\x15\x7e\x66\xda\x9c\xee\xc9\x25\x8f\x8f\x2b\xf9\xe0\x2b\x4a\xc9\x37\x93\xdd\x6e\x29\xe3\x07\xed\xe3\x69\x5a\x0d\xf6\x3c\xbd\xc0\xfc\x66\xfb\x77\x08\x13\xeb\x14\x9c\xa2\xa9\x16\x91\x1b\xee\x49\x02\xc4\x7c\x78\x02\xe6\x9e\x40\x5f\xe3\xc0\x4c\xeb\x55\x22\x79\x2a\x55\x03\xfa\x82\x9f\x70\x72\x72\x22\x66\x21\xf7\xc4\x88\xa7\x69\x8c\x0d\x69\xaa\x56\x1b\xe9\xf3\x78",
+       "\x81\x18\xf2\xc1\x57\xdf\x12\x50\xdb\x43\xb3\x11\x83\xf4\x42\xf8\x9b\x32\x2e\x49\x69\x18\x83\x8c\x5b\x66\x8f\x96\x47\xac\x6d\x6b",
+       153 },
+      { GCRY_MD_SHA3_256,
+       "\x51\xb7\xdb\xb7\xce\x2f\xfe\xb4\x27\xa9\x1c\xcf\xe5\x21\x8f\xd4\x0f\x9e\x0b\x7e\x24\x75\x6d\x4c\x47\xcd\x55\x60\x60\x08\xbd\xc2\x7d\x16\x40\x09\x33\x90\x6f\xd9\xf3\x0e\xff\xdd\x48\x80\x02\x2d\x08\x11\x55\x34\x2a\xf3\xfb\x6c\xd5\x36\x72\xab\x7f\xb5\xb3\xa3\xbc\xbe\x47\xbe\x1f\xd3\xa2\x27\x8c\xae\x8a\x5f\xd6\x1c\x14\x33\xf7\xd3\x50\x67\x5d\xd2\x18\x03\x74\x6c\xad\xca\x57\x41\x30\xf0\x12\x00\x02\x4c\x63\x40\xab\x0c\xc2\xcf\x74\xf2\x23\x46\x69\xf3\x4e\x90\x09\xef\x2e\xb9\x48\x23\xd6\x2b\x31\x40\x7f\x4b\xa4\x6f\x1a\x1e\xec\x41\x64\x1e\x84\xd7\x77\x27\xb5\x9e\x74\x6b\x8a\x67\x1b\xef\x93\x6f\x05\xbe\x82\x07\x59\xfa",
+       "\x73\x6e\x30\xac\xcc\x55\x59\x18\x84\x12\xc7\x97\xa1\xa5\xbe\x61\xd1\xf9\x0f\x14\x94\x01\xf6\x31\x59\x79\x44\x15\x5a\x85\xfa\xf7",
+       154 },
+      { GCRY_MD_SHA3_256,
+       "\x83\x59\x9d\x93\xf5\x56\x1e\x82\x1b\xd0\x1a\x47\x23\x86\xbc\x2f\xf4\xef\xbd\x4a\xed\x60\xd5\x82\x1e\x84\xaa\xe7\x4d\x80\x71\x02\x98\x10\xf5\xe2\x86\xf8\xf1\x76\x51\xcd\x27\xda\x07\xb1\xeb\x43\x82\xf7\x54\xcd\x1c\x95\x26\x87\x83\xad\x09\x22\x0f\x55\x02\x84\x03\x70\xd4\x94\xbe\xb1\x71\x24\x22\x0f\x6a\xfc\xe9\x1e\xc8\xa0\xf5\x52\x31\xf9\x65\x24\x33\xe5\xce\x34\x89\xb7\x27\x71\x6c\xf4\xae\xba\x7d\xcd\xa2\x0c\xd2\x9a\xa9\xa8\x59\x20\x12\x53\xf9\x48\xdd\x94\x39\x5a\xba\x9e\x38\x52\xbd\x1d\x60\xdd\xa7\xae\x5d\xc0\x45\xb2\x83\xda\x00\x6e\x1c\xba\xd8\x3c\xc1\x32\x92\xa3\x15\xdb\x55\x53\x30\x5c\x62\x8d\xd0\x91\x14\x65\x97",
+       "\x95\x99\xde\xec\xcc\x69\x8a\x24\xa4\x61\xa7\x41\x9e\x91\x93\x9c\x74\x16\x13\xf4\xce\x88\x7d\xba\x89\xdc\x7e\x32\x7c\x51\xf5\xbf",
+       155 },
+      { GCRY_MD_SHA3_256,
+       "\x2b\xe9\xbf\x52\x6c\x9d\x5a\x75\xd5\x65\xdd\x11\xef\x63\xb9\x79\xd0\x68\x65\x9c\x7f\x02\x6c\x08\xbe\xa4\xaf\x16\x1d\x85\xa4\x62\xd8\x0e\x45\x04\x0e\x91\xf4\x16\x5c\x07\x4c\x43\xac\x66\x13\x80\x31\x1a\x8c\xbe\xd5\x9c\xc8\xe4\xc4\x51\x8e\x80\xcd\x2c\x78\xab\x1c\xab\xf6\x6b\xff\x83\xea\xb3\xa8\x01\x48\x55\x03\x07\x31\x09\x50\xd0\x34\xa6\x28\x6c\x93\xa1\xec\xe8\x92\x9e\x63\x85\xc5\xe3\xbb\x6e\xa8\xa7\xc0\xfb\x6d\x63\x32\xe3\x20\xe7\x1c\xc4\xeb\x46\x2a\x2a\x62\xe2\xbf\xe0\x8f\x0c\xca\xd9\x3e\x61\xbe\xdb\x5d\xd0\xb7\x86\xa7\x28\xab\x66\x6f\x07\xe0\x57\x6d\x18\x9c\x92\xbf\x9f\xb2\x0d\xca\x49\xac\x2d\x39\x56\xd4\x73\x85\xe2",
+       "\xbe\x0d\x87\x16\x06\xa4\xc1\x29\xce\xf6\x16\xf4\x38\x60\x0d\x5c\xbc\x0e\x9f\x49\xd2\xad\xc8\xa8\x65\x71\xc1\x92\x36\x1c\x3f\x4f",
+       156 },
+      { GCRY_MD_SHA3_256,
+       "\xca\x76\xd3\xa1\x25\x95\xa8\x17\x68\x26\x17\x00\x68\x48\x67\x55\x47\xd3\xe8\xf5\x0c\x22\x10\xf9\xaf\x90\x6c\x0e\x7c\xe5\x0b\x44\x60\x18\x6f\xe7\x04\x57\xa9\xe8\x79\xe7\x9f\xd4\xd1\xa6\x88\xc7\x0a\x34\x73\x61\xc8\x47\xba\x0d\xd6\xaa\x52\x93\x6e\xaf\x8e\x58\xa1\xbe\x2f\x5c\x1c\x70\x4e\x20\x14\x6d\x36\x6a\xeb\x38\x53\xbe\xd9\xde\x9b\xef\xe9\x56\x9a\xc8\xaa\xea\x37\xa9\xfb\x71\x39\xa1\xa1\xa7\xd5\xc7\x48\x60\x5a\x8d\xef\xb2\x97\x86\x9e\xbe\xdd\x71\xd6\x15\xa5\xda\x23\x49\x6d\x11\xe1\x1a\xbb\xb1\x26\xb2\x06\xfa\x0a\x77\x97\xee\x7d\xe1\x17\x98\x60\x12\xd0\x36\x2d\xce\xf7\x75\xc2\xfe\x14\x5a\xda\x6b\xda\x1c\xcb\x32\x6b\xf6\x44",
+       "\x4d\x30\x60\x0c\x60\xed\x94\xa0\xd2\xbc\xc1\x75\x71\xa1\x9b\xd0\x17\x0c\xda\xca\xc7\x8d\x04\x21\xe0\xbb\xae\x2a\x36\xa4\x8b\x6d",
+       157 },
+      { GCRY_MD_SHA3_256,
+       "\xf7\x6b\x85\xdc\x67\x42\x10\x25\xd6\x4e\x93\x09\x6d\x1d\x71\x2b\x7b\xaf\x7f\xb0\x01\x71\x6f\x02\xd3\x3b\x21\x60\xc2\xc8\x82\xc3\x10\xef\x13\xa5\x76\xb1\xc2\xd3\x0e\xf8\xf7\x8e\xf8\xd2\xf4\x65\x00\x71\x09\xaa\xd9\x3f\x74\xcb\x9e\x7d\x7b\xef\x7c\x95\x90\xe8\xaf\x3b\x26\x7c\x89\xc1\x5d\xb2\x38\x13\x8c\x45\x83\x3c\x98\xcc\x4a\x47\x1a\x78\x02\x72\x3e\xf4\xc7\x44\xa8\x53\xcf\x80\xa0\xc2\x56\x8d\xd4\xed\x58\xa2\xc9\x64\x48\x06\xf4\x21\x04\xce\xe5\x36\x28\xe5\xbd\xf7\xb6\x3b\x0b\x33\x8e\x93\x1e\x31\xb8\x7c\x24\xb1\x46\xc6\xd0\x40\x60\x55\x67\xce\xef\x59\x60\xdf\x9e\x02\x2c\xb4\x69\xd4\xc7\x87\xf4\xcb\xa3\xc5\x44\xa1\xac\x91\xf9\x5f",
+       "\x3b\xd6\xfb\x72\x76\x4f\x7a\xd4\x39\x1b\x7b\x40\xae\xa4\x24\xab\xd5\xf5\x56\x1a\xc5\x6f\x9e\x07\x2c\x75\x3d\x60\x90\xfa\x4b\xfb",
+       158 },
+      { GCRY_MD_SHA3_256,
+       "\x25\xb8\xc9\xc0\x32\xea\x6b\xcd\x73\x3f\xfc\x87\x18\xfb\xb2\xa5\x03\xa4\xea\x8f\x71\xde\xa1\x17\x61\x89\xf6\x94\x30\x4f\x0f\xf6\x8e\x86\x2a\x81\x97\xb8\x39\x95\x75\x49\xef\x24\x3a\x52\x79\xfc\x26\x46\xbd\x4c\x00\x9b\x6d\x1e\xde\xbf\x24\x73\x81\x97\xab\xb4\xc9\x92\xf6\xb1\xdc\x9b\xa8\x91\xf5\x70\x87\x9a\xcc\xd5\xa6\xb1\x86\x91\xa9\x3c\x7d\x0a\x8d\x38\xf9\x5b\x63\x9c\x1d\xae\xb4\x8c\x4c\x2f\x15\xcc\xf5\xb9\xd5\x08\xf8\x33\x3c\x32\xde\x78\x78\x1b\x41\x85\x0f\x26\x1b\x85\x5c\x4b\xeb\xcc\x12\x5a\x38\x0c\x54\xd5\x01\xc5\xd3\xbd\x07\xe6\xb5\x21\x02\x11\x60\x88\xe5\x3d\x76\x58\x3b\x01\x61\xe2\xa5\x8d\x07\x78\xf0\x91\x20\x6a\xab\xd5\xa1",
+       "\x66\x89\xbb\x25\xba\xee\x0c\x58\x2f\x8f\x1b\x0c\x87\x07\x3b\xe3\x66\x64\x4d\xa8\x59\x31\x3b\xec\xf4\x46\x43\x5d\x2f\x6e\x89\x9e",
+       159 },
+      { GCRY_MD_SHA3_256,
+       "\x21\xcf\xdc\x2a\x7c\xcb\x7f\x33\x1b\x3d\x2e\xef\xff\x37\xe4\x8a\xd9\xfa\x9c\x78\x8c\x3f\x3c\x20\x0e\x01\x73\xd9\x99\x63\xe1\xcb\xca\x93\x62\x3b\x26\x4e\x92\x03\x94\xae\x48\xbb\x4c\x3a\x5b\xb9\x6f\xfb\xc8\xf0\xe5\x3f\x30\xe2\x29\x56\xad\xab\xc2\x76\x5f\x57\xfb\x76\x1e\x14\x7e\xcb\xf8\x56\x75\x33\xdb\x6e\x50\xc8\xa1\xf8\x94\x31\x0a\x94\xed\xf8\x06\xdd\x8c\xa6\xa0\xe1\x41\xc0\xfa\x7c\x9f\xae\x6c\x6a\xe6\x5f\x18\xc9\x3a\x85\x29\xe6\xe5\xb5\x53\xbf\x55\xf2\x5b\xe2\xe8\x0a\x98\x82\xbd\x37\xf1\x45\xfe\xcb\xeb\x3d\x44\x7a\x3c\x4e\x46\xc2\x15\x24\xcc\x55\xcd\xd6\x2f\x52\x1a\xb9\x2a\x8b\xa7\x2b\x89\x79\x96\xc4\x9b\xb2\x73\x19\x8b\x7b\x1c\x9e",
+       "\x26\x28\xdd\xc7\x75\x82\x08\xaa\x9f\x1e\x49\x49\x72\x24\xeb\x26\x8c\x6d\x2b\xcd\xaa\xb4\x82\x0d\xe9\xc1\x6a\x65\xc6\xf6\x01\x7a",
+       160 },
+      { GCRY_MD_SHA3_256,
+       "\x4e\x45\x2b\xa4\x21\x27\xdc\xc9\x56\xef\x4f\x8f\x35\xdd\x68\xcb\x22\x5f\xb7\x3b\x5b\xc7\xe1\xec\x5a\x89\x8b\xba\x29\x31\x56\x3e\x74\xfa\xff\x3b\x67\x31\x4f\x24\x1e\xc4\x9f\x4a\x70\x61\xe3\xbd\x02\x13\xae\x82\x6b\xab\x38\x0f\x1f\x14\xfa\xab\x8b\x0e\xfd\xdd\x5f\xd1\xbb\x49\x37\x38\x53\xa0\x8f\x30\x55\x3d\x5a\x55\xcc\xbb\xb8\x15\x3d\xe4\x70\x4f\x29\xca\x2b\xde\xef\x04\x19\x46\x8e\x05\xdd\x51\x55\x7c\xcc\x80\xc0\xa9\x61\x90\xbb\xcc\x4d\x77\xec\xff\x21\xc6\x6b\xdf\x48\x64\x59\xd4\x27\xf9\x86\x41\x0f\x88\x3a\x80\xa5\xbc\xc3\x2c\x20\xf0\x47\x8b\xb9\xa9\x7a\x12\x6f\xc5\xf9\x54\x51\xe4\x0f\x29\x2a\x46\x14\x93\x0d\x05\x4c\x85\x1a\xcd\x01\x9c\xcf",
+       "\xdf\x44\x89\x36\xee\x72\xd9\xfe\x6c\xcf\xb3\x7d\x18\x3a\xaf\xdd\xc7\x90\x8e\x01\x62\x71\xaf\xa8\x1e\xc0\x83\xa1\x0a\x14\x4f\x5d",
+       161 },
+      { GCRY_MD_SHA3_256,
+       "\xfa\x85\x67\x1d\xf7\xda\xdf\x99\xa6\xff\xee\x97\xa3\xab\x99\x91\x67\x1f\x56\x29\x19\x50\x49\x88\x04\x97\x48\x78\x67\xa6\xc4\x46\xb6\x00\x87\xfa\xc9\xa0\xf2\xfc\xc8\xe3\xb2\x4e\x97\xe4\x23\x45\xb9\x3b\x5f\x7d\x36\x91\x82\x9d\x3f\x8c\xcd\x4b\xb3\x64\x11\xb8\x5f\xc2\x32\x8e\xb0\xc5\x1c\xb3\x15\x1f\x70\x86\x0a\xd3\x24\x6c\xe0\x62\x3a\x8d\xc8\xb3\xc4\x9f\x95\x8f\x86\x90\xf8\xe3\x86\x0e\x71\xeb\x2b\x14\x79\xa5\xce\xa0\xb3\xf8\xbe\xfd\x87\xac\xaf\x53\x62\x43\x5e\xae\xcc\xb5\x2f\x38\x61\x7b\xc6\xc5\xc2\xc6\xe2\x69\xea\xd1\xfb\xd6\x9e\x94\x1d\x4a\xd2\x01\x2d\xa2\xc5\xb2\x1b\xcf\xbf\x98\xe4\xa7\x7a\xb2\xaf\x1f\x3f\xda\x32\x33\xf0\x46\xd3\x8f\x1d\xc8",
+       "\x2b\xb4\xce\xc2\x2a\x4f\xec\xd8\x3f\xbb\xba\xd1\xe3\x83\x53\x43\xe3\x6c\x6c\xb6\x6c\x26\x96\x4a\x43\x2e\xc4\xc7\x0f\x3e\x17\xb4",
+       162 },
+      { GCRY_MD_SHA3_256,
+       "\xe9\x08\x47\xae\x67\x97\xfb\xc0\xb6\xb3\x6d\x6e\x58\x8c\x0a\x74\x3d\x72\x57\x88\xca\x50\xb6\xd7\x92\x35\x2e\xa8\x29\x4f\x5b\xa6\x54\xa1\x53\x66\xb8\xe1\xb2\x88\xd8\x4f\x51\x78\x24\x08\x27\x97\x5a\x76\x3b\xc4\x5c\x7b\x04\x30\xe8\xa5\x59\xdf\x44\x88\x50\x5e\x00\x9c\x63\xda\x99\x4f\x14\x03\xf4\x07\x95\x82\x03\xce\xbb\x6e\x37\xd8\x9c\x94\xa5\xea\xcf\x60\x39\xa3\x27\xf6\xc4\xdb\xbc\x7a\x2a\x30\x7d\x97\x6a\xa3\x9e\x41\xaf\x65\x37\x24\x3f\xc2\x18\xdf\xa6\xab\x4d\xd8\x17\xb6\xa3\x97\xdf\x5c\xa6\x91\x07\xa9\x19\x87\x99\xed\x24\x86\x41\xb6\x3b\x42\xcb\x4c\x29\xbf\xdd\x79\x75\xac\x96\xed\xfc\x27\x4a\xc5\x62\xd0\x47\x4c\x60\x34\x7a\x07\x8c\xe4\xc2\x5e\x88",
+       "\x14\x62\xf2\xea\x1c\x35\x80\xc0\xa2\xe8\xc0\xb3\x0c\x27\xa6\x08\xd8\x2c\xd7\x07\xf6\xd1\xa0\xaa\xd5\xcc\x7c\x3d\x1b\x8d\x6c\x30",
+       163 },
+      { GCRY_MD_SHA3_256,
+       "\xf6\xd5\xc2\xb6\xc9\x39\x54\xfc\x62\x76\x02\xc0\x0c\x4c\xa9\xa7\xd3\xed\x12\xb2\x71\x73\xf0\xb2\xc9\xb0\xe4\xa5\x93\x93\x98\xa6\x65\xe6\x7e\x69\xd0\xb1\x2f\xb7\xe4\xce\xb2\x53\xe8\x08\x3d\x1c\xeb\x72\x4a\xc0\x7f\x00\x9f\x09\x4e\x42\xf2\xd6\xf2\x12\x94\x89\xe8\x46\xea\xff\x07\x00\xa8\xd4\x45\x3e\xf4\x53\xa3\xed\xdc\x18\xf4\x08\xc7\x7a\x83\x27\x56\x17\xfa\xbc\x4e\xa3\xa2\x83\x3a\xa7\x34\x06\xc0\xe9\x66\x27\x60\x79\xd3\x8e\x8e\x38\x53\x9a\x70\xe1\x94\xcc\x55\x13\xaa\xa4\x57\xc6\x99\x38\x3f\xd1\x90\x0b\x1e\x72\xbd\xfb\x83\x5d\x1f\xd3\x21\xb3\x7b\xa8\x05\x49\xb0\x78\xa4\x9e\xa0\x81\x52\x86\x9a\x91\x8c\xa5\x7f\x5b\x54\xed\x71\xe4\xfd\x3a\xc5\xc0\x67\x29",
+       "\x61\x7b\x41\x2e\xd6\x4f\x56\xd6\xdb\x36\xb7\xe5\x2e\xad\x61\x8d\x95\xa0\x91\xd6\x50\x52\xc3\xf3\x76\xa5\x32\xd8\xbb\xda\xf7\xc7",
+       164 },
+      { GCRY_MD_SHA3_256,
+       "\xcf\x85\x62\xb1\xbe\xd8\x98\x92\xd6\x7d\xda\xaf\x3d\xee\xb2\x82\x46\x45\x6e\x97\x23\x26\xdb\xcd\xb5\xcf\x3f\xb2\x89\xac\xa0\x1e\x68\xda\x5d\x59\x89\x6e\x3a\x61\x65\x35\x8b\x07\x1b\x30\x4d\x6a\xb3\xd0\x18\x94\x4b\xe5\x04\x9d\x5e\x0e\x2b\xb8\x19\xac\xf6\x7a\x60\x06\x11\x10\x89\xe6\x76\x71\x32\xd7\x2d\xd8\x5b\xed\xdc\xbb\x2d\x64\x49\x6d\xb0\xcc\x92\x95\x5a\xb4\xc6\x23\x4f\x1e\xea\x24\xf2\xd5\x14\x83\xf2\xe2\x09\xe4\x58\x9b\xf9\x51\x9f\xac\x51\xb4\xd0\x61\xe8\x01\x12\x5e\x60\x5f\x80\x93\xbb\x69\x97\xbc\x16\x3d\x55\x15\x96\xfe\x4a\xb7\xcf\xae\x8f\xb9\xa9\x0f\x69\x80\x48\x0c\xe0\xc2\x29\xfd\x16\x75\x40\x9b\xd7\x88\x35\x4d\xaf\x31\x62\x40\xcf\xe0\xaf\x93\xeb",
+       "\x82\xc5\x41\xea\x5c\xb1\x5d\x1a\x41\x25\xf5\x36\x82\x59\x38\xc2\x35\x8e\xec\x2b\xdd\xc5\xd1\xcc\x40\x42\xde\x3a\xf0\x36\xca\x55",
+       165 },
+      { GCRY_MD_SHA3_256,
+       "\x2a\xce\x31\xab\xb0\xa2\xe3\x26\x79\x44\xd2\xf7\x5e\x15\x59\x98\x5d\xb7\x35\x4c\x6e\x60\x5f\x18\xdc\x84\x70\x42\x3f\xca\x30\xb7\x33\x1d\x9b\x33\xc4\xa4\x32\x67\x83\xd1\xca\xae\x1b\x4f\x07\x06\x0e\xff\x97\x8e\x47\x46\xbf\x0c\x7e\x30\xcd\x61\x04\x0b\xd5\xec\x27\x46\xb2\x98\x63\xeb\x7f\x10\x3e\xbd\xa6\x14\xc4\x29\x1a\x80\x5b\x6a\x4c\x82\x14\x23\x05\x64\xa0\x55\x7b\xc7\x10\x2e\x0b\xd3\xed\x23\x71\x92\x52\xf7\x43\x5d\x64\xd2\x10\xee\x2a\xaf\xc5\x85\xbe\x90\x3f\xa4\x1e\x19\x68\xc5\x0f\xd5\xd5\x36\x79\x26\xdf\x7a\x05\xe3\xa4\x2c\xf0\x7e\x65\x6f\xf9\x2d\xe7\x3b\x03\x6c\xf8\xb1\x98\x98\xc0\xcb\x34\x55\x7c\x0c\x12\xc2\xd8\xb8\x4e\x91\x18\x1a\xf4\x67\xbc\x75\xa9\xd1",
+       "\x68\x4b\xb7\x93\x24\x33\x21\x8c\x61\x6f\x05\x90\xb0\x39\xce\xfa\xc9\x72\x82\x84\x70\x64\x7d\x15\x91\xce\xac\x88\x9c\x89\x32\x72",
+       166 },
+      { GCRY_MD_SHA3_256,
+       "\x0d\x8d\x09\xae\xd1\x9f\x10\x13\x96\x9c\xe5\xe7\xeb\x92\xf8\x3a\x20\x9a\xe7\x6b\xe3\x1c\x75\x48\x44\xea\x91\x16\xce\xb3\x9a\x22\xeb\xb6\x00\x30\x17\xbb\xcf\x26\x55\x5f\xa6\x62\x41\x85\x18\x7d\xb8\xf0\xcb\x35\x64\xb8\xb1\xc0\x6b\xf6\x85\xd4\x7f\x32\x86\xed\xa2\x0b\x83\x35\x8f\x59\x9d\x20\x44\xbb\xf0\x58\x3f\xab\x8d\x78\xf8\x54\xfe\x0a\x59\x61\x83\x23\x0c\x5e\xf8\xe5\x44\x26\x75\x0e\xaf\x2c\xc4\xe2\x9d\x3b\xdd\x03\x7e\x73\x4d\x86\x3c\x2b\xd9\x78\x9b\x4c\x24\x30\x96\x13\x8f\x76\x72\xc2\x32\x31\x4e\xff\xdf\xc6\x51\x34\x27\xe2\xda\x76\x91\x6b\x52\x48\x93\x3b\xe3\x12\xeb\x5d\xde\x4c\xf7\x08\x04\xfb\x25\x8a\xc5\xfb\x82\xd5\x8d\x08\x17\x7a\xc6\xf4\x75\x60\x17\xff\xf5",
+       "\x50\x8b\x2a\xf3\x76\xba\x64\x67\xcf\x98\x2c\x76\x7c\x84\x8d\x2b\xda\x8d\x06\x8a\x53\x41\x6f\x07\x4a\x0c\x98\xc4\x73\xd0\x2f\x6b",
+       167 },
+      { GCRY_MD_SHA3_256,
+       "\xc3\x23\x6b\x73\xde\xb7\x66\x2b\xf3\xf3\xda\xa5\x8f\x13\x7b\x35\x8b\xa6\x10\x56\x0e\xf7\x45\x57\x85\xa9\xbe\xfd\xb0\x35\xa0\x66\xe9\x07\x04\xf9\x29\xbd\x96\x89\xce\xf0\xce\x3b\xda\x5a\xcf\x44\x80\xbc\xeb\x8d\x09\xd1\x0b\x09\x8a\xd8\x50\x0d\x9b\x60\x71\xdf\xc3\xa1\x4a\xf6\xc7\x75\x11\xd8\x1e\x3a\xa8\x84\x49\x86\xc3\xbe\xa6\xf4\x69\xf9\xe0\x21\x94\xc9\x28\x68\xcd\x5f\x51\x64\x62\x56\x79\x8f\xf0\x42\x49\x54\xc1\x43\x4b\xdf\xed\x9f\xac\xb3\x90\xb0\x7d\x34\x2e\x99\x29\x36\xe0\xf8\x8b\xfd\x0e\x88\x4a\x0d\xdb\x67\x9d\x05\x47\xcc\xde\xc6\x38\x42\x85\xa4\x54\x29\xd1\x15\xac\x7d\x23\x5a\x71\x72\x42\x02\x1d\x1d\xc3\x56\x41\xf5\xf0\xa4\x8e\x84\x45\xdb\xa5\x8e\x6c\xb2\xc8\xea",
+       "\x55\xe2\x28\xbc\xbd\xa7\x06\x16\x42\xd0\x04\x37\x3d\x4e\x64\x07\xb7\x2a\x37\x38\x1d\x1b\xef\xfc\xbf\xbf\x9f\x5f\x6e\xa0\x93\xea",
+       168 },
+      { GCRY_MD_SHA3_256,
+       "\xb3\x9f\xeb\x82\x83\xea\xdc\x63\xe8\x18\x4b\x51\xdf\x5a\xe3\xfd\x41\xaa\xc8\xa9\x63\xbb\x0b\xe1\xcd\x08\xaa\x58\x67\xd8\xd9\x10\xc6\x69\x22\x1e\x73\x24\x33\x60\x64\x6f\x65\x53\xd1\xca\x05\xa8\x4e\x8d\xc0\xde\x05\xb6\x41\x9e\xc3\x49\xca\x99\x44\x80\x19\x3d\x01\xc9\x25\x25\xf3\xfb\x3d\xce\xfb\x08\xaf\xc6\xd2\x69\x47\xbd\xbb\xfd\x85\x19\x3f\x53\xb5\x06\x09\xc6\x14\x09\x05\xc5\x3a\x66\x86\xb5\x8e\x53\xa3\x19\xa5\x7b\x96\x23\x31\xed\xe9\x81\x49\xaf\x3d\xe3\x11\x8a\x81\x9d\xa4\xd7\x67\x06\xa0\x42\x4b\x4e\x1d\x29\x10\xb0\xed\x26\xaf\x61\xd1\x50\xeb\xcb\x46\x59\x5d\x42\x66\xa0\xbd\x7f\x65\x1b\xa4\x7d\x0c\x7f\x17\x9c\xa2\x85\x45\x00\x7d\x92\xe8\x41\x9d\x48\xfd\xfb\xd7\x44\xce",
+       "\x05\x23\xc0\x9b\xbc\xff\xe4\x18\xd3\xfc\xd2\x2c\x6a\xbf\x95\xab\xfb\x38\xf9\x4c\xe5\x56\x2b\x8b\xfc\xd2\xee\xa9\xfb\x72\x90\x41",
+       169 },
+      { GCRY_MD_SHA3_256,
+       "\xa9\x83\xd5\x4f\x50\x38\x03\xe8\xc7\x99\x9f\x4e\xdb\xbe\x82\xe9\x08\x4f\x42\x21\x43\xa9\x32\xdd\xdd\xc4\x7a\x17\xb0\xb7\x56\x4a\x7f\x37\xa9\x9d\x07\x86\xe9\x94\x76\x42\x8d\x29\xe2\x9d\x3c\x19\x7a\x72\xbf\xab\x13\x42\xc1\x2a\x0f\xc4\x78\x7f\xd7\x01\x7d\x7a\x61\x74\x04\x9e\xa4\x3b\x57\x79\x16\x9e\xf7\x47\x2b\xdb\xbd\x94\x1d\xcb\x82\xfc\x73\xaa\xc4\x5a\x8a\x94\xc9\xf2\xbd\x34\x77\xf6\x1f\xd3\xb7\x96\xf0\x2a\x1b\x82\x64\xa2\x14\xc6\xfe\xa7\x4b\x70\x51\xb2\x26\xc7\x22\x09\x9e\xc7\x88\x3a\x46\x2b\x83\xb6\xaf\xdd\x40\x09\x24\x8b\x8a\x23\x7f\x60\x5f\xe5\xa0\x8f\xe7\xd8\xb4\x53\x21\x42\x1e\xbb\xa6\x7b\xd7\x0a\x0b\x00\xdd\xbf\x94\xba\xab\x7f\x35\x9d\x5d\x1e\xea\x10\x5f\x28\xdc\xfb",
+       "\xdc\xbc\x25\x82\x41\xad\xed\x37\x99\x99\x6c\x2a\xd6\xed\x0e\x3d\x74\xcf\xcc\x67\x74\x9d\x34\x80\xb2\xa9\xa7\x8e\x5f\x8a\xff\x82",
+       170 },
+      { GCRY_MD_SHA3_256,
+       "\xe4\xd1\xc1\x89\x7a\x0a\x86\x6c\xe5\x64\x63\x5b\x74\x22\x2f\x96\x96\xbf\x2c\x7f\x64\x0d\xd7\x8d\x7e\x2a\xca\x66\xe1\xb6\x1c\x64\x2b\xb0\x3e\xa7\x53\x6a\xae\x59\x78\x11\xe9\xbf\x4a\x7b\x45\x3e\xde\x31\xf9\x7b\x46\xa5\xf0\xef\x51\xa0\x71\xa2\xb3\x91\x8d\xf1\x6b\x15\x25\x19\xae\x37\x76\xf9\xf1\xed\xab\x4c\x2a\x37\x7c\x32\x92\xe9\x64\x08\x35\x9d\x36\x13\x84\x4d\x5e\xb3\x93\x00\x02\x83\xd5\xad\x34\x01\xa3\x18\xb1\x2f\xd1\x47\x4b\x86\x12\xf2\xbb\x50\xfb\x6a\x8b\x9e\x02\x3a\x54\xd7\xdd\xe2\x8c\x43\xd6\xd8\x85\x4c\x8d\x9d\x11\x55\x93\x5c\x19\x98\x11\xdb\xfc\x87\xe9\xe0\x07\x2e\x90\xeb\x88\x68\x1c\xc7\x52\x97\x14\xf8\xfb\x8a\x2c\x9d\x88\x56\x7a\xdf\xb9\x74\xee\x20\x5a\x9b\xf7\xb8\x48",
+       "\xcb\xe8\x31\x8e\x7b\x2f\xe7\x2b\xfc\xd2\x53\x0c\xcc\xec\xea\x40\x18\xb1\x58\x7f\x48\x3b\x73\xf5\x0c\xe5\xe8\x4c\xed\x65\xe0\x93",
+       171 },
+      { GCRY_MD_SHA3_256,
+       "\xb1\x0c\x59\x72\x3e\x3d\xca\xdd\x6d\x75\xdf\x87\xd0\xa1\x58\x0e\x73\x13\x3a\x9b\x7d\x00\xcb\x95\xec\x19\xf5\x54\x70\x27\x32\x3b\xe7\x51\x58\xb1\x1f\x80\xb6\xe1\x42\xc6\xa7\x85\x31\x88\x6d\x90\x47\xb0\x8e\x55\x1e\x75\xe6\x26\x1e\x79\x78\x53\x66\xd7\x02\x4b\xd7\xcd\x9c\xf3\x22\xd9\xbe\x7d\x57\xfb\x66\x10\x69\xf2\x48\x1c\x7b\xb7\x59\xcd\x71\xb4\xb3\x6c\xa2\xbc\x2d\xf6\xd3\xa3\x28\xfa\xeb\xdb\x99\x5a\x97\x94\xa8\xd7\x21\x55\xed\x55\x1a\x1f\x87\xc8\x0b\xf6\x05\x9b\x43\xfc\x76\x49\x00\xb1\x8a\x1c\x24\x41\xf7\x48\x77\x43\xcf\x84\xe5\x65\xf6\x1f\x8d\xd2\xec\xe6\xb6\xcc\xc9\x44\x40\x49\x19\x7a\xaa\xf5\x3e\x92\x6f\xbe\xe3\xbf\xca\x8b\xe5\x88\xec\x77\xf2\x9d\x21\x1b\xe8\x9d\xe1\x8b\x15\xf6",
+       "\x8c\xea\x29\x60\x08\x70\x48\xe6\xe6\xd4\x7e\x31\x55\x4f\x30\x5f\xcc\x81\xe0\x3e\x90\xba\x8f\x83\x32\xdd\x86\xc6\xb6\xb3\x8e\x03",
+       172 },
+      { GCRY_MD_SHA3_256,
+       "\xdb\x11\xf6\x09\xba\xba\x7b\x0c\xa6\x34\x92\x6b\x1d\xd5\x39\xc8\xcb\xad\xa2\x49\x67\xd7\xad\xd4\xd9\x87\x6f\x77\xc2\xd8\x0c\x0f\x4d\xce\xfb\xd7\x12\x15\x48\x37\x35\x82\x70\x5c\xca\x24\x95\xbd\x2a\x43\x71\x6f\xe6\x4e\xd2\x6d\x05\x9c\xfb\x56\x6b\x33\x64\xbd\x49\xee\x07\x17\xbd\xd9\x81\x0d\xd1\x4d\x8f\xad\x80\xdb\xbd\xc4\xca\xfb\x37\xcc\x60\xfb\x0f\xe2\xa8\x0f\xb4\x54\x1b\x8c\xa9\xd5\x9d\xce\x45\x77\x38\xa9\xd3\xd8\xf6\x41\xaf\x8c\x3f\xd6\xda\x16\x2d\xc1\x6f\xc0\x1a\xac\x52\x7a\x4a\x02\x55\xb4\xd2\x31\xc0\xbe\x50\xf4\x4f\x0d\xb0\xb7\x13\xaf\x03\xd9\x68\xfe\x7f\x0f\x61\xed\x08\x24\xc5\x5c\x4b\x52\x65\x54\x8f\xeb\xd6\xaa\xd5\xc5\xee\xdf\x63\xef\xe7\x93\x48\x9c\x39\xb8\xfd\x29\xd1\x04\xce",
+       "\x44\xe2\x76\x99\x1e\x53\x82\xbd\x7e\xb5\xad\xcf\x1f\x79\x36\x28\x04\xd3\x46\xbe\xdf\xc6\x91\x6f\x4d\xca\x4b\x57\x24\x0e\x9c\x99",
+       173 },
+      { GCRY_MD_SHA3_256,
+       "\xbe\xbd\x4f\x1a\x84\xfc\x8b\x15\xe4\x45\x2a\x54\xbd\x02\xd6\x9e\x30\x4b\x7f\x32\x61\x6a\xad\xd9\x05\x37\x93\x71\x06\xae\x4e\x28\xde\x9d\x8a\xab\x02\xd1\x9b\xc3\xe2\xfd\xe1\xd6\x51\x55\x9e\x29\x64\x53\xe4\xdb\xa9\x43\x70\xa1\x4d\xbb\xb2\xd1\xd4\xe2\x02\x23\x02\xee\x90\xe2\x08\x32\x1e\xfc\xd8\x52\x8a\xd8\x9e\x46\xdc\x83\x9e\xa9\xdf\x61\x8e\xa8\x39\x4a\x6b\xff\x30\x8e\x77\x26\xba\xe0\xc1\x9b\xcd\x4b\xe5\x2d\xa6\x25\x8e\x2e\xf4\xe9\x6a\xa2\x12\x44\x42\x9f\x49\xef\x5c\xb4\x86\xd7\xff\x35\xca\xc1\xba\xcb\x7e\x95\x71\x19\x44\xbc\xcb\x2a\xb3\x47\x00\xd4\x2d\x1e\xb3\x8b\x5d\x53\x6b\x94\x73\x48\xa4\x58\xed\xe3\xdc\x6b\xd6\xec\x54\x7b\x1b\x0c\xae\x5b\x25\x7b\xe3\x6a\x71\x24\xe1\x06\x0c\x17\x0f\xfa",
+       "\x80\x89\x1a\x08\x6a\xf3\x85\x02\x50\x68\x79\x9f\x19\x24\x11\xc6\x89\xcc\x4e\x0d\x9a\x59\xf3\xf4\x1d\xbb\x02\xa3\x43\xf1\xa7\x59",
+       174 },
+      { GCRY_MD_SHA3_256,
+       "\x5a\xca\x56\xa0\x3a\x13\x78\x4b\xdc\x32\x89\xd9\x36\x4f\x79\xe2\xa8\x5c\x12\x27\x6b\x49\xb9\x2d\xb0\xad\xaa\x4f\x20\x6d\x50\x28\xf2\x13\xf6\x78\xc3\x51\x0e\x11\x1f\x9d\xc4\xc1\xc1\xf8\xb6\xac\xb1\x7a\x64\x13\xaa\x22\x76\x07\xc5\x15\xc6\x2a\x73\x38\x17\xba\x5e\x76\x2c\xc6\x74\x8e\x7e\x0d\x68\x72\xc9\x84\xd7\x23\xc9\xbb\x3b\x11\x7e\xb8\x96\x31\x85\x30\x0a\x80\xbf\xa6\x5c\xde\x49\x5d\x70\xa4\x6c\x44\x85\x86\x05\xfc\xcb\xed\x08\x6c\x2b\x45\xce\xf9\x63\xd3\x32\x94\xdb\xe9\x70\x6b\x13\xaf\x22\xf1\xb7\xc4\xcd\x5a\x00\x1c\xfe\xc2\x51\xfb\xa1\x8e\x72\x2c\x6e\x1c\x4b\x11\x66\x91\x8b\x4f\x6f\x48\xa9\x8b\x64\xb3\xc0\x7f\xc8\x6a\x6b\x17\xa6\xd0\x48\x0a\xb7\x9d\x4e\x64\x15\xb5\x20\xf1\xc4\x84\xd6\x75\xb1",
+       "\x77\xdd\xf0\x34\xb7\xdf\xd6\xb2\x92\xaa\x3b\x0c\x1e\x55\x2f\x47\xb1\xd8\xc2\x30\x78\x04\x2c\xc5\x8b\xb3\xdd\x47\x20\xb9\xee\x4d",
+       175 },
+      { GCRY_MD_SHA3_256,
+       "\xa5\xaa\xd0\xe4\x64\x6a\x32\xc8\x5c\xfc\xac\x73\xf0\x2f\xc5\x30\x0f\x19\x82\xfa\xbb\x2f\x21\x79\xe2\x83\x03\xe4\x47\x85\x40\x94\xcd\xfc\x85\x43\x10\xe5\xc0\xf6\x09\x93\xce\xff\x54\xd8\x4d\x6b\x46\x32\x3d\x93\x0a\xdb\x07\xc1\x75\x99\xb3\x5b\x50\x5f\x09\xe7\x84\xbc\xa5\x98\x5e\x01\x72\x25\x77\x97\xfb\x53\x64\x9e\x2e\x97\x23\xef\xd1\x68\x65\xc3\x1b\x5c\x3d\x51\x13\xb5\x8b\xb0\xbf\xc8\x92\x0f\xab\xdd\xa0\x86\xd7\x53\x7e\x66\xd7\x09\xd0\x50\xbd\x14\xd0\xc9\x60\x87\x3f\x15\x6f\xad\x5b\x3d\x38\x40\xcd\xfc\xdc\x9b\xe6\xaf\x51\x9d\xb2\x62\xa2\x7f\x40\x89\x6a\xb2\x5c\xc3\x9f\x96\x98\x4d\x65\x06\x11\xc0\xd5\xa3\x08\x0d\x5b\x3a\x1b\xf1\x86\xab\xd4\x29\x56\x58\x8b\x3b\x58\xcd\x94\x89\x70\xd2\x98\x77\x60\x60",
+       "\x23\xd2\x68\x8d\x86\x7a\x18\x04\x0e\x82\xf7\x87\x6a\xcf\x04\xdc\x3a\x9c\x01\x40\xfe\xdd\x93\xeb\xe7\xad\xf9\x20\xb2\xf8\x3d\xa4",
+       176 },
+      { GCRY_MD_SHA3_256,
+       "\x06\xcb\xbe\x67\xe9\x4a\x97\x82\x03\xea\xd6\xc0\x57\xa1\xa5\xb0\x98\x47\x8b\x4b\x4c\xbe\xf5\xa9\x7e\x93\xc8\xe4\x2f\x55\x72\x71\x35\x75\xfc\x2a\x88\x45\x31\xd7\x62\x2f\x8f\x87\x93\x87\xa8\x59\xa8\x0f\x10\xef\x02\x70\x8c\xd8\xf7\x41\x3a\xb3\x85\xaf\xc3\x57\x67\x8b\x95\x78\xc0\xeb\xf6\x41\xef\x07\x6a\x1a\x30\xf1\xf7\x53\x79\xe9\xdc\xb2\xa8\x85\xbd\xd2\x95\x90\x5e\xe8\x0c\x01\x68\xa6\x2a\x95\x97\xd1\x0c\xf1\x2d\xd2\xd8\xce\xe4\x66\x45\xc7\xe5\xa1\x41\xf6\xe0\xe2\x3a\xa4\x82\xab\xe5\x66\x1c\x16\xe6\x9e\xf1\xe2\x83\x71\xe2\xe2\x36\xc3\x59\xba\x4e\x92\xc2\x56\x26\xa7\xb7\xff\x13\xf6\xea\x4a\xe9\x06\xe1\xcf\xe1\x63\xe9\x17\x19\xb1\xf7\x50\xa9\x6c\xbd\xe5\xfb\xc9\x53\xd9\xe5\x76\xcd\x21\x6a\xfc\x90\x32\x3a",
+       "\x2d\xf6\x66\xfc\x5d\x4e\xad\x1c\x3b\x10\xb9\xf8\xd4\xbb\x81\xae\xa4\xf9\x3d\x38\x73\xd5\xce\x5c\xfb\xac\x4b\x69\x43\x5e\x1b\x7c",
+       177 },
+      { GCRY_MD_SHA3_256,
+       "\xf1\xc5\x28\xcf\x77\x39\x87\x47\x07\xd4\xd8\xad\x5b\x98\xf7\xc7\x71\x69\xde\x0b\x57\x18\x8d\xf2\x33\xb2\xdc\x8a\x5b\x31\xed\xa5\xdb\x42\x91\xdd\x9f\x68\xe6\xba\xd3\x7b\x8d\x7f\x6c\x9c\x00\x44\xb3\xbf\x74\xbb\xc3\xd7\xd1\x79\x8e\x13\x87\x09\xb0\xd7\x5e\x7c\x59\x3d\x3c\xcc\xdc\x1b\x20\xc7\x17\x4b\x4e\x69\x2a\xdd\x82\x0a\xce\x26\x2d\x45\xcc\xfa\xe2\x07\x7e\x87\x87\x96\x34\x71\x68\x06\x0a\x16\x2e\xcc\xa8\xc3\x8c\x1a\x88\x35\x0b\xd6\x3b\xb5\x39\x13\x4f\x70\x0f\xd4\xad\xdd\x59\x59\xe2\x55\x33\x7d\xaa\x06\xbc\x86\x35\x8f\xab\xcb\xef\xdf\xb5\xbc\x88\x97\x83\xd8\x43\xc0\x8a\xad\xc6\xc4\xf6\xc3\x6f\x65\xf1\x56\xe8\x51\xc9\xa0\xf9\x17\xe4\xa3\x67\xb5\xad\x93\xd8\x74\x81\x2a\x1d\xe6\xa7\xb9\x3c\xd5\x3a\xd9\x72\x32",
+       "\xaf\x0c\x54\x74\x52\x80\x32\xe2\x62\x9b\x8f\xbb\x0e\x34\x40\x5f\x7f\x25\x1d\x41\xe7\x3b\x56\x67\xbe\x3c\x07\xcc\xb2\xc1\xc9\x53",
+       178 },
+      { GCRY_MD_SHA3_256,
+       "\x9d\x9f\x3a\x7e\xcd\x51\xb4\x1f\x65\x72\xfd\x0d\x08\x81\xe3\x03\x90\xdf\xb7\x80\x99\x1d\xae\x7d\xb3\xb4\x76\x19\x13\x47\x18\xe6\xf9\x87\x81\x0e\x54\x26\x19\xdf\xaa\x7b\x50\x5c\x76\xb7\x35\x0c\x64\x32\xd8\xbf\x1c\xfe\xbd\xf1\x06\x9b\x90\xa3\x5f\x0d\x04\xcb\xdf\x13\x0b\x0d\xfc\x78\x75\xf4\xa4\xe6\x2c\xdb\x8e\x52\x5a\xad\xd7\xce\x84\x25\x20\xa4\x82\xac\x18\xf0\x94\x42\xd7\x83\x05\xfe\x85\xa7\x4e\x39\xe7\x60\xa4\x83\x74\x82\xed\x2f\x43\x7d\xd1\x3b\x2e\xc1\x04\x2a\xfc\xf9\xde\xcd\xc3\xe8\x77\xe5\x0f\xf4\x10\x6a\xd1\x0a\x52\x52\x30\xd1\x19\x20\x32\x4a\x81\x09\x4d\xa3\x1d\xea\xb6\x47\x6a\xa4\x2f\x20\xc8\x48\x43\xcf\xc1\xc5\x85\x45\xee\x80\x35\x2b\xdd\x37\x40\xdd\x6a\x16\x79\x2a\xe2\xd8\x6f\x11\x64\x1b\xb7\x17\xc2",
+       "\x9b\xbe\xf7\xa7\x53\x91\x35\x4a\x38\x8a\xaa\x7c\xa0\x35\xdc\x62\xd3\x23\x1b\x80\x09\x1b\xb7\x74\x8f\x76\xe5\x2d\x8e\x9f\x20\xf0",
+       179 },
+      { GCRY_MD_SHA3_256,
+       "\x51\x79\x88\x87\x24\x81\x9f\xba\xd3\xaf\xa9\x27\xd3\x57\x77\x96\x66\x0e\x6a\x81\xc5\x2d\x98\xe9\x30\x32\x61\xd5\xa4\xa8\x32\x32\xf6\xf7\x58\x93\x4d\x50\xaa\x83\xff\x9e\x20\xa5\x92\x6d\xfe\xba\xac\x49\x52\x9d\x00\x6e\xb9\x23\xc5\xae\x50\x48\xed\x54\x4e\xc4\x71\xed\x71\x91\xed\xf4\x63\x63\x38\x38\x24\xf9\x15\x76\x9b\x3e\x68\x80\x94\xc6\x82\xb0\x21\x51\xe5\xee\x01\xe5\x10\xb4\x31\xc8\x86\x5a\xff\x8b\x6b\x6f\x2f\x59\xcb\x6d\x12\x9d\xa7\x9e\x97\xc6\xd2\xb8\xfa\x6c\x6d\xa3\xf6\x03\x19\x9d\x2d\x1b\xca\xb5\x47\x68\x2a\x81\xcd\x6c\xf6\x5f\x65\x51\x12\x13\x91\xd7\x8b\xcc\x23\xb5\xbd\x0e\x92\x2e\xc6\xd8\xbf\x97\xc9\x52\xe8\x4d\xd2\x8a\xef\x90\x9a\xba\x31\xed\xb9\x03\xb2\x8f\xbf\xc3\x3b\x77\x03\xcd\x99\x62\x15\xa1\x12\x38",
+       "\xb1\x08\x45\x7a\x6b\xd3\x31\xbe\x43\xc9\xfe\x1e\x2a\x02\xe8\xc7\x44\xc2\xbc\xc9\x27\xa9\xc3\xc4\x86\xf1\x10\xdc\xcf\x90\x7f\x6b",
+       180 },
+      { GCRY_MD_SHA3_256,
+       "\x57\x6e\xf3\x52\x0d\x30\xb7\xa4\x89\x9b\x8c\x0d\x5e\x35\x9e\x45\xc5\x18\x9a\xdd\x10\x0e\x43\xbe\x42\x9a\x02\xfb\x3d\xe5\xff\x4f\x8f\xd0\xe7\x9d\x96\x63\xac\xca\x72\xcd\x29\xc9\x45\x82\xb1\x92\x92\xa5\x57\xc5\xb1\x31\x52\x97\xd1\x68\xfb\xb5\x4e\x9e\x2e\xcd\x13\x80\x9c\x2b\x5f\xce\x99\x8e\xdc\x65\x70\x54\x5e\x14\x99\xdb\xe7\xfb\x74\xd4\x7c\xd7\xf3\x58\x23\xb2\x12\xb0\x5b\xf3\xf5\xa7\x9c\xaa\x34\x22\x4f\xdd\x67\x0d\x33\x5f\xcb\x10\x6f\x5d\x92\xc3\x94\x6f\x44\xd3\xaf\xcb\xae\x2e\x41\xac\x55\x4d\x8e\x67\x59\xf3\x32\xb7\x6b\xe8\x9a\x03\x24\xaa\x12\xc5\x48\x2d\x1e\xa3\xee\x89\xde\xd4\x93\x6f\x3e\x3c\x08\x04\x36\xf5\x39\xfa\x13\x7e\x74\xc6\xd3\x38\x9b\xdf\x5a\x45\x07\x4c\x47\xbc\x7b\x20\xb0\x94\x84\x07\xa6\x6d\x85\x5e\x2f",
+       "\xa6\x11\x09\x83\x8d\xfa\x5b\x14\x6d\xf4\xe6\xc3\xbd\xbc\x7a\x47\x7b\xe3\x6b\x62\x28\xeb\xd9\x10\x25\x01\x2a\xf4\xcc\x0e\xb4\x09",
+       181 },
+      { GCRY_MD_SHA3_256,
+       "\x0d\xf2\x15\x2f\xa4\xf4\x35\x7c\x87\x41\x52\x9d\xd7\x7e\x78\x39\x25\xd3\xd7\x6e\x95\xba\xfa\x2b\x54\x2a\x2c\x33\xf3\xd1\xd1\x17\xd1\x59\xcf\x47\x3f\x82\x31\x03\x56\xfe\xe4\xc9\x0a\x9e\x50\x5e\x70\xf8\xf2\x48\x59\x65\x63\x68\xba\x09\x38\x1f\xa2\x45\xeb\x6c\x3d\x76\x3f\x30\x93\xf0\xc8\x9b\x97\x2e\x66\xb5\x3d\x59\x40\x6d\x9f\x01\xae\xa0\x7f\x8b\x3b\x61\x5c\xac\x4e\xe4\xd0\x5f\x54\x2e\x7d\x0d\xab\x45\xd6\x7c\xcc\xcd\x3a\x60\x6c\xcb\xeb\x31\xea\x1f\xa7\x00\x5b\xa0\x71\x76\xe6\x0d\xab\x7d\x78\xf6\x81\x0e\xf0\x86\xf4\x2f\x08\xe5\x95\xf0\xec\x21\x73\x72\xb9\x89\x70\xcc\x63\x21\x57\x6d\x92\xce\x38\xf7\xc3\x97\xa4\x03\xba\xda\x15\x48\xd2\x05\xc3\x43\xac\x09\xde\xca\x86\x32\x53\x73\xc3\xb7\x6d\x9f\x32\x02\x8f\xea\x8e\xb3\x25\x15",
+       "\x4f\x0f\x30\xc8\x90\xb0\xab\x40\x49\x61\x15\x85\x73\x53\x8f\xe9\xa2\xb2\x34\xb9\x4a\x09\x91\xf2\x6d\x5e\xa0\x4f\xdd\xc9\xc5\x65",
+       182 },
+      { GCRY_MD_SHA3_256,
+       "\x3e\x15\x35\x0d\x87\xd6\xeb\xb5\xc8\xad\x99\xd4\x25\x15\xcf\xe1\x79\x80\x93\x3c\x7a\x8f\x6b\x8b\xbb\xf0\xa6\x37\x28\xce\xfa\xad\x20\x52\x62\x3c\x0b\xd5\x93\x18\x39\x11\x2a\x48\x63\x3f\xb3\xc2\x00\x4e\x07\x49\xc8\x7a\x41\xb2\x6a\x8b\x48\x94\x55\x39\xd1\xff\x41\xa4\xb2\x69\x46\x2f\xd1\x99\xbf\xec\xd4\x53\x74\x75\x6f\x55\xa9\x11\x6e\x92\x09\x3a\xc9\x94\x51\xae\xfb\x2a\xf9\xfd\x32\xd6\xd7\xf5\xfb\xc7\xf7\xa5\x40\xd5\x09\x7c\x09\x6e\xbc\x3b\x3a\x72\x15\x41\xde\x07\x3a\x1c\xc0\x2f\x7f\xb0\xfb\x1b\x93\x27\xfb\x0b\x12\x18\xca\x49\xc9\x48\x7a\xb5\x39\x66\x22\xa1\x3a\xe5\x46\xc9\x7a\xbd\xef\x6b\x56\x38\x0d\xda\x70\x12\xa8\x38\x40\x91\xb6\x65\x6d\x0a\xb2\x72\xd3\x63\xce\xa7\x81\x63\xff\x76\x5c\xdd\x13\xab\x17\x38\xb9\x40\xd1\x6c\xae",
+       "\x85\x45\x9c\xfb\x02\x89\x59\x9c\xdd\x67\xc4\x73\xa0\xba\x6d\xa6\x16\xc6\x08\xe3\x67\xf5\x8c\x50\xa0\x35\x62\x42\x4d\xcf\x1d\x06",
+       183 },
+      { GCRY_MD_SHA3_256,
+       "\xc3\x8d\x6b\x0b\x75\x7c\xb5\x52\xbe\x40\x94\x0e\xce\x00\x09\xef\x3b\x0b\x59\x30\x7c\x14\x51\x68\x6f\x1a\x22\x70\x29\x22\x80\x0d\x58\xbc\xe7\xa6\x36\xc1\x72\x7e\xe5\x47\xc0\x1b\x21\x47\x79\xe8\x98\xfc\x0e\x56\x0f\x8a\xe7\xf6\x1b\xef\x4d\x75\xea\xa6\x96\xb9\x21\xfd\x6b\x73\x5d\x17\x15\x35\xe9\xed\xd2\x67\xc1\x92\xb9\x98\x80\xc8\x79\x97\x71\x10\x02\x00\x90\x95\xd8\xa7\xa4\x37\xe2\x58\x10\x4a\x41\xa5\x05\xe5\xef\x71\xe5\x61\x3d\xdd\x20\x08\x19\x5f\x0c\x57\x4e\x6b\xa3\xfe\x40\x09\x9c\xfa\x11\x6e\x5f\x1a\x2f\xa8\xa6\xda\x04\xba\xdc\xb4\xe2\xd5\xd0\xde\x31\xfd\xc4\x80\x08\x91\xc4\x57\x81\xa0\xaa\xc7\xc9\x07\xb5\x6d\x63\x1f\xca\x5c\xe8\xb2\xcd\xe6\x20\xd1\x1d\x17\x77\xed\x9f\xa6\x03\x54\x1d\xe7\x94\xdd\xc5\x75\x8f\xcd\x5f\xad\x78\xc0",
+       "\x55\x39\xd2\xe5\x2a\x5a\x1b\xb3\xc2\x46\xb0\x15\x83\x56\xe2\xb2\x78\x2f\xc1\x3c\x10\x24\x89\x37\xa0\xc4\xa4\x0b\x09\x1f\x62\x47",
+       184 },
+      { GCRY_MD_SHA3_256,
+       "\x8d\x2d\xe3\xf0\xb3\x7a\x63\x85\xc9\x07\x39\x80\x5b\x17\x00\x57\xf0\x91\xcd\x0c\x7a\x0b\xc9\x51\x54\x0f\x26\xa5\xa7\x5b\x3e\x69\x46\x31\xbb\x64\xc7\x63\x5e\xed\x31\x6f\x51\x31\x8e\x9d\x8d\xe1\x3c\x70\xa2\xab\xa0\x4a\x14\x83\x68\x55\xf3\x5e\x48\x05\x28\xb7\x76\xd0\xa1\xe8\xa2\x3b\x54\x7c\x8b\x8d\x6a\x0d\x09\xb2\x41\xd3\xbe\x93\x77\x16\x0c\xca\x4e\x67\x93\xd0\x0a\x51\x5d\xc2\x99\x2c\xb7\xfc\x74\x1d\xac\xa1\x71\x43\x1d\xa9\x9c\xce\x6f\x77\x89\xf1\x29\xe2\xac\x5c\xf6\x5b\x40\xd7\x03\x03\x5c\xd2\x18\x5b\xb9\x36\xc8\x20\x02\xda\xf8\xcb\xc2\x7a\x7a\x9e\x55\x4b\x06\x19\x66\x30\x44\x6a\x6f\x0a\x14\xba\x15\x5e\xd2\x6d\x95\xbd\x62\x7b\x72\x05\xc0\x72\xd0\x2b\x60\xdb\x0f\xd7\xe4\x9e\xa0\x58\xc2\xe0\xba\x20\x2d\xaf\xf0\xde\x91\xe8\x45\xcf\x79",
+       "\x6d\x63\x41\x92\x07\xb9\x9d\x4d\xb1\xad\xd7\x95\xd8\x52\xa8\xda\xac\x11\xb7\x89\xaf\x0c\x7d\x63\x53\x03\x6c\xb2\x3f\x64\x28\xb4",
+       185 },
+      { GCRY_MD_SHA3_256,
+       "\xc4\x64\xbb\xda\xd2\x75\xc5\x0d\xcd\x98\x3b\x65\xad\x10\x19\xb9\xff\x85\xa1\xe7\x1c\x80\x7f\x32\x04\xbb\x2c\x92\x1d\xc3\x1f\xbc\xd8\xc5\xfc\x45\x86\x8a\xe9\xef\x85\xb6\xc9\xb8\x3b\xba\x2a\x5a\x82\x22\x01\xed\x68\x58\x6e\xc5\xec\x27\xfb\x28\x57\xa5\xd1\xa2\xd0\x9d\x09\x11\x5f\x22\xdc\xc3\x9f\xe6\x1f\x5e\x1b\xa0\xff\x6e\x8b\x4a\xcb\x4c\x6d\xa7\x48\xbe\x7f\x3f\x08\x39\x73\x93\x94\xff\x7f\xa8\xe3\x9f\x7f\x7e\x84\xa3\x3c\x38\x66\x87\x5c\x01\xbc\xb1\x26\x3c\x94\x05\xd9\x19\x08\xe9\xe0\xb5\x0e\x74\x59\xfa\xbb\x63\xd8\xc6\xbb\xb7\x3d\x8e\x34\x83\xc0\x99\xb5\x5b\xc3\x0f\xf0\x92\xff\x68\xb6\xad\xed\xfd\x47\x7d\x63\x57\x0c\x9f\x55\x15\x84\x7f\x36\xe2\x4b\xa0\xb7\x05\x55\x71\x30\xce\xc5\x7e\xba\xd1\xd0\xb3\x1a\x37\x8e\x91\x89\x4e\xe2\x6e\x3a\x04",
+       "\xd2\x09\x0d\xae\x0f\xc2\x01\xb2\xb9\xc0\x3d\xd4\x82\xa8\xeb\x1f\xfd\x3c\xf7\x0c\x55\xf9\x8d\x6f\x39\xa4\x1b\x8b\xda\xc2\x7a\x17",
+       186 },
+      { GCRY_MD_SHA3_256,
+       "\x8b\x8d\x68\xbb\x8a\x75\x73\x2f\xe2\x72\x81\x5a\x68\xa1\xc9\xc5\xaa\x31\xb4\x1d\xed\xc8\x49\x3e\x76\x52\x5d\x1d\x01\x3d\x33\xce\xbd\x9e\x21\xa5\xbb\x95\xdb\x26\x16\x97\x6a\x8c\x07\xfc\xf4\x11\xf5\xf6\xbc\x6f\x7e\x0b\x57\xac\xa7\x8c\xc2\x79\x0a\x6f\x9b\x89\x88\x58\xac\x9c\x79\xb1\x65\xff\x24\xe6\x66\x77\x53\x1e\x39\xf5\x72\xbe\x5d\x81\xeb\x32\x64\x52\x41\x81\x11\x5f\x32\x78\x02\x57\xbf\xb9\xae\xec\x6a\xf1\x2a\xf2\x8e\x58\x7c\xac\x06\x8a\x1a\x29\x53\xb5\x9a\xd6\x80\xf4\xc2\x45\xb2\xe3\xec\x36\xf5\x99\x40\xd3\x7e\x1d\x3d\xb3\x8e\x13\xed\xb2\x9b\x5c\x0f\x40\x4f\x6f\xf8\x7f\x80\xfc\x8b\xe7\xa2\x25\xff\x22\xfb\xb9\xc8\xb6\xb1\xd7\x33\x0c\x57\x84\x0d\x24\xbc\x75\xb0\x6b\x80\xd3\x0d\xad\x68\x06\x54\x4d\x51\x0a\xf6\xc4\x78\x5e\x82\x3a\xc3\xe0\xb8",
+       "\xc9\xe8\xf9\x6b\xa7\x5e\xaf\x37\x1d\xca\x35\xdc\x69\x13\x8e\xca\x8c\xb3\xf2\x82\x3f\x3b\xe5\x51\xd9\xdc\x8a\xa6\xa4\xed\x41\x69",
+       187 },
+      { GCRY_MD_SHA3_256,
+       "\x6b\x01\x87\x10\x44\x6f\x36\x8e\x74\x21\xf1\xbc\x0c\xcf\x56\x2d\x9c\x18\x43\x84\x6b\xc8\xd9\x8d\x1c\x9b\xf7\xd9\xd6\xfc\xb4\x8b\xfc\x3b\xf8\x3b\x36\xd4\x4c\x4f\xa9\x34\x30\xaf\x75\xcd\x19\x0b\xde\x36\xa7\xf9\x2f\x86\x7f\x58\xa8\x03\x90\x0d\xf8\x01\x81\x50\x38\x4d\x85\xd8\x21\x32\xf1\x23\x00\x6a\xc2\xae\xba\x58\xe0\x2a\x03\x7f\xe6\xaf\xbd\x65\xec\xa7\xc4\x49\x77\xdd\x3d\xc7\x4f\x48\xb6\xe7\xa1\xbf\xd5\xcc\x4d\xcf\x24\xe4\xd5\x2e\x92\xbd\x44\x55\x84\x8e\x49\x28\xb0\xea\xc8\xb7\x47\x6f\xe3\xcc\x03\xe8\x62\xaa\x4d\xff\x44\x70\xdb\xfe\xd6\xde\x48\xe4\x10\xf2\x50\x96\x48\x7e\xcf\xc3\x2a\x27\x27\x7f\x3f\x50\x23\xb2\x72\x5a\xde\x46\x1b\x13\x55\x88\x95\x54\xa8\x83\x6c\x9c\xf5\x3b\xd7\x67\xf5\x73\x7d\x55\x18\x4e\xea\x1a\xb3\xf5\x3e\xdd\x09\x76\xc4\x85",
+       "\x23\x3b\x0b\xc2\x81\x43\xc3\x2a\x66\x8b\x0a\xb5\xd7\x6b\xe5\x71\x2c\x03\x87\x05\x6f\xb0\xe7\x9f\x2c\x2f\x7f\x1c\x31\xe4\xa8\x6a",
+       188 },
+      { GCRY_MD_SHA3_256,
+       "\xc9\x53\x4a\x24\x71\x4b\xd4\xbe\x37\xc8\x8a\x3d\xa1\x08\x2e\xda\x7c\xab\xd1\x54\xc3\x09\xd7\xbd\x67\x0d\xcc\xd9\x5a\xa5\x35\x59\x44\x63\x05\x8a\x29\xf7\x90\x31\xd6\xec\xaa\x9f\x67\x5d\x12\x11\xe9\x35\x9b\xe8\x26\x69\xa7\x9c\x85\x5e\xa8\xd8\x9d\xd3\x8c\x2c\x76\x1d\xdd\x0e\xc0\xce\x9e\x97\x59\x74\x32\xe9\xa1\xbe\xae\x06\x2c\xdd\x71\xed\xfd\xfd\x46\x41\x19\xbe\x9e\x69\xd1\x8a\x7a\x7f\xd7\xce\x0e\x21\x06\xf0\xc8\xb0\xab\xf4\x71\x5e\x2c\xa4\x8e\xf9\xf4\x54\xdc\x20\x3c\x96\x65\x66\x53\xb7\x27\x08\x35\x13\xf8\xef\xb8\x6e\x49\xc5\x13\xbb\x75\x8b\x3b\x05\x2f\xe2\x1f\x1c\x05\xbb\x33\xc3\x71\x29\xd6\xcc\x81\xf1\xae\xf6\xad\xc4\x5b\x0e\x88\x27\xa8\x30\xfe\x54\x5c\xf5\x7d\x09\x55\x80\x2c\x11\x7d\x23\xcc\xb5\x5e\xa2\x8f\x95\xc0\xd8\xc2\xf9\xc5\xa2\x42\xb3\x3f",
+       "\xb7\x9b\x5f\x81\x82\xd3\xfb\x4a\xba\xb6\x3e\x7c\xb2\x6a\x8e\x08\x65\xae\x8d\x79\xbd\x4c\x51\x4a\xd8\x91\x7d\x5e\xcb\x7f\xed\x8f",
+       189 },
+      { GCRY_MD_SHA3_256,
+       "\x07\x90\x6c\x87\x29\x7b\x86\x7a\xbf\x45\x76\xe9\xf3\xcc\x7f\x82\xf2\x2b\x15\x4a\xfc\xbf\x29\x3b\x93\x19\xf1\xb0\x58\x4d\xa6\xa4\x0c\x27\xb3\x2e\x0b\x1b\x7f\x41\x2c\x4f\x1b\x82\x48\x0e\x70\xa9\x23\x5b\x12\xec\x27\x09\x0a\x5a\x33\x17\x5a\x2b\xb2\x8d\x8a\xdc\x47\x5c\xef\xe3\x3f\x78\x03\xf8\xce\x27\x96\x72\x17\x38\x1f\x02\xe6\x7a\x3b\x4f\x84\xa7\x1f\x1c\x52\x28\xe0\xc2\xad\x97\x13\x73\xf6\xf6\x72\x62\x4f\xce\xa8\xd1\xa9\xf8\x51\x70\xfa\xd3\x0f\xa0\xbb\xd2\x50\x35\xc3\xb4\x1a\x61\x75\xd4\x67\x99\x8b\xd1\x21\x5f\x6f\x38\x66\xf5\x38\x47\xf9\xcf\x68\xef\x3e\x2f\xbb\x54\xbc\x99\x4d\xe2\x30\x2b\x82\x9c\x5e\xea\x68\xec\x44\x1f\xcb\xaf\xd7\xd1\x6a\xe4\xfe\x9f\xff\x98\xbf\x00\xe5\xbc\x2a\xd5\x4d\xd9\x1f\xf9\xfd\xa4\xdd\x77\xb6\xc7\x54\xa9\x19\x55\xd1\xfb\xaa\xd0",
+       "\xf6\x80\x19\x8d\xe2\x94\x3d\x20\xe9\xd8\x09\xfd\x83\x12\xd6\x74\xc9\xa2\x50\xda\x22\xba\x6e\x92\x0e\x40\x8f\x6f\x2c\x0e\x07\x39",
+       190 },
+      { GCRY_MD_SHA3_256,
+       "\x58\x8e\x94\xb9\x05\x4a\xbc\x21\x89\xdf\x69\xb8\xba\x34\x34\x1b\x77\xcd\xd5\x28\xe7\x86\x0e\x5d\xef\xca\xa7\x9b\x0c\x9a\x45\x2a\xd4\xb8\x2a\xa3\x06\xbe\x84\x53\x6e\xb7\xce\xdc\xbe\x05\x8d\x7b\x84\xa6\xae\xf8\x26\xb0\x28\xb8\xa0\x27\x1b\x69\xac\x36\x05\xa9\x63\x5e\xa9\xf5\xea\x0a\xa7\x00\xf3\xeb\x78\x35\xbc\x54\x61\x1b\x92\x29\x64\x30\x0c\x95\x3e\xfe\x74\x91\xe3\x67\x7c\x2c\xeb\xe0\x82\x2e\x95\x6c\xd1\x64\x33\xb0\x2c\x68\xc4\xa2\x32\x52\xc3\xf9\xe1\x51\xa4\x16\xb4\x96\x32\x57\xb7\x83\xe0\x38\xf6\xb4\xd5\xc9\xf1\x10\xf8\x71\x65\x2c\x7a\x64\x9a\x7b\xce\xdc\xbc\xcc\x6f\x2d\x07\x25\xbb\x90\x3c\xc1\x96\xba\x76\xc7\x6a\xa9\xf1\x0a\x19\x0b\x1d\x11\x68\x99\x3b\xaa\x9f\xfc\x96\xa1\x65\x52\x16\x77\x34\x58\xbe\xc7\x2b\x0e\x39\xc9\xf2\xc1\x21\x37\x8f\xea\xb4\xe7\x6a",
+       "\xa1\x90\xdd\x73\x55\x60\x86\xea\x70\xbc\x31\x02\x2d\x6a\x4f\x95\xd8\x9d\xc0\x99\xe2\x03\x0c\x19\x31\x1c\xc8\x98\x82\x81\x27\x8f",
+       191 },
+      { GCRY_MD_SHA3_256,
+       "\x08\x95\x9a\x7e\x4b\xaa\xe8\x74\x92\x88\x13\x36\x40\x71\x19\x4e\x29\x39\x77\x2f\x20\xdb\x7c\x31\x57\x07\x89\x87\xc5\x57\xc2\xa6\xd5\xab\xe6\x8d\x52\x0e\xef\x3d\xc4\x91\x69\x2e\x1e\x21\xbc\xd8\x80\xad\xeb\xf6\x3b\xb4\x21\x3b\x50\x89\x7f\xa0\x05\x25\x6e\xd4\x1b\x56\x90\xf7\x8f\x52\x85\x5c\x8d\x91\x68\xa4\xb6\x66\xfc\xe2\xda\x2b\x45\x6d\x7a\x7e\x7c\x17\xab\x5f\x2f\xb1\xee\x90\xb7\x9e\x69\x87\x12\xe9\x63\x71\x59\x83\xfd\x07\x64\x1a\xe4\xb4\xe9\xdc\x73\x20\x3f\xac\x1a\xe1\x1f\xa1\xf8\xc7\x94\x1f\xcc\x82\xea\xb2\x47\xad\xdb\x56\xe2\x63\x84\x47\xe9\xd6\x09\xe6\x10\xb6\x0c\xe0\x86\x65\x6a\xae\xbf\x1d\xa3\xc8\xa2\x31\xd7\xd9\x4e\x2f\xd0\xaf\xe4\x6b\x39\x1f\xf1\x4a\x72\xea\xeb\x3f\x44\xad\x4d\xf8\x58\x66\xde\xf4\x3d\x47\x81\xa0\xb3\x57\x8b\xc9\x96\xc8\x79\x70\xb1\x32",
+       "\x21\x16\x60\x64\xc5\x2b\x58\x8c\x1e\xc7\xea\x6d\xf1\x90\x5a\x2b\x59\xba\xd4\x99\xb4\x70\xf3\x08\xa2\x6b\x6e\x35\x4d\xdf\xe5\x8f",
+       192 },
+      { GCRY_MD_SHA3_256,
+       "\xcb\x2a\x23\x4f\x45\xe2\xec\xd5\x86\x38\x95\xa4\x51\xd3\x89\xa3\x69\xaa\xb9\x9c\xfe\xf0\xd5\xc9\xff\xca\x1e\x6e\x63\xf7\x63\xb5\xc1\x4f\xb9\xb4\x78\x31\x3c\x8e\x8c\x0e\xfe\xb3\xac\x95\x00\xcf\x5f\xd9\x37\x91\xb7\x89\xe6\x7e\xac\x12\xfd\x03\x8e\x25\x47\xcc\x8e\x0f\xc9\xdb\x59\x1f\x33\xa1\xe4\x90\x7c\x64\xa9\x22\xdd\xa2\x3e\xc9\x82\x73\x10\xb3\x06\x09\x85\x54\xa4\xa7\x8f\x05\x02\x62\xdb\x5b\x54\x5b\x15\x9e\x1f\xf1\xdc\xa6\xeb\x73\x4b\x87\x23\x43\xb8\x42\xc5\x7e\xaf\xcf\xda\x84\x05\xee\xdb\xb4\x8e\xf3\x2e\x99\x69\x6d\x13\x59\x79\x23\x5c\x3a\x05\x36\x4e\x37\x1c\x2d\x76\xf1\x90\x2f\x1d\x83\x14\x6d\xf9\x49\x5c\x0a\x6c\x57\xd7\xbf\x9e\xe7\x7e\x80\xf9\x78\x7a\xee\x27\xbe\x1f\xe1\x26\xcd\xc9\xef\x89\x3a\x4a\x7d\xcb\xbc\x36\x7e\x40\xfe\x4e\x1e\xe9\x0b\x42\xea\x25\xaf\x01",
+       "\x05\x1e\x19\x90\x64\x64\xec\x7f\xdc\x3d\x37\xee\x3b\xce\xf6\x34\x38\xec\x5e\xdb\xea\x5a\xa2\x02\xa2\x4b\x7f\x71\x90\xb6\x89\xe0",
+       193 },
+      { GCRY_MD_SHA3_256,
+       "\xd1\x6b\xea\xdf\x02\xab\x1d\x4d\xc6\xf8\x8b\x8c\x45\x54\xc5\x1e\x86\x6d\xf8\x30\xb8\x9c\x06\xe7\x86\xa5\xf8\x75\x7e\x89\x09\x31\x0a\xf5\x1c\x84\x0e\xfe\x8d\x20\xb3\x53\x31\xf4\x35\x5d\x80\xf7\x32\x95\x97\x46\x53\xdd\xd6\x20\xcd\xde\x47\x30\xfb\x6c\x8d\x0d\x2d\xcb\x2b\x45\xd9\x2d\x4f\xbd\xb5\x67\xc0\xa3\xe8\x6b\xd1\xa8\xa7\x95\xaf\x26\xfb\xf2\x9f\xc6\xc6\x59\x41\xcd\xdb\x09\x0f\xf7\xcd\x23\x0a\xc5\x26\x8a\xb4\x60\x6f\xcc\xba\x9e\xde\xd0\xa2\xb5\xd0\x14\xee\x0c\x34\xf0\xb2\x88\x1a\xc0\x36\xe2\x4e\x15\x1b\xe8\x9e\xeb\x6c\xd9\xa7\xa7\x90\xaf\xcc\xff\x23\x4d\x7c\xb1\x1b\x99\xeb\xf5\x8c\xd0\xc5\x89\xf2\x0b\xda\xc4\xf9\xf0\xe2\x8f\x75\xe3\xe0\x4e\x5b\x3d\xeb\xce\x60\x7a\x49\x6d\x84\x8d\x67\xfa\x7b\x49\x13\x2c\x71\xb8\x78\xfd\x55\x57\xe0\x82\xa1\x8e\xca\x1f\xbd\xa9\x4d\x4b",
+       "\x18\xfe\x66\xc0\xcd\x09\x5c\x9c\xc8\x11\xf5\x41\x0b\x5c\xfd\xc1\xb1\x52\xae\x3c\xab\x0c\x33\x28\x97\x4e\x7d\x4b\xbe\xb4\x00\x53",
+       194 },
+      { GCRY_MD_SHA3_256,
+       "\x8f\x65\xf6\xbc\x59\xa8\x57\x05\x01\x6e\x2b\xae\x7f\xe5\x79\x80\xde\x31\x27\xe5\xab\x27\x5f\x57\x3d\x33\x4f\x73\xf8\x60\x31\x06\xec\x35\x53\x01\x66\x08\xef\x2d\xd6\xe6\x9b\x24\xbe\x0b\x71\x13\xbf\x6a\x76\x0b\xa6\xe9\xce\x1c\x48\xf9\xe1\x86\x01\x2c\xf9\x6a\x1d\x48\x49\xd7\x5d\xf5\xbb\x83\x15\x38\x7f\xd7\x8e\x9e\x15\x3e\x76\xf8\xba\x7e\xc6\xc8\x84\x98\x10\xf5\x9f\xb4\xbb\x9b\x00\x43\x18\x21\x0b\x37\xf1\x29\x95\x26\x86\x6f\x44\x05\x9e\x01\x7e\x22\xe9\x6c\xbe\x41\x86\x99\xd0\x14\xc6\xea\x01\xc9\xf0\x03\x8b\x10\x29\x98\x84\xdb\xec\x31\x99\xbb\x05\xad\xc9\x4e\x95\x5a\x15\x33\x21\x9c\x11\x15\xfe\xd0\xe5\xf2\x12\x28\xb0\x71\xf4\x0d\xd5\x7c\x42\x40\xd9\x8d\x37\xb7\x3e\x41\x2f\xe0\xfa\x47\x03\x12\x0d\x7c\x0c\x67\x97\x2e\xd2\x33\xe5\xde\xb3\x00\xa2\x26\x05\x47\x2f\xa3\xa3\xba\x86",
+       "\xbd\xb4\x26\x38\x92\x11\x99\xd6\x04\x29\x4b\x55\x78\xce\xba\xcc\xdf\x13\x2e\x1d\x7a\xf7\x67\x5b\x77\x68\xe5\x05\x53\xfc\xb6\x04",
+       195 },
+      { GCRY_MD_SHA3_256,
+       "\x84\x89\x1e\x52\xe0\xd4\x51\x81\x32\x10\xc3\xfd\x63\x5b\x39\xa0\x3a\x6b\x7a\x73\x17\xb2\x21\xa7\xab\xc2\x70\xdf\xa9\x46\xc4\x26\x69\xaa\xcb\xbb\xdf\x80\x1e\x15\x84\xf3\x30\xe2\x8c\x72\x98\x47\xea\x14\x15\x2b\xd6\x37\xb3\xd0\xf2\xb3\x8b\x4b\xd5\xbf\x9c\x79\x1c\x58\x80\x62\x81\x10\x3a\x3e\xab\xba\xed\xe5\xe7\x11\xe5\x39\xe6\xa8\xb2\xcf\x29\x7c\xf3\x51\xc0\x78\xb4\xfa\x8f\x7f\x35\xcf\x61\xbe\xbf\x88\x14\xbf\x24\x8a\x01\xd4\x1e\x86\xc5\x71\x5e\xa4\x0c\x63\xf7\x37\x53\x79\xa7\xeb\x1d\x78\xf2\x76\x22\xfb\x46\x8a\xb7\x84\xaa\xab\xa4\xe5\x34\xa6\xdf\xd1\xdf\x6f\xa1\x55\x11\x34\x1e\x72\x5e\xd2\xe8\x7f\x98\x73\x7c\xcb\x7b\x6a\x6d\xfa\xe4\x16\x47\x74\x72\xb0\x46\xbf\x18\x11\x18\x7d\x15\x1b\xfa\x9f\x7b\x2b\xf9\xac\xdb\x23\xa3\xbe\x50\x7c\xdf\x14\xcf\xdf\x51\x7d\x2c\xb5\xfb\x9e\x4a\xb6",
+       "\xcb\xd8\x82\x09\xb5\x30\x01\x8a\x85\x6c\x5c\x23\x21\xd7\xe4\x85\x51\x1c\xa1\x51\x36\x61\xf1\xfd\xe1\xfa\x06\xf4\x60\x3d\xe1\x17",
+       196 },
+      { GCRY_MD_SHA3_256,
+       "\xfd\xd7\xa9\x43\x3a\x3b\x4a\xfa\xbd\x7a\x3a\x5e\x34\x57\xe5\x6d\xeb\xf7\x8e\x84\xb7\xa0\xb0\xca\x0e\x8c\x6d\x53\xbd\x0c\x2d\xae\x31\xb2\x70\x0c\x61\x28\x33\x4f\x43\x98\x1b\xe3\xb2\x13\xb1\xd7\xa1\x18\xd5\x9c\x7e\x6b\x64\x93\xa8\x6f\x86\x6a\x16\x35\xc1\x28\x59\xcf\xb9\xad\x17\x46\x0a\x77\xb4\x52\x2a\x5c\x18\x83\xc3\xd6\xac\xc8\x6e\x61\x62\x66\x7e\xc4\x14\xe9\xa1\x04\xaa\x89\x20\x53\xa2\xb1\xd7\x21\x65\xa8\x55\xba\xcd\x8f\xaf\x80\x34\xa5\xdd\x9b\x71\x6f\x47\xa0\x81\x8c\x09\xbb\x6b\xaf\x22\xaa\x50\x3c\x06\xb4\xca\x26\x1f\x55\x77\x61\x98\x9d\x2a\xfb\xd8\x8b\x6a\x67\x8a\xd1\x28\xaf\x68\x67\x21\x07\xd0\xf1\xfc\x73\xc5\xca\x74\x04\x59\x29\x7b\x32\x92\xb2\x81\xe9\x3b\xce\xb7\x61\xbd\xe7\x22\x1c\x3a\x55\x70\x8e\x5e\xc8\x44\x72\xcd\xdc\xaa\x84\xec\xf2\x37\x23\xcc\x09\x91\x35\x5c\x62\x80",
+       "\xf0\xc4\xc1\x37\x4f\x33\xa9\x1d\xc6\x57\xf8\xa3\xfa\x51\x76\x3c\xbd\x0f\xba\x1c\xaf\xdd\x2c\x59\x5e\xd3\x02\xaa\xb1\xab\x75\xa9",
+       197 },
+      { GCRY_MD_SHA3_256,
+       "\x70\xa4\x0b\xfb\xef\x92\x27\x7a\x1a\xad\x72\xf6\xb7\x9d\x01\x77\x19\x7c\x4e\xbd\x43\x26\x68\xcf\xec\x05\xd0\x99\xac\xcb\x65\x10\x62\xb5\xdf\xf1\x56\xc0\xb2\x73\x36\x68\x7a\x94\xb2\x66\x79\xcf\xdd\x9d\xaf\x7a\xd2\x04\x33\x8d\xd9\xc4\xd1\x41\x14\x03\x3a\x5c\x22\x5b\xd1\x1f\x21\x7b\x5f\x47\x32\xda\x16\x7e\xe3\xf9\x39\x26\x2d\x40\x43\xfc\x9c\xba\x92\x30\x3b\x7b\x5e\x96\xae\xa1\x2a\xdd\xa6\x48\x59\xdf\x4b\x86\xe9\xee\x0b\x58\xe3\x90\x91\xe6\xb1\x88\xb4\x08\xac\x94\xe1\x29\x4a\x89\x11\x24\x5e\xe3\x61\xe6\x0e\x60\x1e\xff\x58\xd1\xd3\x76\x39\xf3\x75\x3b\xec\x80\xeb\xb4\xef\xde\x25\x81\x74\x36\x07\x66\x23\xfc\x65\x41\x5f\xe5\x1d\x1b\x02\x80\x36\x6d\x12\xc5\x54\xd8\x67\x43\xf3\xc3\xb6\x57\x2e\x40\x03\x61\xa6\x07\x26\x13\x14\x41\xba\x49\x3a\x83\xfb\xe9\xaf\xda\x90\xf7\xaf\x1a\xe7\x17\x23\x8d",
+       "\xf2\x15\x7c\x16\x5e\xeb\xdf\xd0\x44\x51\xe9\xe6\xcf\x0b\x11\x2b\xb1\x48\xeb\x9c\x40\xe8\xb2\x42\x7e\xe8\xea\x57\xe6\x0d\x5d\xd6",
+       198 },
+      { GCRY_MD_SHA3_256,
+       "\x74\x35\x6e\x44\x9f\x4b\xf8\x64\x4f\x77\xb1\x4f\x4d\x67\xcb\x6b\xd9\xc1\xf5\xae\x35\x76\x21\xd5\xb8\x14\x7e\x56\x2b\x65\xc6\x65\x85\xca\xf2\xe4\x91\xb4\x85\x29\xa0\x1a\x34\xd2\x26\xd4\x36\x95\x91\x53\x81\x53\x80\xd5\x68\x9e\x30\xb3\x53\x57\xcd\xac\x6e\x08\xd3\xf2\xb0\xe8\x8e\x20\x06\x00\xd6\x2b\xd9\xf5\xea\xf4\x88\xdf\x86\xa4\x47\x0e\xa2\x27\x00\x61\x82\xe4\x48\x09\x00\x98\x68\xc4\xc2\x80\xc4\x3d\x7d\x64\xa5\x26\x8f\xa7\x19\x07\x49\x60\x08\x7b\x3a\x6a\xbc\x83\x78\x82\xf8\x82\xc8\x37\x83\x45\x35\x92\x93\x89\xa1\x2b\x2c\x78\x18\x7e\x2e\xa0\x7e\xf8\xb8\xee\xf2\x7d\xc8\x50\x02\xc3\xae\x35\xf1\xa5\x0b\xee\x6a\x1c\x48\xba\x7e\x17\x5f\x33\x16\x67\x0b\x27\x98\x34\x72\xaa\x6a\x61\xee\xd0\xa6\x83\xa3\x9e\xe3\x23\x08\x06\x20\xea\x44\xa9\xf7\x44\x11\xae\x5c\xe9\x90\x30\x52\x8f\x9a\xb4\x9c\x79\xf2",
+       "\x08\x36\xab\xbf\x77\xef\x78\xe1\x62\xde\x8f\xb6\x64\xb9\x99\x6d\x5a\x03\x91\x9b\x74\x1e\xb4\xa3\xf0\x2e\x7b\x97\x82\x65\x69\xfa",
+       199 },
+      { GCRY_MD_SHA3_256,
+       "\x8c\x37\x98\xe5\x1b\xc6\x84\x82\xd7\x33\x7d\x3a\xbb\x75\xdc\x9f\xfe\x86\x07\x14\xa9\xad\x73\x55\x1e\x12\x00\x59\x86\x0d\xde\x24\xab\x87\x32\x72\x22\xb6\x4c\xf7\x74\x41\x5a\x70\xf7\x24\xcd\xf2\x70\xde\x3f\xe4\x7d\xda\x07\xb6\x1c\x9e\xf2\xa3\x55\x1f\x45\xa5\x58\x48\x60\x24\x8f\xab\xde\x67\x6e\x1c\xd7\x5f\x63\x55\xaa\x3e\xae\xab\xe3\xb5\x1d\xc8\x13\xd9\xfb\x2e\xaa\x4f\x0f\x1d\x9f\x83\x4d\x7c\xad\x9c\x7c\x69\x5a\xe8\x4b\x32\x93\x85\xbc\x0b\xef\x89\x5b\x9f\x1e\xdf\x44\xa0\x3d\x4b\x41\x0c\xc2\x3a\x79\xa6\xb6\x2e\x4f\x34\x6a\x5e\x8d\xd8\x51\xc2\x85\x79\x95\xdd\xbf\x5b\x2d\x71\x7a\xeb\x84\x73\x10\xe1\xf6\xa4\x6a\xc3\xd2\x6a\x7f\x9b\x44\x98\x5a\xf6\x56\xd2\xb7\xc9\x40\x6e\x8a\x9e\x8f\x47\xdc\xb4\xef\x6b\x83\xca\xac\xf9\xae\xfb\x61\x18\xbf\xcf\xf7\xe4\x4b\xef\x69\x37\xeb\xdd\xc8\x91\x86\x83\x9b\x77",
+       "\x84\x97\x0c\x79\x31\x6e\x89\xb7\x0e\x2b\x18\x6a\x69\xdb\x1a\x4c\x3e\x33\xc7\xa3\x76\xb4\x5c\x1b\x79\xbd\x34\x6d\xd3\x3e\xf4\xce",
+       200 },
+      { GCRY_MD_SHA3_256,
+       "\xfa\x56\xbf\x73\x0c\x4f\x83\x95\x87\x51\x89\xc1\x0c\x4f\xb2\x51\x60\x57\x57\xa8\xfe\xcc\x31\xf9\x73\x7e\x3c\x25\x03\xb0\x26\x08\xe6\x73\x1e\x85\xd7\xa3\x83\x93\xc6\x7d\xe5\x16\xb8\x53\x04\x82\x4b\xfb\x13\x5e\x33\xbf\x22\xb3\xa2\x3b\x91\x3b\xf6\xac\xd2\xb7\xab\x85\x19\x8b\x81\x87\xb2\xbc\xd4\x54\xd5\xe3\x31\x8c\xac\xb3\x2f\xd6\x26\x1c\x31\xae\x7f\x6c\x54\xef\x6a\x7a\x2a\x4c\x9f\x3e\xcb\x81\xce\x35\x55\xd4\xf0\xad\x46\x6d\xd4\xc1\x08\xa9\x03\x99\xd7\x00\x41\x99\x7c\x3b\x25\x34\x5a\x96\x53\xf3\xc9\xa6\x71\x1a\xb1\xb9\x1d\x6a\x9d\x22\x16\x44\x2d\xa2\xc9\x73\xcb\xd6\x85\xee\x76\x43\xbf\xd7\x73\x27\xa2\xf7\xae\x9c\xb2\x83\x62\x0a\x08\x71\x6d\xfb\x46\x2e\x5c\x1d\x65\x43\x2c\xa9\xd5\x6a\x90\xe8\x11\x44\x3c\xd1\xec\xb8\xf0\xde\x17\x9c\x9c\xb4\x8b\xa4\xf6\xfe\xc3\x60\xc6\x6f\x25\x2f\x6e\x64\xed\xc9\x6b",
+       "\x06\xed\x2e\xbc\x41\x9d\x05\x39\x49\xe8\x8c\xc9\xc0\x40\xb1\xeb\xce\x74\x37\x5a\xd0\xce\x09\xc0\xcd\x4d\x56\x2c\x62\xf8\x49\x7d",
+       201 },
+      { GCRY_MD_SHA3_256,
+       "\xb6\x13\x4f\x9c\x3e\x91\xdd\x80\x00\x74\x0d\x00\x9d\xd8\x06\x24\x08\x11\xd5\x1a\xb1\x54\x6a\x97\x4b\xcb\x18\xd3\x44\x64\x2b\xaa\x5c\xd5\x90\x3a\xf8\x4d\x58\xec\x5b\xa1\x73\x01\xd5\xec\x0f\x10\xcc\xd0\x50\x9c\xbb\x3f\xd3\xff\xf9\x17\x2d\x19\x3a\xf0\xf7\x82\x25\x2f\xd1\x33\x8c\x72\x44\xd4\x0e\x0e\x42\x36\x22\x75\xb2\x2d\x01\xc4\xc3\x38\x9f\x19\xdd\x69\xbd\xf9\x58\xeb\xe2\x8e\x31\xa4\xff\xe2\xb5\xf1\x8a\x87\x83\x1c\xfb\x70\x95\xf5\x8a\x87\xc9\xfa\x21\xdb\x72\xba\x26\x93\x79\xb2\xdc\x23\x84\xb3\xda\x95\x3c\x79\x25\x76\x1f\xed\x32\x46\x20\xac\xea\x43\x5e\x52\xb4\x24\xa7\x72\x3f\x6a\x23\x57\x37\x41\x57\xa3\x4c\xd8\x25\x23\x51\xc2\x5a\x1b\x23\x28\x26\xce\xfe\x1b\xd3\xe7\x0f\xfc\x15\xa3\x1e\x7c\x05\x98\x21\x9d\x7f\x00\x43\x62\x94\xd1\x18\x91\xb8\x24\x97\xbc\x78\xaa\x53\x63\x89\x2a\x24\x95\xdf\x8c\x1e\xef",
+       "\xcf\x90\x60\xaf\x3e\x4e\xd4\x73\x16\xac\xf5\x1e\x5b\x92\x12\x3c\xdc\x48\x27\xbd\x4a\xef\x99\x15\x88\xdc\xd8\x07\x8b\x9e\xea\x40",
+       202 },
+      { GCRY_MD_SHA3_256,
+       "\xc9\x41\xcd\xb9\xc2\x8a\xb0\xa7\x91\xf2\xe5\xc8\xe8\xbb\x52\x85\x06\x26\xaa\x89\x20\x5b\xec\x3a\x7e\x22\x68\x23\x13\xd1\x98\xb1\xfa\x33\xfc\x72\x95\x38\x13\x54\x85\x87\x58\xae\x6c\x8e\xc6\xfa\xc3\x24\x5c\x6e\x45\x4d\x16\xfa\x2f\x51\xc4\x16\x6f\xab\x51\xdf\x27\x28\x58\xf2\xd6\x03\x77\x0c\x40\x98\x7f\x64\x44\x2d\x48\x7a\xf4\x9c\xd5\xc3\x99\x1c\xe8\x58\xea\x2a\x60\xda\xb6\xa6\x5a\x34\x41\x49\x65\x93\x39\x73\xac\x24\x57\x08\x9e\x35\x91\x60\xb7\xcd\xed\xc4\x2f\x29\xe1\x0a\x91\x92\x17\x85\xf6\xb7\x22\x4e\xe0\xb3\x49\x39\x3c\xdc\xff\x61\x51\xb5\x0b\x37\x7d\x60\x95\x59\x92\x3d\x09\x84\xcd\xa6\x00\x08\x29\xb9\x16\xab\x68\x96\x69\x3e\xf6\xa2\x19\x9b\x3c\x22\xf7\xdc\x55\x00\xa1\x5b\x82\x58\x42\x0e\x31\x4c\x22\x2b\xc0\x00\xbc\x4e\x54\x13\xe6\xdd\x82\xc9\x93\xf8\x33\x0f\x5c\x6d\x1b\xe4\xbc\x79\xf0\x8a\x1a\x0a\x46",
+       "\x63\xe4\x07\x30\x0f\x99\xff\x23\x60\xf0\x2a\xae\x0a\xda\x35\xf6\xc1\xa9\x0a\xed\x2c\x63\x28\x2b\x23\xa7\x99\x0b\xae\x30\x72\x54",
+       203 },
+      { GCRY_MD_SHA3_256,
+       "\x44\x99\xef\xff\xac\x4b\xce\xa5\x27\x47\xef\xd1\xe4\xf2\x0b\x73\xe4\x87\x58\xbe\x91\x5c\x88\xa1\xff\xe5\x29\x9b\x0b\x00\x58\x37\xa4\x6b\x2f\x20\xa9\xcb\x3c\x6e\x64\xa9\xe3\xc5\x64\xa2\x7c\x0f\x1c\x6a\xd1\x96\x03\x73\x03\x6e\xc5\xbf\xe1\xa8\xfc\x6a\x43\x5c\x21\x85\xed\x0f\x11\x4c\x50\xe8\xb3\xe4\xc7\xed\x96\xb0\x6a\x03\x68\x19\xc9\x46\x3e\x86\x4a\x58\xd6\x28\x6f\x78\x5e\x32\xa8\x04\x44\x3a\x56\xaf\x0b\x4d\xf6\xab\xc5\x7e\xd5\xc2\xb1\x85\xdd\xee\x84\x89\xea\x08\x0d\xee\xee\x66\xaa\x33\xc2\xe6\xda\xb3\x62\x51\xc4\x02\x68\x2b\x68\x24\x82\x1f\x99\x8c\x32\x16\x31\x64\x29\x8e\x1f\xaf\xd3\x1b\xab\xbc\xff\xb5\x94\xc9\x18\x88\xc6\x21\x90\x79\xd9\x07\xfd\xb4\x38\xed\x89\x52\x9d\x6d\x96\x21\x2f\xd5\x5a\xbe\x20\x39\x9d\xbe\xfd\x34\x22\x48\x50\x74\x36\x93\x1c\xde\xad\x49\x6e\xb6\xe4\xa8\x03\x58\xac\xc7\x86\x47\xd0\x43",
+       "\x42\x77\x41\x57\x0d\x5e\x21\x59\x0e\x50\x45\xa8\x45\x02\x16\x36\x5b\xa9\x5c\x2e\x72\x45\x5a\x3d\xbd\x69\x4f\x13\x15\x5d\xe1\xb7",
+       204 },
+      { GCRY_MD_SHA3_256,
+       "\xee\xcb\xb8\xfd\xfa\x4d\xa6\x21\x70\xfd\x06\x72\x7f\x69\x7d\x81\xf8\x3f\x60\x1f\xf6\x1e\x47\x81\x05\xd3\xcb\x75\x02\xf2\xc8\x9b\xf3\xe8\xf5\x6e\xdd\x46\x9d\x04\x98\x07\xa3\x88\x82\xa7\xee\xfb\xc8\x5f\xc9\xa9\x50\x95\x2e\x9f\xa8\x4b\x8a\xfe\xbd\x3c\xe7\x82\xd4\xda\x59\x80\x02\x82\x7b\x1e\xb9\x88\x82\xea\x1f\x0a\x8f\x7a\xa9\xce\x01\x3a\x6e\x9b\xc4\x62\xfb\x66\xc8\xd4\xa1\x8d\xa2\x14\x01\xe1\xb9\x33\x56\xeb\x12\xf3\x72\x5b\x6d\xb1\x68\x4f\x23\x00\xa9\x8b\x9a\x11\x9e\x5d\x27\xff\x70\x4a\xff\xb6\x18\xe1\x27\x08\xe7\x7e\x6e\x5f\x34\x13\x9a\x5a\x41\x13\x1f\xd1\xd6\x33\x6c\x27\x2a\x8f\xc3\x70\x80\xf0\x41\xc7\x13\x41\xbe\xe6\xab\x55\x0c\xb4\xa2\x0a\x6d\xdb\x6a\x8e\x02\x99\xf2\xb1\x4b\xc7\x30\xc5\x4b\x8b\x1c\x1c\x48\x7b\x49\x4b\xdc\xcf\xd3\xa5\x35\x35\xab\x2f\x23\x15\x90\xbf\x2c\x40\x62\xfd\x2a\xd5\x8f\x90\x6a\x2d\x0d",
+       "\xb5\xe6\x0a\x01\x9e\x84\x14\xd4\x70\xae\x70\x27\x38\xbc\x35\x8f\x1c\x80\xbb\x6f\xf7\xbd\xe4\xf2\xdb\xb5\x6c\x29\x9c\x76\x4b\x16",
+       205 },
+      { GCRY_MD_SHA3_256,
+       "\xe6\x4f\x3e\x4a\xce\x5c\x84\x18\xd6\x5f\xec\x2b\xc5\xd2\xa3\x03\xdd\x45\x80\x34\x73\x6e\x3b\x0d\xf7\x19\x09\x8b\xe7\xa2\x06\xde\xaf\x52\xd6\xba\x82\x31\x6c\xaf\x33\x0e\xf8\x52\x37\x51\x88\xcd\xe2\xb3\x9c\xc9\x4a\xa4\x49\x57\x8a\x7e\x2a\x8e\x3f\x5a\x9d\x68\xe8\x16\xb8\xd1\x68\x89\xfb\xc0\xeb\xf0\x93\x9d\x04\xf6\x30\x33\xae\x9a\xe2\xbd\xab\x73\xb8\x8c\x26\xd6\xbd\x25\xee\x46\x0e\xe1\xef\x58\xfb\x0a\xfa\x92\xcc\x53\x9f\x8c\x76\xd3\xd0\x97\xe7\xa6\xa6\x3e\xbb\x9b\x58\x87\xed\xf3\xcf\x07\x60\x28\xc5\xbb\xd5\xb9\xdb\x32\x11\x37\x1a\xd3\xfe\x12\x1d\x4e\x9b\xf4\x42\x29\xf4\xe1\xec\xf5\xa0\xf9\xf0\xeb\xa4\xd5\xce\xb7\x28\x78\xab\x22\xc3\xf0\xeb\x5a\x62\x53\x23\xac\x66\xf7\x06\x1f\x4a\x81\xfa\xc8\x34\x47\x1e\x0c\x59\x55\x3f\x10\x84\x75\xfe\x29\x0d\x43\xe6\xa0\x55\xae\x3e\xe4\x6f\xb6\x74\x22\xf8\x14\xa6\x8c\x4b\xe3\xe8\xc9",
+       "\xc9\x86\xbd\xae\x9b\x13\xfb\xc9\x27\x93\x61\x9e\x49\x70\xab\xc3\x33\x98\xf2\xb5\xa5\x7a\x6c\xbb\x40\xa6\x22\x59\x2e\x26\x95\xdf",
+       206 },
+      { GCRY_MD_SHA3_256,
+       "\xd2\xcb\x2d\x73\x30\x33\xf9\xe9\x13\x95\x31\x28\x08\x38\x3c\xc4\xf0\xca\x97\x4e\x87\xec\x68\x40\x0d\x52\xe9\x6b\x3f\xa6\x98\x4a\xc5\x8d\x9a\xd0\x93\x8d\xde\x5a\x97\x30\x08\xd8\x18\xc4\x96\x07\xd9\xde\x22\x84\xe7\x61\x8f\x1b\x8a\xed\x83\x72\xfb\xd5\x2e\xd5\x45\x57\xaf\x42\x20\xfa\xc0\x9d\xfa\x84\x43\x01\x16\x99\xb9\x7d\x74\x3f\x8f\x2b\x1a\xef\x35\x37\xeb\xb4\x5d\xcc\x9e\x13\xdf\xb4\x38\x42\x8e\xe1\x90\xa4\xef\xdb\x3c\xae\xb7\xf3\x93\x31\x17\xbf\x63\xab\xdc\x7e\x57\xbe\xb4\x17\x1c\x7e\x1a\xd2\x60\xab\x05\x87\x80\x6c\x4d\x13\x7b\x63\x16\xb5\x0a\xbc\x9c\xce\x0d\xff\x3a\xca\xda\x47\xbb\xb8\x6b\xe7\x77\xe6\x17\xbb\xe5\x78\xff\x45\x19\x84\x4d\xb3\x60\xe0\xa9\x6c\x67\x01\x29\x0e\x76\xbb\x95\xd2\x6f\x0f\x80\x4c\x8a\x4f\x27\x17\xea\xc4\xe7\xde\x9f\x2c\xff\x3b\xbc\x55\xa1\x7e\x77\x6c\x0d\x02\x85\x60\x32\xa6\xcd\x10\xad\x28\x38",
+       "\x22\x4c\x7f\xc8\xa0\xec\x38\x95\xe8\x96\x9c\xe7\xc7\xf7\xec\xaa\x54\xfe\x2e\xec\x9a\xb3\x12\x07\x26\x10\x6f\x22\xaa\x29\x75\x41",
+       207 },
+      { GCRY_MD_SHA3_256,
+       "\xf2\x99\x89\x55\x61\x3d\xd4\x14\xcc\x11\x1d\xf5\xce\x30\xa9\x95\xbb\x79\x2e\x26\x0b\x0e\x37\xa5\xb1\xd9\x42\xfe\x90\x17\x1a\x4a\xc2\xf6\x6d\x49\x28\xd7\xad\x37\x7f\x4d\x05\x54\xcb\xf4\xc5\x23\xd2\x1f\x6e\x5f\x37\x9d\x6f\x4b\x02\x8c\xdc\xb9\xb1\x75\x8d\x3b\x39\x66\x32\x42\xff\x3c\xb6\xed\xe6\xa3\x6a\x6f\x05\xdb\x3b\xc4\x1e\x0d\x86\x1b\x38\x4b\x6d\xec\x58\xbb\x09\x6d\x0a\x42\x2f\xd5\x42\xdf\x17\x5e\x1b\xe1\x57\x1f\xb5\x2a\xe6\x6f\x2d\x86\xa2\xf6\x82\x4a\x8c\xfa\xac\xba\xc4\xa7\x49\x2a\xd0\x43\x3e\xeb\x15\x45\x4a\xf8\xf3\x12\xb3\xb2\xa5\x77\x75\x0e\x3e\xfb\xd3\x70\xe8\xa8\xca\xc1\x58\x25\x81\x97\x1f\xba\x3b\xa4\xbd\x0d\x76\xe7\x18\xda\xcf\x84\x33\xd3\x3a\x59\xd2\x87\xf8\xcc\x92\x23\x4e\x7a\x27\x10\x41\xb5\x26\xe3\x89\xef\xb0\xe4\x0b\x6a\x18\xb3\xaa\xf6\x58\xe8\x2e\xd1\xc7\x86\x31\xfd\x23\xb4\xc3\xeb\x27\xc3\xfa\xec\x86\x85",
+       "\xfa\xf5\xe3\xb7\xa6\x46\x29\xff\xee\xe0\x7a\x67\xed\x77\xa3\xa4\xf6\x7f\x18\xc9\x38\x1f\xe9\xb1\x9f\x6e\xe6\x01\xf5\xfb\x99\xaf",
+       208 },
+      { GCRY_MD_SHA3_256,
+       "\x44\x77\x97\xe2\x89\x9b\x72\xa3\x56\xba\x55\xbf\x4d\xf3\xac\xca\x6c\xdb\x10\x41\xeb\x47\x7b\xd1\x83\x4a\x9f\x9a\xcb\xc3\x40\xa2\x94\xd7\x29\xf2\xf9\x7d\xf3\xa6\x10\xbe\x0f\xf1\x5e\xdb\x9c\x6d\x5d\xb4\x16\x44\xb9\x87\x43\x60\x14\x0f\xc6\x4f\x52\xaa\x03\xf0\x28\x6c\x8a\x64\x06\x70\x06\x7a\x84\xe0\x17\x92\x6a\x70\x43\x8d\xb1\xbb\x36\x1d\xef\xee\x73\x17\x02\x14\x25\xf8\x82\x1d\xef\x26\xd1\xef\xd7\x7f\xc8\x53\xb8\x18\x54\x5d\x05\x5a\xdc\x92\x84\x79\x6e\x58\x3c\x76\xe6\xfe\x74\xc9\xac\x25\x87\xaa\x46\xaa\x8f\x88\x04\xf2\xfe\xb5\x83\x6c\xc4\xb3\xab\xab\xab\x84\x29\xa5\x78\x3e\x17\xd5\x99\x9f\x32\x24\x2e\xb5\x9e\xf3\x0c\xd7\xad\xab\xc1\x6d\x72\xdb\xdb\x09\x76\x23\x04\x7c\x98\x98\x9f\x88\xd1\x4e\xaf\x02\xa7\x21\x2b\xe1\x6e\xc2\xd0\x79\x81\xaa\xa9\x99\x49\xdd\xf8\x9e\xcd\x90\x33\x3a\x77\xbc\x4e\x19\x88\xa8\x2a\xbf\x7c\x7c\xaf\x32\x91",
+       "\xa8\xa9\x8e\x6b\x3a\x00\x5f\xcb\x31\x9f\xee\x58\xc5\x45\x7d\x04\xb6\x9d\x59\xf5\x38\x73\xf6\xfc\xc6\x06\x5d\x68\xf8\x80\x83\x3f",
+       209 },
+      { GCRY_MD_SHA3_256,
+       "\x9f\x2c\x18\xad\xe9\xb3\x80\xc7\x84\xe1\x70\xfb\x76\x3e\x9a\xa2\x05\xf6\x43\x03\x06\x7e\xb1\xbc\xea\x93\xdf\x5d\xac\x4b\xf5\xa2\xe0\x0b\x78\x19\x5f\x80\x8d\xf2\x4f\xc7\x6e\x26\xcb\x7b\xe3\x1d\xc3\x5f\x08\x44\xcd\xed\x15\x67\xbb\xa2\x98\x58\xcf\xfc\x97\xfb\x29\x01\x03\x31\xb0\x1d\x6a\x3f\xb3\x15\x9c\xc1\xb9\x73\xd2\x55\xda\x98\x43\xe3\x4a\x0a\x40\x61\xca\xbd\xb9\xed\x37\xf2\x41\xbf\xab\xb3\xc2\x0d\x32\x74\x3f\x40\x26\xb5\x9a\x4c\xcc\x38\x5a\x23\x01\xf8\x3c\x0b\x0a\x19\x0b\x0f\x2d\x01\xac\xb8\xf0\xd4\x11\x11\xe1\x0f\x2f\x4e\x14\x93\x79\x27\x55\x99\xa5\x2d\xc0\x89\xb3\x5f\xdd\x52\x34\xb0\xcf\xb7\xb6\xd8\xae\xbd\x56\x3c\xa1\xfa\x65\x3c\x5c\x02\x1d\xfd\x6f\x59\x20\xe6\xf1\x8b\xfa\xfd\xbe\xcb\xf0\xab\x00\x28\x13\x33\xed\x50\xb9\xa9\x99\x54\x9c\x1c\x8f\x8c\x63\xd7\x62\x6c\x48\x32\x2e\x97\x91\xd5\xff\x72\x29\x40\x49\xbd\xe9\x1e\x73\xf8",
+       "\xc8\x9f\x2b\x34\x61\x27\xea\xb9\xe2\x80\x95\xdc\x44\x91\x8c\x1a\x1a\xae\xae\x04\x86\x1c\x1d\xd0\x14\x4a\x1e\xe0\x7f\x82\x3c\x18",
+       210 },
+      { GCRY_MD_SHA3_256,
+       "\xae\x15\x9f\x3f\xa3\x36\x19\x00\x2a\xe6\xbc\xce\x8c\xbb\xdd\x7d\x28\xe5\xed\x9d\x61\x53\x45\x95\xc4\xc9\xf4\x3c\x40\x2a\x9b\xb3\x1f\x3b\x30\x1c\xbf\xd4\xa4\x3c\xe4\xc2\x4c\xd5\xc9\x84\x9c\xc6\x25\x9e\xca\x90\xe2\xa7\x9e\x01\xff\xba\xc0\x7b\xa0\xe1\x47\xfa\x42\x67\x6a\x1d\x66\x85\x70\xe0\x39\x63\x87\xb5\xbc\xd5\x99\xe8\xe6\x6a\xae\xd1\xb8\xa1\x91\xc5\xa4\x75\x47\xf6\x13\x73\x02\x1f\xa6\xde\xad\xcb\x55\x36\x3d\x23\x3c\x24\x44\x0f\x2c\x73\xdb\xb5\x19\xf7\xc9\xfa\x5a\x89\x62\xef\xd5\xf6\x25\x2c\x04\x07\xf1\x90\xdf\xef\xad\x70\x7f\x3c\x70\x07\xd6\x9f\xf3\x6b\x84\x89\xa5\xb6\xb7\xc5\x57\xe7\x9d\xd4\xf5\x0c\x06\x51\x1f\x59\x9f\x56\xc8\x96\xb3\x5c\x91\x7b\x63\xba\x35\xc6\xff\x80\x92\xba\xf7\xd1\x65\x8e\x77\xfc\x95\xd8\xa6\xa4\x3e\xeb\x4c\x01\xf3\x3f\x03\x87\x7f\x92\x77\x4b\xe8\x9c\x11\x14\xdd\x53\x1c\x01\x1e\x53\xa3\x4d\xc2\x48\xa2\xf0\xe6",
+       "\xe7\xa8\x1a\xcb\xef\x35\xd7\xb2\x4b\x70\x65\x49\xb4\x1a\xbd\x82\x62\x8c\xcf\xf9\xac\xf4\x1f\x2c\x8a\xdd\x28\x74\x36\x88\xae\x01",
+       211 },
+      { GCRY_MD_SHA3_256,
+       "\x3b\x8e\x97\xc5\xff\xc2\xd6\xa4\x0f\xa7\xde\x7f\xce\xfc\x90\xf3\xb1\x2c\x94\x0e\x7a\xb4\x15\x32\x1e\x29\xee\x69\x2d\xfa\xc7\x99\xb0\x09\xc9\x9d\xcd\xdb\x70\x8f\xce\x5a\x17\x8c\x5c\x35\xee\x2b\x86\x17\x14\x3e\xdc\x4c\x40\xb4\xd3\x13\x66\x1f\x49\xab\xdd\x93\xce\xa7\x9d\x11\x75\x18\x80\x54\x96\xfe\x6a\xcf\x29\x2c\x4c\x2a\x1f\x76\xb4\x03\xa9\x7d\x7c\x39\x9d\xaf\x85\xb4\x6a\xd8\x4e\x16\x24\x6c\x67\xd6\x83\x67\x57\xbd\xe3\x36\xc2\x90\xd5\xd4\x01\xe6\xc1\x38\x6a\xb3\x27\x97\xaf\x6b\xb2\x51\xe9\xb2\xd8\xfe\x75\x4c\x47\x48\x2b\x72\xe0\xb3\x94\xea\xb7\x69\x16\x12\x6f\xd6\x8e\xa7\xd6\x5e\xb9\x3d\x59\xf5\xb4\xc5\xac\x40\xf7\xc3\xb3\x7e\x7f\x36\x94\xf2\x94\x24\xc2\x4a\xf8\xc8\xf0\xef\x59\xcd\x9d\xbf\x1d\x28\xe0\xe1\x0f\x79\x9a\x6f\x78\xca\xd1\xd4\x5b\x9d\xb3\xd7\xde\xe4\xa7\x05\x9a\xbe\x99\x18\x27\x14\x98\x3b\x9c\x9d\x44\xd7\xf5\x64\x35\x96\xd4\xf3",
+       "\xd8\x12\x49\x14\x3a\x69\xea\x1c\x9d\xc1\x68\xb5\x5f\xfe\x06\xd4\x6d\x0f\xbc\x00\x70\x65\x11\x03\x53\xd7\x6c\x6c\xce\x4f\xfe\x66",
+       212 },
+      { GCRY_MD_SHA3_256,
+       "\x34\x34\xec\x31\xb1\x0f\xaf\xdb\xfe\xec\x0d\xd6\xbd\x94\xe8\x0f\x7b\xa9\xdc\xa1\x9e\xf0\x75\xf7\xeb\x01\x75\x12\xaf\x66\xd6\xa4\xbc\xf7\xd1\x6b\xa0\x81\x9a\x18\x92\xa6\x37\x2f\x9b\x35\xbc\xc7\xca\x81\x55\xee\x19\xe8\x42\x8b\xc2\x2d\x21\x48\x56\xed\x5f\xa9\x37\x4c\x3c\x09\xbd\xe1\x69\x60\x2c\xc2\x19\x67\x9f\x65\xa1\x56\x6f\xc7\x31\x6f\x4c\xc3\xb6\x31\xa1\x8f\xb4\x44\x9f\xa6\xaf\xa1\x6a\x3d\xb2\xbc\x42\x12\xef\xf5\x39\xc6\x7c\xf1\x84\x68\x08\x26\x53\x55\x89\xc7\x11\x1d\x73\xbf\xfc\xe4\x31\xb4\xc4\x04\x92\xe7\x63\xd9\x27\x95\x60\xaa\xa3\x8e\xb2\xdc\x14\xa2\x12\xd7\x23\xf9\x94\xa1\xfe\x65\x6f\xf4\xdd\x14\x55\x1c\xe4\xe7\xc6\x21\xb2\xaa\x56\x04\xa1\x00\x01\xb2\x87\x8a\x89\x7a\x28\xa0\x80\x95\xc3\x25\xe1\x0a\x26\xd2\xfb\x1a\x75\xbf\xd6\x4c\x25\x03\x09\xbb\x55\xa4\x4f\x23\xbb\xac\x0d\x55\x16\xa1\xc6\x87\xd3\xb4\x1e\xf2\xfb\xbf\x9c\xc5\x6d\x47\x39",
+       "\xaa\x8b\xbd\x48\x12\x14\x22\x11\x21\x27\x63\xbf\x8e\xe4\xd6\xe0\xaa\xda\xfe\x5e\x52\x8a\xea\x1f\xb1\xbe\x11\x88\x06\xe4\x9f\x66",
+       213 },
+      { GCRY_MD_SHA3_256,
+       "\x7c\x79\x53\xd8\x1c\x8d\x20\x8f\xd1\xc9\x76\x81\xd4\x8f\x49\xdd\x00\x34\x56\xde\x60\x47\x5b\x84\x07\x0e\xf4\x84\x7c\x33\x3b\x74\x57\x5b\x1f\xc8\xd2\xa1\x86\x96\x44\x85\xa3\xb8\x63\x4f\xea\xa3\x59\x5a\xaa\x1a\x2f\x45\x95\xa7\xd6\xb6\x15\x35\x63\xde\xe3\x1b\xba\xc4\x43\xc8\xa3\x3e\xed\x6d\x5d\x95\x6a\x98\x0a\x68\x36\x6c\x25\x27\xb5\x50\xee\x95\x02\x50\xdf\xb6\x91\xea\xcb\xd5\xd5\x6a\xe1\x4b\x97\x06\x68\xbe\x17\x4c\x89\xdf\x2f\xea\x43\xae\x52\xf1\x31\x42\x63\x9c\x88\x4f\xd6\x2a\x36\x83\xc0\xc3\x79\x2f\x0f\x24\xab\x13\x18\xbc\xb2\x7e\x21\xf4\x73\x7f\xab\x62\xc7\x7e\xa3\x8b\xc8\xfd\x1c\xf4\x1f\x7d\xab\x64\xc1\x3f\xeb\xe7\x15\x2b\xf5\xbb\x7a\xb5\xa7\x8f\x53\x46\xd4\x3c\xc7\x41\xcb\x6f\x72\xb7\xb8\x98\x0f\x26\x8b\x68\xbf\x62\xab\xdf\xb1\x57\x7a\x52\x43\x8f\xe1\x4b\x59\x14\x98\xcc\x95\xf0\x71\x22\x84\x60\xc7\xc5\xd5\xce\xb4\xa7\xbd\xe5\x88\xe7\xf2\x1c",
+       "\x40\x89\xb1\x81\xdf\x5e\xca\x5f\x14\xda\xb1\x05\x7a\xaa\xee\xca\xba\x15\xf2\x00\xfd\xda\x0d\xe4\x93\x57\xd6\x19\x6f\xaa\xb4\x4b",
+       214 },
+      { GCRY_MD_SHA3_256,
+       "\x7a\x6a\x4f\x4f\xdc\x59\xa1\xd2\x23\x38\x1a\xe5\xaf\x49\x8d\x74\xb7\x25\x2e\xcf\x59\xe3\x89\xe4\x91\x30\xc7\xea\xee\x62\x6e\x7b\xd9\x89\x7e\xff\xd9\x20\x17\xf4\xcc\xde\x66\xb0\x44\x04\x62\xcd\xed\xfd\x35\x2d\x81\x53\xe6\xa4\xc8\xd7\xa0\x81\x2f\x70\x1c\xc7\x37\xb5\x17\x8c\x25\x56\xf0\x71\x11\x20\x0e\xb6\x27\xdb\xc2\x99\xca\xa7\x92\xdf\xa5\x8f\x35\x93\x52\x99\xfa\x3a\x35\x19\xe9\xb0\x31\x66\xdf\xfa\x15\x91\x03\xff\xa3\x5e\x85\x77\xf7\xc0\xa8\x6c\x6b\x46\xfe\x13\xdb\x8e\x2c\xdd\x9d\xcf\xba\x85\xbd\xdd\xcc\xe0\xa7\xa8\xe1\x55\xf8\x1f\x71\x2d\x8e\x9f\xe6\x46\x15\x3d\x3d\x22\xc8\x11\xbd\x39\xf8\x30\x43\x3b\x22\x13\xdd\x46\x30\x19\x41\xb5\x92\x93\xfd\x0a\x33\xe2\xb6\x3a\xdb\xd9\x52\x39\xbc\x01\x31\x5c\x46\xfd\xb6\x78\x87\x5b\x3c\x81\xe0\x53\xa4\x0f\x58\x1c\xfb\xec\x24\xa1\x40\x4b\x16\x71\xa1\xb8\x8a\x6d\x06\x12\x02\x29\x51\x8f\xb1\x3a\x74\xca\x0a\xc5\xae",
+       "\xde\xbf\x59\xbb\x23\x3d\x05\x54\x98\x53\x80\x4f\xc6\x78\x40\x82\x1b\xd5\x80\x2f\x87\xfc\x8a\x91\x5b\x71\x0d\x3e\x82\x07\x09\x50",
+       215 },
+      { GCRY_MD_SHA3_256,
+       "\xd9\xfa\xa1\x4c\xeb\xe9\xb7\xde\x55\x1b\x6c\x07\x65\x40\x9a\x33\x93\x85\x62\x01\x3b\x5e\x8e\x0e\x1e\x0a\x64\x18\xdf\x73\x99\xd0\xa6\xa7\x71\xfb\x81\xc3\xca\x9b\xd3\xbb\x8e\x29\x51\xb0\xbc\x79\x25\x25\xa2\x94\xeb\xd1\x08\x36\x88\x80\x6f\xe5\xe7\xf1\xe1\x7f\xd4\xe3\xa4\x1d\x00\xc8\x9e\x8f\xcf\x4a\x36\x3c\xae\xdb\x1a\xcb\x55\x8e\x3d\x56\x2f\x13\x02\xb3\xd8\x3b\xb8\x86\xed\x27\xb7\x60\x33\x79\x81\x31\xda\xb0\x5b\x42\x17\x38\x1e\xaa\xa7\xba\x15\xec\x82\x0b\xb5\xc1\x3b\x51\x6d\xd6\x40\xea\xec\x5a\x27\xd0\x5f\xdf\xca\x0f\x35\xb3\xa5\x31\x21\x46\x80\x6b\x4c\x02\x75\xbc\xd0\xaa\xa3\xb2\x01\x7f\x34\x69\x75\xdb\x56\x6f\x9b\x4d\x13\x7f\x4e\xe1\x06\x44\xc2\xa2\xda\x66\xde\xec\xa5\x34\x2e\x23\x64\x95\xc3\xc6\x28\x05\x28\xbf\xd3\x2e\x90\xaf\x4c\xd9\xbb\x90\x8f\x34\x01\x2b\x52\xb4\xbc\x56\xd4\x8c\xc8\xa6\xb5\x9b\xab\x01\x49\x88\xea\xbd\x12\xe1\xa0\xa1\xc2\xe1\x70\xe7",
+       "\x0f\xdb\xa1\xc7\x9f\x55\xf2\x33\xa1\x21\x7f\x52\x2d\x6c\x81\xf7\x77\xf3\x30\xfa\xdb\x56\x5e\x11\x71\xf3\x9e\x17\x88\x91\x33\x42",
+       216 },
+      { GCRY_MD_SHA3_256,
+       "\x2d\x84\x27\x43\x3d\x0c\x61\xf2\xd9\x6c\xfe\x80\xcf\x1e\x93\x22\x65\xa1\x91\x36\x5c\x3b\x61\xaa\xa3\xd6\xdc\xc0\x39\xf6\xba\x2a\xd5\x2a\x6a\x8c\xc3\x0f\xc1\x0f\x70\x5e\x6b\x77\x05\x10\x59\x77\xfa\x49\x6c\x1c\x70\x8a\x27\x7a\x12\x43\x04\xf1\xfc\x40\x91\x1e\x74\x41\xd1\xb5\xe7\x7b\x95\x1a\xad\x7b\x01\xfd\x5d\xb1\xb3\x77\xd1\x65\xb0\x5b\xbf\x89\x80\x42\xe3\x96\x60\xca\xf8\xb2\x79\xfe\x52\x29\xd1\xa8\xdb\x86\xc0\x99\x9e\xd6\x5e\x53\xd0\x1c\xcb\xc4\xb4\x31\x73\xcc\xf9\x92\xb3\xa1\x45\x86\xf6\xba\x42\xf5\xfe\x30\xaf\xa8\xae\x40\xc5\xdf\x29\x96\x6f\x93\x46\xda\x5f\x8b\x35\xf1\x6a\x1d\xe3\xab\x6d\xe0\xf4\x77\xd8\xd8\x66\x09\x18\x06\x0e\x88\xb9\xb9\xe9\xca\x6a\x42\x07\x03\x3b\x87\xa8\x12\xdb\xf5\x54\x4d\x39\xe4\x88\x20\x10\xf8\x2b\x6c\xe0\x05\xf8\xe8\xff\x6f\xe3\xc3\x80\x6b\xc2\xb7\x3c\x2b\x83\xaf\xb7\x04\x34\x56\x29\x30\x4f\x9f\x86\x35\x87\x12\xe9\xfa\xe3\xca\x3e",
+       "\xed\x45\xa0\x6e\x95\xa6\x53\x92\x70\xb0\x22\x90\xd7\x10\x05\xf0\x1c\x55\xba\x07\x74\x14\xc3\xbc\xdb\x37\x95\x37\xe6\xdb\xef\xc9",
+       217 },
+      { GCRY_MD_SHA3_256,
+       "\x5e\x19\xd9\x78\x87\xfc\xaa\xc0\x38\x7e\x22\xc6\xf8\x03\xc3\x4a\x3d\xac\xd2\x60\x41\x72\x43\x3f\x7a\x8a\x7a\x52\x6c\xa4\xa2\xa1\x27\x1e\xcf\xc5\xd5\xd7\xbe\x5a\xc0\xd8\x5d\x92\x10\x95\x35\x0d\xfc\x65\x99\x7d\x44\x3c\x21\xc8\x09\x4e\x0a\x3f\xef\xd2\x96\x1b\xcb\x94\xae\xd0\x32\x91\xae\x31\x0c\xcd\xa7\x5d\x8a\xce\x4b\xc7\xd8\x9e\x7d\x3e\x5d\x16\x50\xbd\xa5\xd6\x68\xb8\xb5\x0b\xfc\x8e\x60\x8e\x18\x4f\x4d\x3a\x9a\x2b\xad\xc4\xff\x5f\x07\xe0\xc0\xbc\x8a\x9f\x2e\x0b\x2a\x26\xfd\x6d\x8c\x55\x00\x08\xfa\xaa\xb7\x5f\xd7\x1a\xf2\xa4\x24\xbe\xc9\xa7\xcd\x9d\x83\xfa\xd4\xc8\xe9\x31\x91\x15\x65\x6a\x87\x17\xd3\xb5\x23\xa6\x8f\xf8\x00\x42\x58\xb9\x99\x0e\xd3\x62\x30\x84\x61\x80\x4b\xa3\xe3\xa7\xe9\x2d\x8f\x2f\xfa\xe5\xc2\xfb\xa5\x5b\xa5\xa3\xc2\x7c\x0a\x2f\x71\xbd\x71\x1d\x2f\xe1\x79\x9c\x2a\xdb\x31\xb2\x00\x03\x54\x81\xe9\xee\x5c\x4a\xdf\x2a\xb9\xc0\xfa\x50\xb2\x39\x75\xcf",
+       "\x37\xe7\xcf\x6a\x9a\x31\xb0\x98\x2b\x24\x79\x43\x2b\x78\x38\x65\x77\x41\xb0\xee\x79\xad\xda\x1b\x28\x75\x50\xeb\x32\x5c\x78\xcc",
+       218 },
+      { GCRY_MD_SHA3_256,
+       "\xc8\xe9\x76\xab\x46\x38\x90\x93\x87\xce\x3b\x8d\x4e\x51\x0c\x32\x30\xe5\x69\x0e\x02\xc4\x50\x93\xb1\xd2\x97\x91\x0a\xbc\x48\x1e\x56\xee\xa0\xf2\x96\xf9\x83\x79\xdf\xc9\x08\x0a\xf6\x9e\x73\xb2\x39\x9d\x1c\x14\x3b\xee\x80\xae\x13\x28\x16\x2c\xe1\xba\x7f\x6a\x83\x74\x67\x9b\x20\xaa\xcd\x38\x0e\xb4\xe6\x13\x82\xc9\x99\x98\x70\x4d\x62\x70\x1a\xfa\x91\x4f\x9a\x27\x05\xcd\xb0\x65\x88\x5f\x50\xd0\x86\xc3\xeb\x57\x53\x70\x0c\x38\x71\x18\xbb\x14\x2f\x3e\x6d\xa1\xe9\x88\xdf\xb3\x1a\xc7\x5d\x73\x68\x93\x1e\x45\xd1\x39\x1a\x27\x4b\x22\xf8\x3c\xeb\x07\x2f\x9b\xca\xbc\x0b\x21\x66\x85\xbf\xd7\x89\xf5\x02\x39\x71\x02\x4b\x18\x78\xa2\x05\x44\x25\x22\xf9\xea\x7d\x87\x97\xa4\x10\x2a\x3d\xf4\x17\x03\x76\x82\x51\xfd\x5e\x01\x7c\x85\xd1\x20\x0a\x46\x41\x18\xaa\x35\x65\x4e\x7c\xa3\x9f\x3c\x37\x5b\x8e\xf8\xcb\xe7\x53\x4d\xbc\x64\xbc\x20\xbe\xfb\x41\x7c\xf6\x0e\xc9\x2f\x63\xd9\xee\x73\x97",
+       "\x37\x37\x04\xf6\x41\xfa\xf2\xb9\x18\xe2\x2e\x91\x42\xab\xf6\xb4\xac\x71\xb6\x88\x3a\xc4\xd7\xa0\x75\xf6\x26\xe9\x47\x83\x7d\x3f",
+       219 },
+      { GCRY_MD_SHA3_256,
+       "\x71\x45\xfa\x12\x4b\x74\x29\xa1\xfc\x22\x31\x23\x7a\x94\x9b\xa7\x20\x1b\xcc\x18\x22\xd3\x27\x2d\xe0\x05\xb6\x82\x39\x81\x96\xc2\x5f\x7e\x5c\xc2\xf2\x89\xfb\xf4\x44\x15\xf6\x99\xcb\x7f\xe6\x75\x77\x91\xb1\x44\x34\x10\x23\x4a\xe0\x61\xed\xf6\x23\x35\x9e\x2b\x4e\x32\xc1\x9b\xf8\x84\x50\x43\x2d\xd0\x1c\xaa\x5e\xb1\x6a\x1d\xc3\x78\xf3\x91\xca\x5e\x3c\x4e\x5f\x35\x67\x28\xbd\xdd\x49\x75\xdb\x7c\x89\x0d\xa8\xbb\xc8\x4c\xc7\x3f\xf2\x44\x39\x4d\x0d\x48\x95\x49\x78\x76\x5e\x4a\x00\xb5\x93\xf7\x0f\x2c\xa0\x82\x67\x3a\x26\x1e\xd8\x8d\xbc\xef\x11\x27\x72\x8d\x8c\xd8\x9b\xc2\xc5\x97\xe9\x10\x2c\xed\x60\x10\xf6\x5f\xa7\x5a\x14\xeb\xe4\x67\xfa\x57\xce\x3b\xd4\x94\x8b\x68\x67\xd7\x4a\x9d\xf5\xc0\xec\x6f\x53\x0c\xbf\x2e\xe6\x1c\xe6\xf0\x6b\xc8\xf2\x86\x4d\xff\x55\x83\x77\x6b\x31\xdf\x8c\x7f\xfc\xb6\x14\x28\xa5\x6b\xf7\xbd\x37\x18\x8b\x4a\x51\x23\xbb\xf3\x38\x39\x3a\xf4\x6e\xda\x85\xe6",
+       "\xee\x59\x94\xb3\xd3\x2b\xda\xe5\x8e\x72\x56\x6f\xc2\x4b\x88\x64\x61\x21\x7f\xdd\x72\x73\xe1\x60\x8f\x0b\x29\x26\xb7\x92\x35\x46",
+       220 },
+      { GCRY_MD_SHA3_256,
+       "\x7f\xdf\xad\xcc\x9d\x29\xba\xd2\x3a\xe0\x38\xc6\xc6\x5c\xda\x1a\xef\x75\x72\x21\xb8\x87\x2e\xd3\xd7\x5f\xf8\xdf\x7d\xa0\x62\x7d\x26\x6e\x22\x4e\x81\x2c\x39\xf7\x98\x3e\x45\x58\xbf\xd0\xa1\xf2\xbe\xf3\xfe\xb5\x6b\xa0\x91\x20\xef\x76\x29\x17\xb9\xc0\x93\x86\x79\x48\x54\x7a\xee\x98\x60\x0d\x10\xd8\x7b\x20\x10\x68\x78\xa8\xd2\x2c\x64\x37\x8b\xf6\x34\xf7\xf7\x59\x00\xc0\x39\x86\xb0\x77\xb0\xbf\x8b\x74\x0a\x82\x44\x7b\x61\xb9\x9f\xee\x53\x76\xc5\xeb\x66\x80\xec\x9e\x30\x88\xf0\xbd\xd0\xc5\x68\x83\x41\x3d\x60\xc1\x35\x7d\x3c\x81\x19\x50\xe5\x89\x0e\x76\x00\x10\x3c\x91\x63\x41\xb8\x0c\x74\x3c\x6a\x85\x2b\x7b\x4f\xb6\x0c\x3b\xa2\x1f\x3b\xc1\x5b\x83\x82\x43\x7a\x68\x45\x47\x79\xcf\x3c\xd7\xf9\xf9\x0c\xcc\x8e\xf2\x8d\x0b\x70\x65\x35\xb1\xe4\x10\x8e\xb5\x62\x7b\xb4\x5d\x71\x9c\xb0\x46\x83\x9a\xee\x31\x1c\xa1\xab\xdc\x83\x19\xe0\x50\xd6\x79\x72\xcb\x35\xa6\xb1\x60\x1b\x25\xdb\xf4\x87",
+       "\x6a\x58\x4f\x9f\x4a\xcd\x8f\xc8\xe1\x5d\xac\xd3\x26\x29\x1f\xe9\x31\x1c\x20\x98\x72\x25\xc5\x1c\xf4\x25\x1e\x52\xb4\x7f\xa2\x23",
+       221 },
+      { GCRY_MD_SHA3_256,
+       "\x98\x86\x38\x21\x9f\xd3\x09\x54\x21\xf8\x26\xf5\x6e\x4f\x09\xe3\x56\x29\x6b\x62\x8c\x3c\xe6\x93\x0c\x9f\x2e\x75\x8f\xd1\xa8\x0c\x82\x73\xf2\xf6\x1e\x4d\xaa\xe6\x5c\x4f\x11\x0d\x3e\x7c\xa0\x96\x5a\xc7\xd2\x4e\x34\xc0\xdc\x4b\xa2\xd6\xff\x0b\xf5\xbb\xe9\x3b\x35\x85\xf3\x54\xd7\x54\x3c\xb5\x42\xa1\xaa\x54\x67\x4d\x37\x50\x77\xf2\xd3\x60\xa8\xf4\xd4\x2f\x3d\xb1\x31\xc3\xb7\xab\x73\x06\x26\x7b\xa1\x07\x65\x98\x64\xa9\x0c\x8c\x90\x94\x60\xa7\x36\x21\xd1\xf5\xd9\xd3\xfd\x95\xbe\xb1\x9b\x23\xdb\x1c\xb6\xc0\xd0\xfb\xa9\x1d\x36\x89\x15\x29\xb8\xbd\x82\x63\xca\xa1\xba\xb5\x6a\x4a\xff\xae\xd4\x49\x62\xdf\x09\x6d\x8d\x5b\x1e\xb8\x45\xef\x31\x18\x8b\x3e\x10\xf1\xaf\x81\x1a\x13\xf1\x56\xbe\xb7\xa2\x88\xaa\xe5\x93\xeb\xd1\x47\x1b\x62\x4a\xa1\xa7\xc6\xad\xf0\x1e\x22\x00\xb3\xd7\x2d\x88\xa3\xae\xd3\x10\x0c\x88\x23\x1e\x41\xef\xc3\x76\x90\x6f\x0b\x58\x0d\xc8\x95\xf0\x80\xfd\xa5\x74\x1d\xb1\xcb",
+       "\x4f\x92\x83\x9c\xdd\xb0\xdf\x31\xd1\x6a\x0d\xb5\x3b\xbe\x07\x69\x8a\x7c\x19\x12\xd5\x59\x0d\x21\x15\x5d\x45\xdb\x1b\x48\xca\xb4",
+       222 },
+      { GCRY_MD_SHA3_256,
+       "\x5a\xab\x62\x75\x6d\x30\x7a\x66\x9d\x14\x6a\xba\x98\x8d\x90\x74\xc5\xa1\x59\xb3\xde\x85\x15\x1a\x81\x9b\x11\x7c\xa1\xff\x65\x97\xf6\x15\x6e\x80\xfd\xd2\x8c\x9c\x31\x76\x83\x51\x64\xd3\x7d\xa7\xda\x11\xd9\x4e\x09\xad\xd7\x70\xb6\x8a\x6e\x08\x1c\xd2\x2c\xa0\xc0\x04\xbf\xe7\xcd\x28\x3b\xf4\x3a\x58\x8d\xa9\x1f\x50\x9b\x27\xa6\x58\x4c\x47\x4a\x4a\x2f\x3e\xe0\xf1\xf5\x64\x47\x37\x92\x40\xa5\xab\x1f\xb7\x7f\xdc\xa4\x9b\x30\x5f\x07\xba\x86\xb6\x27\x56\xfb\x9e\xfb\x4f\xc2\x25\xc8\x68\x45\xf0\x26\xea\x54\x20\x76\xb9\x1a\x0b\xc2\xcd\xd1\x36\xe1\x22\xc6\x59\xbe\x25\x9d\x98\xe5\x84\x1d\xf4\xc2\xf6\x03\x30\xd4\xd8\xcd\xee\x7b\xf1\xa0\xa2\x44\x52\x4e\xec\xc6\x8f\xf2\xae\xf5\xbf\x00\x69\xc9\xe8\x7a\x11\xc6\xe5\x19\xde\x1a\x40\x62\xa1\x0c\x83\x83\x73\x88\xf7\xef\x58\x59\x8a\x38\x46\xf4\x9d\x49\x96\x82\xb6\x83\xc4\xa0\x62\xb4\x21\x59\x4f\xaf\xbc\x13\x83\xc9\x43\xba\x83\xbd\xef\x51\x5e\xfc\xf1\x0d",
+       "\xea\xfd\x66\x1f\x34\x3a\xe8\x34\xc6\x21\xe0\x74\xac\x69\x03\xa2\xe3\xe6\x32\x4f\x36\x5b\x34\x32\xdf\xfa\x73\x2f\x47\x7a\xc1\x29",
+       223 },
+      { GCRY_MD_SHA3_256,
+       "\x47\xb8\x21\x6a\xa0\xfb\xb5\xd6\x79\x66\xf2\xe8\x2c\x17\xc0\x7a\xa2\xd6\x32\x7e\x96\xfc\xd8\x3e\x3d\xe7\x33\x36\x89\xf3\xee\x79\x99\x4a\x1b\xf4\x50\x82\xc4\xd7\x25\xed\x8d\x41\x20\x5c\xb5\xbc\xdf\x5c\x34\x1f\x77\xfa\xcb\x1d\xa4\x6a\x5b\x9b\x2c\xbc\x49\xea\xdf\x78\x6b\xcd\x88\x1f\x37\x1a\x95\xfa\x17\xdf\x73\xf6\x06\x51\x9a\xea\x0f\xf7\x9d\x5a\x11\x42\x7b\x98\xee\x7f\x13\xa5\xc0\x06\x37\xe2\x85\x41\x34\x69\x10\x59\x83\x91\x21\xfe\xa9\xab\xe2\xcd\x1b\xcb\xbb\xf2\x7c\x74\xca\xf3\x67\x8e\x05\xbf\xb1\xc9\x49\x89\x7e\xa0\x1f\x56\xff\xa4\xda\xfb\xe8\x64\x46\x11\x68\x5c\x61\x7a\x32\x06\xc7\xa7\x03\x6e\x4a\xc8\x16\x79\x9f\x69\x3d\xaf\xe7\xf1\x9f\x30\x3c\xe4\xeb\xa0\x9d\x21\xe0\x36\x10\x20\x1b\xfc\x66\x5b\x72\x40\x0a\x54\x7a\x1e\x00\xfa\x9b\x7a\xd8\xd8\x4f\x84\xb3\x4a\xef\x11\x85\x15\xe7\x4d\xef\x11\xb9\x18\x8b\xd1\xe1\xf9\x7d\x9a\x12\xc3\x01\x32\xec\x28\x06\x33\x9b\xda\xda\xcd\xa2\xfd\x8b\x78",
+       "\x3d\xce\xc6\x69\xc5\xd0\x17\x6b\x1b\xdc\x00\x27\x28\xd2\x42\xc5\x87\xdd\xa0\x3b\x3a\xbf\xa6\x07\x45\x23\xd3\xfa\xef\x48\x20\xbe",
+       224 },
+      { GCRY_MD_SHA3_256,
+       "\x8c\xff\x1f\x67\xfe\x53\xc0\x98\x89\x6d\x91\x36\x38\x9b\xd8\x88\x18\x16\xcc\xab\x34\x86\x2b\xb6\x7a\x65\x6e\x3d\x98\x89\x6f\x3c\xe6\xff\xd4\xda\x73\x97\x58\x09\xfc\xdf\x96\x66\x76\x0d\x6e\x56\x1c\x55\x23\x8b\x20\x5d\x80\x49\xc1\xce\xde\xef\x37\x4d\x17\x35\xda\xa5\x33\x14\x7b\xfa\x96\x0b\x2c\xce\x4a\x4f\x25\x41\x76\xbb\x4d\x1b\xd1\xe8\x96\x54\x43\x2b\x8d\xbe\x1a\x13\x5c\x42\x11\x5b\x39\x4b\x02\x48\x56\xa2\xa8\x3d\xc8\x5d\x67\x82\xbe\x4b\x44\x42\x39\x56\x7c\xce\xc4\xb1\x84\xd4\x54\x8e\xae\x3f\xf6\xa1\x92\xf3\x43\x29\x2b\xa2\xe3\x2a\x0f\x26\x7f\x31\xcc\x26\x71\x9e\xb8\x52\x45\xd4\x15\xfb\x89\x7a\xc2\xda\x43\x3e\xe9\x1a\x99\x42\x4c\x9d\x7f\x17\x66\xa4\x41\x71\xd1\x65\x10\x01\xc3\x8f\xc7\x92\x94\xac\xcc\x68\xce\xb5\x66\x5d\x36\x21\x84\x54\xd3\xba\x16\x9a\xe0\x58\xa8\x31\x33\x8c\x17\x74\x36\x03\xf8\x1e\xe1\x73\xbf\xc0\x92\x74\x64\xf9\xbd\x72\x8d\xee\x94\xc6\xae\xab\x7a\xae\x6e\xe3\xa6\x27\xe8",
+       "\x4b\xdf\x73\x1b\xbb\x3d\x0e\x2a\xb0\xeb\x3d\x97\x21\x23\xa7\xa0\xa0\x85\xe8\xa9\x8a\xc6\xaf\x8a\xdb\xd3\x35\xb3\x72\x75\xdd\xff",
+       225 },
+      { GCRY_MD_SHA3_256,
+       "\xea\xcd\x07\x97\x1c\xff\x9b\x99\x39\x90\x3f\x8c\x1d\x8c\xbb\x5d\x4d\xb1\xb5\x48\xa8\x5d\x04\xe0\x37\x51\x4a\x58\x36\x04\xe7\x87\xf3\x29\x92\xbf\x21\x11\xb9\x7a\xc5\xe8\xa9\x38\x23\x35\x52\x73\x13\x21\x52\x2a\xb5\xe8\x58\x35\x61\x26\x0b\x7d\x13\xeb\xee\xf7\x85\xb2\x3a\x41\xfd\x85\x76\xa6\xda\x76\x4a\x8e\xd6\xd8\x22\xd4\x95\x7a\x54\x5d\x52\x44\x75\x6c\x18\xaa\x80\xe1\xaa\xd4\xd1\xf9\xc2\x0d\x25\x9d\xee\x17\x11\xe2\xcc\x8f\xd0\x13\x16\x9f\xb7\xcc\x4c\xe3\x8b\x36\x2f\x8e\x09\x36\xae\x91\x98\xb7\xe8\x38\xdc\xea\x4f\x7a\x5b\x94\x29\xbb\x3f\x6b\xbc\xf2\xdc\x92\x56\x5e\x36\x76\xc1\xc5\xe6\xeb\x3d\xd2\xa0\xf8\x6a\xa2\x3e\xdd\x3d\x08\x91\xf1\x97\x44\x76\x92\x79\x4b\x3d\xfa\x26\x96\x11\xad\x97\xf7\x2b\x79\x56\x02\xb4\xfd\xb1\x98\xf3\xfd\x3e\xb4\x1b\x41\x50\x64\x25\x6e\x34\x5e\x8d\x8c\x51\xc5\x55\xdc\x8a\x21\x90\x4a\x9b\x0f\x1a\xd0\xef\xfa\xb7\x78\x6a\xac\x2d\xa3\xb1\x96\x50\x7e\x9f\x33\xca\x35\x64\x27",
+       "\x47\xf9\x04\xfe\xea\x60\x72\x25\xca\xb2\xe3\xc5\x27\x48\x87\x89\x64\xbf\xed\xcf\xe0\x68\x72\x7d\xe6\x10\xf6\x34\x21\x36\x7b\xcf",
+       226 },
+      { GCRY_MD_SHA3_256,
+       "\x23\xac\x4e\x9a\x42\xc6\xef\x45\xc3\x33\x6c\xe6\xdf\xc2\xff\x7d\xe8\x88\x4c\xd2\x3d\xc9\x12\xfe\xf0\xf7\x75\x6c\x09\xd3\x35\xc1\x89\xf3\xad\x3a\x23\x69\x7a\xbd\xa8\x51\xa8\x18\x81\xa0\xc8\xcc\xaf\xc9\x80\xab\x2c\x70\x25\x64\xc2\xbe\x15\xfe\x4c\x4b\x9f\x10\xdf\xb2\x24\x8d\x0d\x0c\xb2\xe2\x88\x7f\xd4\x59\x8a\x1d\x4a\xcd\xa8\x97\x94\x4a\x2f\xfc\x58\x0f\xf9\x27\x19\xc9\x5c\xf2\xaa\x42\xdc\x58\x46\x74\xcb\x5a\x9b\xc5\x76\x5b\x9d\x6d\xdf\x57\x89\x79\x1d\x15\xf8\xdd\x92\x5a\xa1\x2b\xff\xaf\xbc\xe6\x08\x27\xb4\x90\xbb\x7d\xf3\xdd\xa6\xf2\xa1\x43\xc8\xbf\x96\xab\xc9\x03\xd8\x3d\x59\xa7\x91\xe2\xd6\x28\x14\xa8\x9b\x80\x80\xa2\x80\x60\x56\x8c\xf2\x4a\x80\xae\x61\x17\x9f\xe8\x4e\x0f\xfa\xd0\x03\x88\x17\x8c\xb6\xa6\x17\xd3\x7e\xfd\x54\xcc\x01\x97\x0a\x4a\x41\xd1\xa8\xd3\xdd\xce\x46\xed\xbb\xa4\xab\x7c\x90\xad\x56\x53\x98\xd3\x76\xf4\x31\x18\x9c\xe8\xc1\xc3\x3e\x13\x2f\xea\xe6\xa8\xcd\x17\xa6\x1c\x63\x00\x12",
+       "\x32\x49\x37\x60\x7d\x9f\x16\xaf\x81\x57\x01\x74\x9f\x03\x77\xb3\x28\x1a\xf9\xc5\xbb\x56\x5d\x6f\x2b\x96\x11\x53\x2b\x6b\xf0\x44",
+       227 },
+      { GCRY_MD_SHA3_256,
+       "\x01\x72\xdf\x73\x22\x82\xc9\xd4\x88\x66\x9c\x35\x8e\x34\x92\x26\x0c\xbe\x91\xc9\x5c\xfb\xc1\xe3\xfe\xa6\xc4\xb0\xec\x12\x9b\x45\xf2\x42\xac\xe0\x9f\x15\x2f\xc6\x23\x4e\x1b\xee\x8a\xab\x8c\xd5\x6e\x8b\x48\x6e\x1d\xcb\xa9\xc0\x54\x07\xc2\xf9\x5d\xa8\xd8\xf1\xc0\xaf\x78\xee\x2e\xd8\x2a\x3a\x79\xec\x0c\xb0\x70\x93\x96\xee\x62\xaa\xdb\x84\xf8\xa4\xee\x8a\x7c\xcc\xa3\xc1\xee\x84\xe3\x02\xa0\x9e\xa8\x02\x20\x4a\xfe\xcf\x04\x09\x7e\x67\xd0\xf8\xe8\xa9\xd2\x65\x11\x26\xc0\xa5\x98\xa3\x70\x81\xe4\x2d\x16\x8b\x0a\xe8\xa7\x19\x51\xc5\x24\x25\x9e\x4e\x20\x54\xe5\x35\xb7\x79\x67\x9b\xda\xde\x56\x6f\xe5\x57\x00\x85\x86\x18\xe6\x26\xb4\xa0\xfa\xf8\x95\xbc\xce\x90\x11\x50\x4a\x49\xe0\x5f\xd5\x61\x27\xea\xe3\xd1\xf8\x91\x7a\xfb\x54\x8e\xca\xda\xbd\xa1\x02\x01\x11\xfe\xc9\x31\x4c\x41\x34\x98\xa3\x60\xb0\x86\x40\x54\x9a\x22\xcb\x23\xc7\x31\xac\xe7\x43\x25\x2a\x82\x27\xa0\xd2\x68\x9d\x4c\x60\x01\x60\x66\x78\xdf\xb9\x21",
+       "\xb9\x84\xc2\xd6\xb6\xfd\xc2\x85\x74\xaa\xd5\x51\xfc\x16\xb6\x8f\x85\xbf\x6c\xc4\x80\xa1\x5c\x12\x8a\xe5\x61\x65\x61\xd4\x67\x21",
+       228 },
+      { GCRY_MD_SHA3_256,
+       "\x38\x75\xb9\x24\x0c\xf3\xe0\xa8\xb5\x9c\x65\x85\x40\xf2\x6a\x70\x1c\xf1\x88\x49\x6e\x2c\x21\x74\x78\x8b\x12\x6f\xd2\x94\x02\xd6\xa7\x54\x53\xba\x06\x35\x28\x4d\x08\x83\x5f\x40\x05\x1a\x2a\x96\x83\xdc\x92\xaf\xb9\x38\x37\x19\x19\x12\x31\x17\x03\x79\xba\x6f\x4a\xdc\x81\x6f\xec\xbb\x0f\x9c\x44\x6b\x78\x5b\xf5\x20\x79\x68\x41\xe5\x88\x78\xb7\x3c\x58\xd3\xeb\xb0\x97\xce\x47\x61\xfd\xea\xbe\x15\xde\x2f\x31\x9d\xfb\xaf\x17\x42\xcd\xeb\x38\x95\x59\xc7\x88\x13\x1a\x67\x93\xe1\x93\x85\x66\x61\x37\x6c\x81\xce\x95\x68\xda\x19\xaa\x69\x25\xb4\x7f\xfd\x77\xa4\x3c\x7a\x0e\x75\x8c\x37\xd6\x92\x54\x90\x9f\xf0\xfb\xd4\x15\xef\x8e\xb9\x37\xbc\xd4\x9f\x91\x46\x8b\x49\x97\x4c\x07\xdc\x81\x9a\xbd\x67\x39\x5d\xb0\xe0\x58\x74\xff\x83\xdd\xda\xb8\x95\x34\x4a\xbd\x0e\x71\x11\xb2\xdf\x9e\x58\xd7\x6d\x85\xad\x98\x10\x6b\x36\x29\x58\x26\xbe\x04\xd4\x35\x61\x55\x95\x60\x5e\x4b\x4b\xb8\x24\xb3\x3c\x4a\xfe\xb5\xe7\xbb\x0d\x19\xf9\x09",
+       "\x91\xa5\xb9\xfc\x2d\xcc\x5f\xae\xda\x57\xd2\xe7\xa4\x1e\x92\x2d\xc3\x2d\x57\x2a\xeb\xdf\x6d\x54\xcb\x8c\x3a\xe4\x24\x5e\x85\x65",
+       229 },
+      { GCRY_MD_SHA3_256,
+       "\x74\x7c\xc1\xa5\x9f\xef\xba\x94\xa9\xc7\x5b\xa8\x66\xc3\x0d\xc5\xc1\xcb\x0c\x0f\x8e\x93\x61\xd9\x84\x84\x95\x6d\xd5\xd1\xa4\x0f\x61\x84\xaf\xbe\x3d\xac\x9f\x76\x02\x8d\x1c\xae\xcc\xfb\xf6\x91\x99\xc6\xce\x2b\x4c\x09\x2a\x3f\x4d\x2a\x56\xfe\x5a\x33\xa0\x07\x57\xf4\xd7\xde\xe5\xdf\xb0\x52\x43\x11\xa9\x7a\xe0\x66\x8a\x47\x97\x1b\x95\x76\x6e\x2f\x6d\xd4\x8c\x3f\x57\x84\x1f\x91\xf0\x4a\x00\xad\x5e\xa7\x0f\x2d\x47\x9a\x26\x20\xdc\x5c\xd7\x8e\xaa\xb3\xa3\xb0\x11\x71\x9b\x7e\x78\xd1\x9d\xdf\x70\xd9\x42\x37\x98\xaf\x77\x51\x7e\xbc\x55\x39\x2f\xcd\x01\xfc\x60\x0d\x8d\x46\x6b\x9e\x7a\x7a\x85\xbf\x33\xf9\xcc\x54\x19\xe9\xbd\x87\x4d\xdf\xd6\x09\x81\x15\x0d\xda\xf8\xd7\xfe\xba\xa4\x37\x4f\x08\x72\xa5\x62\x8d\x31\x80\x00\x31\x1e\x2f\x56\x55\x36\x5a\xd4\xd4\x07\xc2\x0e\x5c\x04\xdf\x17\xa2\x22\xe7\xde\xec\x79\xc5\xab\x11\x16\xd8\x57\x2f\x91\xcd\x06\xe1\xcc\xc7\xce\xd5\x37\x36\xfc\x86\x7f\xd4\x9e\xce\xbe\x6b\xf8\x08\x2e\x8a",
+       "\x97\xdc\xa1\x05\x0a\x46\x5b\x60\xe9\x1e\xbe\x26\xe2\x9a\xdb\x5a\x28\x6a\x05\x82\xee\xe2\xe8\x9b\x8b\x90\x19\x54\x29\x3f\x61\x46",
+       230 },
+      { GCRY_MD_SHA3_256,
+       "\x57\xaf\x97\x1f\xcc\xae\xc9\x74\x35\xdc\x2e\xc9\xef\x04\x29\xbc\xed\xc6\xb6\x47\x72\x9e\xa1\x68\x85\x8a\x6e\x49\xac\x10\x71\xe7\x06\xf4\xa5\xa6\x45\xca\x14\xe8\xc7\x74\x6d\x65\x51\x16\x20\x68\x2c\x90\x6c\x8b\x86\xec\x90\x1f\x3d\xde\xd4\x16\x7b\x3f\x00\xb0\x6c\xbf\xac\x6a\xee\x37\x28\x05\x1b\x3e\x5f\xf1\x0b\x4f\x9e\xd8\xbd\x0b\x8d\xa9\x43\x03\xc8\x33\x75\x5b\x3c\xa3\xae\xdd\xf0\xb5\x4b\xc8\xd6\x63\x21\x38\xb5\xd2\x5b\xab\x03\xd1\x7b\x34\x58\xa9\xd7\x82\x10\x80\x06\xf5\xbb\x7d\xe7\x5b\x5c\x0b\xa8\x54\xb4\x23\xd8\xbb\x80\x1e\x70\x1e\x99\xdc\x4f\xea\xad\x59\xbc\x1c\x71\x12\x45\x3b\x04\xd3\x3e\xa3\x63\x56\x39\xfb\x80\x2c\x73\xc2\xb7\x1d\x58\xa5\x6b\xbd\x67\x1b\x18\xfe\x34\xed\x2e\x3d\xca\x38\x82\x7d\x63\xfd\xb1\xd4\xfb\x32\x85\x40\x50\x04\xb2\xb3\xe2\x60\x81\xa8\xff\x08\xcd\x6d\x2b\x08\xf8\xe7\xb7\xe9\x0a\x2a\xb1\xed\x7a\x41\xb1\xd0\x12\x85\x22\xc2\xf8\xbf\xf5\x6a\x7f\xe6\x79\x69\x42\x2c\xe8\x39\xa9\xd4\x60\x8f\x03",
+       "\x6d\x03\x3d\x85\xda\xed\x33\x66\xd5\xf7\xd5\xe4\xf0\x3b\x3d\x05\xb6\x57\x78\xee\xea\x07\x4b\x0c\x68\x3c\xff\xcd\x6f\x51\xd5\xbd",
+       231 },
+      { GCRY_MD_SHA3_256,
+       "\x04\xe1\x6d\xed\xc1\x22\x79\x02\xba\xaf\x33\x2d\x3d\x08\x92\x36\x01\xbd\xd6\x4f\x57\x3f\xaa\x1b\xb7\x20\x19\x18\xcf\xe1\x6b\x1e\x10\x15\x1d\xae\x87\x5d\xa0\xc0\xd6\x3c\x59\xc3\xdd\x05\x0c\x4c\x6a\x87\x40\x11\xb0\x18\x42\x1a\xfc\x46\x23\xab\x03\x81\x83\x1b\x2d\xa2\xa8\xba\x42\xc9\x6e\x4f\x70\x86\x4a\xc4\x4e\x10\x6f\x94\x31\x10\x51\xe7\x4c\x77\xc1\x29\x1b\xf5\xdb\x95\x39\xe6\x95\x67\xbf\x6a\x11\xcf\x69\x32\xbb\xba\xd3\x3f\x89\x46\xbf\x58\x14\xc0\x66\xd8\x51\x63\x3d\x1a\x51\x35\x10\x03\x9b\x34\x99\x39\xbf\xd4\x2b\x85\x8c\x21\x82\x7c\x8f\xf0\x5f\x1d\x09\xb1\xb0\x76\x5d\xc7\x8a\x13\x5b\x5c\xa4\xdf\xba\x08\x01\xbc\xad\xdf\xa1\x75\x62\x3c\x8b\x64\x7e\xac\xfb\x44\x44\xb8\x5a\x44\xf7\x38\x90\x60\x7d\x06\xd5\x07\xa4\xf8\x39\x36\x58\x78\x86\x69\xf6\xef\x4d\xeb\x58\xd0\x8c\x50\xca\x07\x56\xd5\xe2\xf4\x9d\x1a\x7a\xd7\x3e\x0f\x0b\x3d\x3b\x5f\x09\x0a\xcf\x62\x2b\x18\x78\xc5\x91\x33\xe4\xa8\x48\xe0\x51\x53\x59\x2e\xa8\x1c\x6f\xbf",
+       "\x01\xeb\xbb\x73\x41\x0e\xeb\xac\x66\x5c\x3b\x40\x06\x3d\x00\x1f\x43\xdb\xe9\xd1\x72\x2e\xb3\x23\xfe\x08\x76\x3d\x7f\xf0\x61\x6c",
+       232 },
+      { GCRY_MD_SHA3_256,
+       "\x7c\x81\x5c\x38\x4e\xee\x0f\x28\x8e\xce\x27\xcc\xed\x52\xa0\x16\x03\x12\x7b\x07\x9c\x00\x73\x78\xbc\x5d\x1e\x6c\x5e\x9e\x6d\x1c\x73\x57\x23\xac\xbb\xd5\x80\x1a\xc4\x98\x54\xb2\xb5\x69\xd4\x47\x2d\x33\xf4\x0b\xbb\x88\x82\x95\x62\x45\xc3\x66\xdc\x35\x82\xd7\x16\x96\xa9\x7a\x4e\x19\x55\x7e\x41\xe5\x4d\xee\x48\x2a\x14\x22\x90\x05\xf9\x3a\xfd\x2c\x4a\x7d\x86\x14\xd1\x0a\x97\xa9\xdf\xa0\x7f\x7c\xd9\x46\xfa\x45\x26\x30\x63\xdd\xd2\x9d\xb8\xf9\xe3\x4d\xb6\x0d\xaa\x32\x68\x4f\x00\x72\xea\x2a\x94\x26\xec\xeb\xfa\x52\x39\xfb\x67\xf2\x9c\x18\xcb\xaa\x2a\xf6\xed\x4b\xf4\x28\x39\x36\x82\x3a\xc1\x79\x01\x64\xfe\xc5\x45\x7a\x9c\xba\x7c\x76\x7c\xa5\x93\x92\xd9\x4c\xab\x74\x48\xf5\x0e\xb3\x4e\x9a\x93\xa8\x00\x27\x47\x1c\xe5\x97\x36\xf0\x99\xc8\x86\xde\xa1\xab\x4c\xba\x4d\x89\xf5\xfc\x7a\xe2\xf2\x1c\xcd\x27\xf6\x11\xec\xa4\x62\x6b\x2d\x08\xdc\x22\x38\x2e\x92\xc1\xef\xb2\xf6\xaf\xdc\x8f\xdc\x3d\x21\x72\x60\x4f\x50\x35\xc4\x6b\x81\x97\xd3",
+       "\x8d\x3a\x49\xcb\x57\x2a\xb9\x9c\x9b\xf0\x23\x13\x66\xbb\x01\x7c\x9a\xdf\x25\x47\x9d\x35\x44\x3a\x97\x1e\x45\x78\x7e\x73\x8c\xe5",
+       233 },
+      { GCRY_MD_SHA3_256,
+       "\xe2\x9d\x50\x51\x58\xdb\xdd\x93\x7d\x9e\x3d\x21\x45\x65\x8e\xe6\xf5\x99\x2a\x2f\xc7\x90\xf4\xf6\x08\xd9\xcd\xb4\x4a\x09\x1d\x5b\x94\xb8\x8e\x81\xfa\xc4\xfd\xf5\xc4\x94\x42\xf1\x3b\x91\x1c\x55\x88\x64\x69\x62\x95\x51\x18\x9e\xaf\xf6\x24\x88\xf1\xa4\x79\xb7\xdb\x11\xa1\x56\x0e\x19\x8d\xdc\xcc\xcf\x50\x15\x90\x93\x42\x5f\xf7\xf1\xcb\x8d\x1d\x12\x46\xd0\x97\x87\x64\x08\x7d\x6b\xac\x25\x70\x26\xb0\x90\xef\xae\x8c\xec\x5f\x22\xb6\xf2\x1c\x59\xac\xe1\xac\x73\x86\xf5\xb8\x83\x7c\xa6\xa1\x2b\x6f\xbf\x55\x34\xdd\x05\x60\xef\x05\xca\x78\x10\x4d\x3b\x94\x3d\xdb\x22\x0f\xea\xec\x89\xaa\x5e\x69\x2a\x00\xf8\x22\xa2\xab\x9a\x2f\xe6\x03\x50\xd7\x5e\x7b\xe1\x6f\xf2\x52\x6d\xc6\x43\x87\x25\x02\xd0\x1f\x42\xf1\x88\xab\xed\x0a\x6e\x9a\x6f\x5f\xd0\xd1\xce\x7d\x57\x55\xc9\xff\xa6\x6b\x0a\xf0\xb2\x0b\xd8\x06\xf0\x8e\x06\x15\x66\x90\xd8\x1a\xc8\x11\x77\x8c\xa3\xda\xc2\xc2\x49\xb9\x60\x02\x01\x7f\xce\x93\xe5\x07\xe3\xb9\x53\xac\xf9\x99\x64\xb8\x47",
+       "\xfb\xb5\xa0\xab\x1a\x3b\x4c\x4f\xa5\x6a\xdb\x1c\x95\x31\xeb\x99\x79\xc5\x54\x90\x30\x53\x01\x3c\x20\xfe\xfd\x3f\x57\xb5\xcc\xdb",
+       234 },
+      { GCRY_MD_SHA3_256,
+       "\xd8\x55\x88\x69\x6f\x57\x6e\x65\xec\xa0\x15\x5f\x39\x5f\x0c\xfa\xcd\x83\xf3\x6a\x99\x11\x1e\xd5\x76\x8d\xf2\xd1\x16\xd2\x12\x1e\x32\x35\x7b\xa4\xf5\x4e\xde\x92\x7f\x18\x9f\x29\x7d\x3a\x97\xfa\xd4\xe9\xa0\xf5\xb4\x1d\x8d\x89\xdd\x7f\xe2\x01\x56\x79\x9c\x2b\x7b\x6b\xf9\xc9\x57\xba\x0d\x67\x63\xf5\xc3\xbc\x51\x29\x74\x7b\xbb\x53\x65\x2b\x49\x29\x0c\xff\x1c\x87\xe2\xcd\xf2\xc4\xb9\x5d\x8a\xae\xe0\x9b\xc8\xfb\xfa\x68\x83\xe6\x2d\x23\x78\x85\x81\x04\x91\xbf\xc1\x01\xf1\xd8\xc6\x36\xe3\xd0\xed\xe8\x38\xad\x05\xc2\x07\xa3\xdf\x4f\xad\x76\x45\x29\x79\xeb\x99\xf2\x9a\xfa\xec\xed\xd1\xc6\x3b\x8d\x36\xcf\x37\x84\x54\xa1\xbb\x67\xa7\x41\xc7\x7a\xc6\xb6\xb3\xf9\x5f\x4f\x02\xb6\x4d\xab\xc1\x54\x38\x61\x3e\xa4\x97\x50\xdf\x42\xee\x90\x10\x1f\x11\x5a\xa9\xab\xb9\xff\x64\x32\x4d\xde\x9d\xab\xbb\x01\x05\x4e\x1b\xd6\xb4\xbc\xdc\x79\x30\xa4\x4c\x23\x00\xd8\x7c\xa7\x8c\x06\x92\x4d\x03\x23\xad\x78\x87\xe4\x6c\x90\xe8\xc4\xd1\x00\xac\xd9\xee\xd2\x1e",
+       "\x6b\x3d\xcc\x7a\xc6\xa5\xcb\x85\xb6\x7f\xc7\x1b\x40\x55\xd3\x79\x81\x34\xde\xef\x26\xfd\x3e\xb0\x3a\x04\x2e\x0d\xaa\x35\xcc\x85",
+       235 },
+      { GCRY_MD_SHA3_256,
+       "\x3a\x12\xf8\x50\x8b\x40\xc3\x2c\x74\x49\x2b\x66\x32\x33\x75\xdc\xfe\x49\x18\x4c\x78\xf7\x31\x79\xf3\x31\x4b\x79\xe6\x33\x76\xb8\xac\x68\x3f\x5a\x51\xf1\x53\x4b\xd7\x29\xb0\x2b\x04\xd0\x02\xf5\x5c\xbd\x8e\x8f\xc9\xb5\xec\x1e\xa6\xbb\xe6\xa0\xd0\xe7\x43\x15\x18\xe6\xba\x45\xd1\x24\x03\x5f\x9d\x3d\xce\x0a\x8b\xb7\xbf\x14\x30\xa9\xf6\x57\xe0\xb4\xea\x9f\x20\xeb\x20\xc7\x86\xa5\x81\x81\xa1\xe2\x0a\x96\xf1\x62\x8f\x87\x28\xa1\x3b\xdf\x7a\x4b\x4b\x32\xfc\x8a\xa7\x05\x4c\xc4\x88\x1a\xe7\xfa\x19\xaf\xa6\x5c\x6c\x3e\xe1\xb3\xad\xe3\x19\x2a\xf4\x20\x54\xa8\xa9\x11\xb8\xec\x18\x26\x86\x5d\x46\xd9\x3f\x1e\x7c\x5e\x2b\x78\x13\xc9\x2a\x50\x6e\x53\x88\x6f\x3d\x47\x01\xbb\x93\xd2\xa6\x81\xad\x10\x9c\x84\x59\x04\xbb\x86\x1a\xf8\xaf\x06\x46\xb6\xe3\x99\xb3\x8b\x61\x40\x51\xd3\x4f\x68\x42\x56\x3a\x0f\x37\xec\x00\xcb\x3d\x86\x5f\xc5\xd7\x46\xc4\x98\x7d\xe2\xa6\x50\x71\x10\x08\x83\xa2\xa9\xc7\xa2\xbf\xe1\xe2\xdd\x60\x3d\x9e\xa2\x4d\xc7\xc5\xfd\x06\xbe",
+       "\x5d\x1d\xba\x8f\x15\x84\xac\x3f\x36\xb3\xac\x92\x5e\xc1\x3a\xc2\x84\x01\x3b\x96\x64\x96\x5a\xb6\x26\x5b\x94\x24\x66\xb5\xd8\xec",
+       236 },
+      { GCRY_MD_SHA3_256,
+       "\x18\x61\xed\xce\x46\xfa\x5a\xd1\x7e\x1f\xf1\xde\xae\x08\x4d\xec\x58\x0f\x97\xd0\xa6\x78\x85\xdf\xe8\x34\xb9\xdf\xac\x1a\xe0\x76\x74\x2c\xe9\xe2\x67\x51\x2c\xa5\x1f\x6d\xf5\xa4\x55\xaf\x0c\x5f\xd6\xab\xf9\x4a\xce\xa1\x03\xa3\x37\x0c\x35\x44\x85\xa7\x84\x6f\xb8\x4f\x3a\xc7\xc2\x90\x4b\x5b\x2f\xbf\x22\x70\x02\xce\x51\x21\x33\xbb\x7e\x1c\x4e\x50\x05\x7b\xfd\x1e\x44\xdb\x33\xc7\xcd\xb9\x69\xa9\x9e\x28\x4b\x18\x4f\x50\xa1\x4b\x06\x8a\x1f\xc5\x00\x9d\x9b\x29\x8d\xbe\x92\x23\x95\x72\xa7\x62\x7a\xac\x02\xab\xe8\xf3\xe3\xb4\x73\x41\x7f\x36\xd4\xd2\x50\x5d\x16\xb7\x57\x7f\x45\x26\xc9\xd9\x4a\x27\x0a\x2d\xfe\x45\x0d\x06\xda\x8f\x6f\xa9\x56\x87\x9a\x0a\x55\xcf\xe9\x9e\x74\x2e\xa5\x55\xea\x47\x7b\xa3\xe9\xb4\x4c\xcd\x50\x8c\x37\x54\x23\x61\x1a\xf9\x2e\x55\x34\x5d\xc2\x15\x77\x9b\x2d\x51\x19\xeb\xa4\x9c\x71\xd4\x9b\x9f\xe3\xf1\x56\x9f\xa2\x4e\x5c\xa3\xe3\x32\xd0\x42\x42\x2a\x8b\x81\x58\xd3\xec\x66\xa8\x00\x12\x97\x6f\x31\xff\xdf\x30\x5f\x0c\x9c\x5e",
+       "\x89\xc6\xc8\x6d\xb0\xa8\x89\xaa\x67\xd8\xcb\x08\x5f\x9f\x43\x12\x64\x59\x72\xd9\x77\xc5\xb9\x52\xd9\xf6\x24\x3d\x7d\x3b\xe4\xd5",
+       237 },
+      { GCRY_MD_SHA3_256,
+       "\x08\xd0\xff\xde\x3a\x6e\x4e\xf6\x56\x08\xea\x67\x2e\x48\x30\xc1\x29\x43\xd7\x18\x7c\xcf\xf0\x8f\x49\x41\xcf\xc1\x3e\x54\x5f\x3b\x9c\x7a\xd5\xee\xbb\xe2\xb0\x16\x42\xb4\x86\xca\xf8\x55\xc2\xc7\x3f\x58\xc1\xe4\xe3\x39\x1d\xa8\xe2\xd6\x3d\x96\xe1\x5f\xd8\x49\x53\xae\x5c\x23\x19\x11\xb0\x0a\xd6\x05\x0c\xd7\xaa\xfd\xaa\xc9\xb0\xf6\x63\xae\x6a\xab\x45\x51\x9d\x0f\x53\x91\xa5\x41\x70\x7d\x47\x90\x34\xe7\x3a\x6a\xd8\x05\xae\x35\x98\x09\x6a\xf0\x78\xf1\x39\x33\x01\x49\x3d\x66\x3d\xd7\x1f\x83\x86\x9c\xa2\x7b\xa5\x08\xb7\xe9\x1e\x81\xe1\x28\xc1\x71\x6d\xc3\xac\xfe\x30\x84\xb2\x20\x1e\x04\xcf\x80\x06\x61\x7e\xec\xf1\xb6\x40\x47\x4a\x5d\x45\xcf\xde\x9f\x4d\x3e\xf9\x2d\x6d\x05\x5b\x90\x98\x92\x19\x4d\x8a\x82\x18\xdb\x6d\x82\x03\xa8\x42\x61\xd2\x00\xd7\x14\x73\xd7\x48\x8f\x34\x27\x41\x6b\x68\x96\xc1\x37\xd4\x55\xf2\x31\x07\x1c\xac\xbc\x86\xe0\x41\x5a\xb8\x8a\xec\x84\x1d\x96\xb7\xb8\xaf\x41\xe0\x5b\xb4\x61\xa4\x06\x45\xbf\x17\x66\x01\xf1\xe7\x60\xde\x5f",
+       "\xac\x02\x43\x2a\x55\x41\xc2\x62\x38\xc6\xf9\x9f\xad\xb2\xb2\x3b\x5f\xfc\xad\x8f\x04\xbd\x4c\x3b\x9a\x66\x20\xca\xb1\x26\x6e\x6b",
+       238 },
+      { GCRY_MD_SHA3_256,
+       "\xd7\x82\xab\xb7\x2a\x5b\xe3\x39\x27\x57\xbe\x02\xd3\xe4\x5b\xe6\xe2\x09\x9d\x6f\x00\x0d\x04\x2c\x8a\x54\x3f\x50\xed\x6e\xbc\x05\x5a\x7f\x13\x3b\x0d\xd8\xe9\xbc\x34\x85\x36\xed\xca\xae\x2e\x12\xec\x18\xe8\x83\x7d\xf7\xa1\xb3\xc8\x7e\xc4\x6d\x50\xc2\x41\xde\xe8\x20\xfd\x58\x61\x97\x55\x2d\xc2\x0b\xee\xa5\x0f\x44\x5a\x07\xa3\x8f\x17\x68\xa3\x9e\x2b\x2f\xf0\x5d\xdd\xed\xf7\x51\xf1\xde\xf6\x12\xd2\xe4\xd8\x10\xda\xa3\xa0\xcc\x90\x45\x16\xf9\xa4\x3a\xf6\x60\x31\x53\x85\x17\x8a\x52\x9e\x51\xf8\xaa\xe1\x41\x80\x8c\x8b\xc5\xd7\xb6\x0c\xac\x26\xbb\x98\x4a\xc1\x89\x0d\x04\x36\xef\x78\x04\x26\xc5\x47\xe9\x4a\x7b\x08\xf0\x1a\xcb\xfc\x4a\x38\x25\xea\xe0\x4f\x52\x0a\x90\x16\xf2\xfb\x8b\xf5\x16\x5e\xd1\x27\x36\xfc\x71\xe3\x6a\x49\xa7\x36\x14\x73\x9e\xaa\x3e\xc8\x34\x06\x9b\x1b\x40\xf1\x35\x0c\x2b\x3a\xb8\x85\xc0\x2c\x64\x0b\x9f\x76\x86\xed\x5f\x99\x52\x7e\x41\xcf\xcd\x79\x6f\xe4\xc2\x56\xc9\x17\x31\x86\xc2\x26\x16\x9f\xf2\x57\x95\x4e\xbd\xa8\x1c\x0e\x5f\x99",
+       "\xf5\x5a\xa0\x1d\xea\xb1\x21\x48\xe3\x57\x59\xdb\x81\x8f\x10\x59\x35\x11\x65\xe9\xe6\xf9\x3d\x34\x2f\x0a\xbf\xca\x10\x2e\x08\x01",
+       239 },
+      { GCRY_MD_SHA3_256,
+       "\x5f\xce\x81\x09\xa3\x58\x57\x0e\x40\x98\x3e\x11\x84\xe5\x41\x83\x3b\xb9\x09\x1e\x28\x0f\x25\x8c\xfb\x14\x43\x87\xb0\x5d\x19\x0e\x43\x1c\xb1\x9b\xaa\x67\x27\x3b\xa0\xc5\x8a\xbe\x91\x30\x8e\x18\x44\xdc\xd0\xb3\x67\x8b\xaa\x42\xf3\x35\xf2\xfa\x05\x26\x7a\x02\x40\xb3\xc7\x18\xa5\x94\x2b\x3b\x3e\x3b\xfa\x98\xa5\x5c\x25\xa1\x46\x6e\x8d\x7a\x60\x37\x22\xcb\x2b\xbf\x03\xaf\xa5\x4c\xd7\x69\xa9\x9f\x31\x07\x35\xee\x5a\x05\xda\xe2\xc2\x2d\x39\x7b\xd9\x56\x35\xf5\x8c\x48\xa6\x7f\x90\xe1\xb7\x3a\xaf\xcd\x3f\x82\x11\x7f\x01\x66\x65\x78\x38\x69\x10\x05\xb1\x8d\xa6\xf3\x41\xd6\xe9\x0f\xc1\xcd\xb3\x52\xb3\x0f\xae\x45\xd3\x48\x29\x4e\x50\x1b\x63\x25\x2d\xe1\x47\x40\xf2\xb8\x5a\xe5\x29\x9d\xde\xc3\x17\x2d\xe8\xb6\xd0\xba\x21\x9a\x20\xa2\x3b\xb5\xe1\x0f\xf4\x34\xd3\x9d\xb3\xf5\x83\x30\x5e\x9f\x5c\x03\x9d\x98\x56\x9e\x37\x7b\x75\xa7\x0a\xb8\x37\xd1\xdf\x26\x9b\x8a\x4b\x56\x6f\x40\xbb\x91\xb5\x77\x45\x5f\xd3\xc3\x56\xc9\x14\xfa\x06\xb9\xa7\xce\x24\xc7\x31\x7a\x17\x2d",
+       "\x7c\x0b\xda\x7c\xb4\x2d\xad\xbd\x03\x7f\x50\xa5\xf2\x7e\x3a\xb5\xda\x25\x8d\x46\x70\xf1\xbe\xa9\x01\x54\xc8\x7c\x98\x13\x6b\xa1",
+       240 },
+      { GCRY_MD_SHA3_256,
+       "\x61\x72\xf1\x97\x1a\x6e\x1e\x4e\x61\x70\xaf\xba\xd9\x5d\x5f\xec\x99\xbf\x69\xb2\x4b\x67\x4b\xc1\x7d\xd7\x80\x11\x61\x5e\x50\x2d\xe6\xf5\x6b\x86\xb1\xa7\x1d\x3f\x43\x48\x08\x72\x18\xac\x7b\x7d\x09\x30\x29\x93\xbe\x27\x2e\x4a\x59\x19\x68\xae\xf1\x8a\x12\x62\xd6\x65\x61\x0d\x10\x70\xee\x91\xcc\x8d\xa3\x6e\x1f\x84\x1a\x69\xa7\xa6\x82\xc5\x80\xe8\x36\x94\x1d\x21\xd9\x09\xa3\xaf\xc1\xf0\xb9\x63\xe1\xca\x5a\xb1\x93\xe1\x24\xa1\xa5\x3d\xf1\xc5\x87\x47\x0e\x58\x81\xfb\x54\xda\xe1\xb0\xd8\x40\xf0\xc8\xf9\xd1\xb0\x4c\x64\x5b\xa1\x04\x1c\x7d\x8d\xbf\x22\x03\x0a\x62\x3a\xa1\x56\x38\xb3\xd9\x9a\x2c\x40\x0f\xf7\x6f\x32\x52\x07\x9a\xf8\x8d\x2b\x37\xf3\x5e\xe6\x6c\x1a\xd7\x80\x1a\x28\xd3\xd3\x88\xac\x45\x0b\x97\xd5\xf0\xf7\x9e\x45\x41\x75\x53\x56\xb3\xb1\xa5\x69\x6b\x02\x3f\x39\xab\x7a\xb5\xf2\x8d\xf4\x20\x29\x36\xbc\x97\x39\x3b\x93\xbc\x91\x5c\xb1\x59\xea\x1b\xd7\xa0\xa4\x14\xcb\x4b\x7a\x1a\xc3\xaf\x68\xf5\x0d\x79\xf0\xc9\xc7\x31\x4e\x75\x0f\x7d\x02\xfa\xa5\x8b\xfa",
+       "\xf6\x0c\x53\xba\x21\x32\x29\x3b\x88\x1f\x05\x13\xe7\xab\x47\xfe\x97\x46\xed\x4a\x6a\xc9\xca\xde\x61\xe6\xd8\x02\xd5\x87\x23\x72",
+       241 },
+      { GCRY_MD_SHA3_256,
+       "\x56\x68\xec\xd9\x9d\xfb\xe2\x15\xc4\x11\x83\x98\xac\x9c\x9e\xaf\x1a\x14\x33\xfa\xb4\xcc\xdd\x39\x68\x06\x47\x52\xb6\x25\xea\x94\x47\x31\xf7\x5d\x48\xa2\x7d\x04\x7d\x67\x54\x7f\x14\xdd\x0f\xfa\xa5\x5f\xa5\xe2\x9f\x7a\xf0\xd1\x61\xd8\x5e\xaf\xc4\xf2\x02\x9b\x71\x7c\x91\x8e\xab\x9d\x30\x45\x43\x29\x0b\xdb\xa7\x15\x8b\x68\x02\x0c\x0b\xa4\xe0\x79\xbc\x95\xb5\xbc\x0f\xc0\x44\xa9\x92\xb9\x4b\x4c\xcd\x3b\xd6\x6d\x0e\xab\xb5\xdb\xba\xb9\x04\xd6\x2e\x00\x75\x2c\x4e\x3b\x00\x91\xd7\x73\xbc\xf4\xc1\x4b\x43\x77\xda\x3e\xff\xf8\x24\xb1\xcb\x2f\xa0\x1b\x32\xd1\xe4\x6c\x90\x9e\x62\x6e\xd2\xda\xe9\x20\xf4\xc7\xdb\xeb\x63\x5b\xc7\x54\xfa\xcb\xd8\xd4\x9b\xeb\xa3\xf2\x3c\x1c\x41\xcc\xbf\xcd\x0e\xe0\xc1\x14\xe6\x97\x37\xf5\x59\x7c\x0b\xf1\xd8\x59\xf0\xc7\x67\xe1\x80\x02\xae\x8e\x39\xc2\x62\x61\xff\xde\x29\x20\xd3\xd0\xba\xf0\xe9\x06\x13\x86\x96\xcf\xe5\xb7\xe3\x2b\x60\x0f\x45\xdf\x3a\xaa\x39\x93\x2f\x3a\x7d\xf9\x5b\x60\xfa\x87\x12\xa2\x27\x1f\xca\xf3\x91\x1c\xe7\xb5\x11\xb1",
+       "\x1c\x66\xb9\xa7\xc5\x0e\xd7\x7d\x17\x9a\x0c\x43\x7d\x58\x90\xc9\x83\x5a\x13\xf9\x0a\x73\xa0\x13\x32\xab\x07\x31\xa4\x1a\x11\x5e",
+       242 },
+      { GCRY_MD_SHA3_256,
+       "\x03\xd6\x25\x48\x83\x54\xdf\x30\xe3\xf8\x75\xa6\x8e\xdf\xcf\x34\x0e\x83\x66\xa8\xe1\xab\x67\xf9\xd5\xc5\x48\x6a\x96\x82\x9d\xfa\xc0\x57\x82\x89\x08\x2b\x2a\x62\x11\x7e\x1c\xf4\x18\xb4\x3b\x90\xe0\xad\xc8\x81\xfc\x6a\xe8\x10\x5c\x88\x8e\x9e\xcd\x21\xae\xa1\xc9\xae\x1a\x40\x38\xdf\xd1\x73\x78\xfe\xd7\x1d\x02\xae\x49\x20\x87\xd7\xcd\xcd\x98\xf7\x46\x85\x52\x27\x96\x7c\xb1\xab\x47\x14\x26\x1e\xe3\xbe\xad\x3f\x4d\xb1\x18\x32\x9d\x3e\xbe\xf4\xbc\x48\xa8\x75\xc1\x9b\xa7\x63\x96\x6d\xa0\xeb\xea\x80\x0e\x01\xb2\xf5\x0b\x00\xe9\xdd\x4c\xac\xa6\xdc\xb3\x14\xd0\x01\x84\xef\x71\xea\x23\x91\xd7\x60\xc9\x50\x71\x0d\xb4\xa7\x0f\x92\x12\xff\xc5\x48\x61\xf9\xdc\x75\x2c\xe1\x88\x67\xb8\xad\x0c\x48\xdf\x84\x66\xef\x72\x31\xe7\xac\x56\x7f\x0e\xb5\x50\x99\xe6\x22\xeb\xb8\x6c\xb2\x37\x52\x01\x90\xa6\x1c\x66\xad\x34\xf1\xf4\xe2\x89\xcb\x32\x82\xae\x3e\xaa\xc6\x15\x2e\xd2\x4d\x2c\x92\xba\xe5\xa7\x65\x82\x52\xa5\x3c\x49\xb7\xb0\x2d\xfe\x54\xfd\xb2\xe9\x00\x74\xb6\xcf\x31\x0a\xc6\x61",
+       "\x48\xa0\x0b\xa2\x24\xac\x55\x58\xf4\x1a\x79\xf5\x21\x37\xdb\x91\x82\xa9\x3f\x10\x45\xd4\x37\x89\xe5\x91\x3d\x7b\xe4\x04\x08\xc2",
+       243 },
+      { GCRY_MD_SHA3_256,
+       "\x2e\xdc\x28\x2f\xfb\x90\xb9\x71\x18\xdd\x03\xaa\xa0\x3b\x14\x5f\x36\x39\x05\xe3\xcb\xd2\xd5\x0e\xcd\x69\x2b\x37\xbf\x00\x01\x85\xc6\x51\xd3\xe9\x72\x6c\x69\x0d\x37\x73\xec\x1e\x48\x51\x0e\x42\xb1\x77\x42\xb0\xb0\x37\x7e\x7d\xe6\xb8\xf5\x5e\x00\xa8\xa4\xdb\x47\x40\xce\xe6\xdb\x08\x30\x52\x9d\xd1\x96\x17\x50\x1d\xc1\xe9\x35\x9a\xa3\xbc\xf1\x47\xe0\xa7\x6b\x3a\xb7\x0c\x49\x84\xc1\x3e\x33\x9e\x68\x06\xbb\x35\xe6\x83\xaf\x85\x27\x09\x36\x70\x85\x9f\x3d\x8a\x0f\xc7\xd4\x93\xbc\xba\x6b\xb1\x2b\x5f\x65\xe7\x1e\x70\x5c\xa5\xd6\xc9\x48\xd6\x6e\xd3\xd7\x30\xb2\x6d\xb3\x95\xb3\x44\x77\x37\xc2\x6f\xad\x08\x9a\xa0\xad\x0e\x30\x6c\xb2\x8b\xf0\xac\xf1\x06\xf8\x9a\xf3\x74\x5f\x0e\xc7\x2d\x53\x49\x68\xcc\xa5\x43\xcd\x2c\xa5\x0c\x94\xb1\x45\x67\x43\x25\x4e\x35\x8c\x13\x17\xc0\x7a\x07\xbf\x2b\x0e\xca\x43\x8a\x70\x93\x67\xfa\xfc\x89\xa5\x72\x39\x02\x8f\xc5\xfe\xcf\xd5\x3b\x8e\xf9\x58\xef\x10\xee\x06\x08\xb7\xf5\xcb\x99\x23\xad\x97\x05\x8e\xc0\x67\x70\x0c\xc7\x46\xc1\x27\xa6\x1e\xe3",
+       "\x24\x0a\x85\xea\xf7\xf3\x01\x6c\x19\x2a\xd5\xe1\x7e\x5f\x93\xb6\x43\xfe\x3e\xdb\xa7\x19\xf4\x23\x69\x3a\x34\xda\x37\x84\x82\x7a",
+       244 },
+      { GCRY_MD_SHA3_256,
+       "\x90\xb2\x8a\x6a\xa1\xfe\x53\x39\x15\xbc\xb8\xe8\x1e\xd6\xca\xcd\xc1\x09\x62\xb7\xff\x82\x47\x4f\x84\x5e\xeb\x86\x97\x76\x00\xcf\x70\xb0\x7b\xa8\xe3\x79\x61\x41\xee\x34\x0e\x3f\xce\x84\x2a\x38\xa5\x0a\xfb\xe9\x03\x01\xa3\xbd\xcc\x59\x1f\x2e\x7d\x9d\xe5\x3e\x49\x55\x25\x56\x0b\x90\x8c\x89\x24\x39\x99\x0a\x2c\xa2\x67\x9c\x55\x39\xff\xdf\x63\x67\x77\xad\x9c\x1c\xde\xf8\x09\xcd\xa9\xe8\xdc\xdb\x45\x1a\xbb\x9e\x9c\x17\xef\xa4\x37\x9a\xbd\x24\xb1\x82\xbd\x98\x1c\xaf\xc7\x92\x64\x0a\x18\x3b\x61\x69\x43\x01\xd0\x4c\x5b\x3e\xaa\xd6\x94\xa6\xbd\x4c\xc0\x6e\xf5\xda\x8f\xa2\x3b\x4f\xa2\xa6\x45\x59\xc5\xa6\x83\x97\x93\x00\x79\xd2\x50\xc5\x1b\xcf\x00\xe2\xb1\x6a\x6c\x49\x17\x14\x33\xb0\xaa\xdf\xd8\x02\x31\x27\x65\x60\xb8\x04\x58\xdd\x77\x08\x9b\x7a\x1b\xbc\xc9\xe7\xe4\xb9\xf8\x81\xea\xcd\x6c\x92\xc4\x31\x83\x48\xa1\x3f\x49\x14\xeb\x27\x11\x5a\x1c\xfc\x5d\x16\xd7\xfd\x94\x95\x4c\x35\x32\xef\xac\xa2\xca\xb0\x25\x10\x3b\x2d\x02\xc6\xfd\x71\xda\x3a\x77\xf4\x17\xd7\x93\x26\x85\x88\x8a",
+       "\x2a\xa9\xd0\xa1\xd9\xb9\xb6\x91\xb4\xb8\x64\x1e\x68\xd4\x54\xd2\xd9\xc3\x4c\xe4\x3a\x5b\x55\xdd\x57\x59\x07\x16\xb8\xa4\x6c\xf7",
+       245 },
+      { GCRY_MD_SHA3_256,
+       "\x29\x69\x44\x7d\x17\x54\x90\xf2\xaa\x9b\xb0\x55\x01\x4d\xbe\xf2\xe6\x85\x4c\x95\xf8\xd6\x09\x50\xbf\xe8\xc0\xbe\x8d\xe2\x54\xc2\x6b\x2d\x31\xb9\xe4\xde\x9c\x68\xc9\xad\xf4\x9e\x4e\xe9\xb1\xc2\x85\x09\x67\xf2\x9f\x5d\x08\x73\x84\x83\xb4\x17\xbb\x96\xb2\xa5\x6f\x0c\x8a\xca\x63\x2b\x55\x20\x59\xc5\x9a\xac\x3f\x61\xf7\xb4\x5c\x96\x6b\x75\xf1\xd9\x93\x1f\xf4\xe5\x96\x40\x63\x78\xce\xe9\x1a\xaa\x72\x6a\x3a\x84\xc3\x3f\x37\xe9\xcd\xbe\x62\x6b\x57\x45\xa0\xb0\x60\x64\xa8\xa8\xd5\x6e\x53\xaa\xf1\x02\xd2\x3d\xd9\xdf\x0a\x3f\xdf\x7a\x63\x85\x09\xa6\x76\x1a\x33\xfa\x42\xfa\x8d\xdb\xd8\xe1\x61\x59\xc9\x30\x08\xb5\x37\x65\x01\x9c\x3f\x0e\x9f\x10\xb1\x44\xce\x2a\xc5\x7f\x5d\x72\x97\xf9\xc9\x94\x9e\x4f\xf6\x8b\x70\xd3\x39\xf8\x75\x01\xce\x85\x50\xb7\x72\xf3\x2c\x6d\xa8\xad\x2c\xe2\x10\x0a\x89\x5d\x8b\x08\xfa\x1e\xea\xd7\xc3\x76\xb4\x07\x70\x97\x03\xc5\x10\xb5\x0f\x87\xe7\x3e\x43\xf8\xe7\x34\x8f\x87\xc3\x83\x2a\x54\x7e\xf2\xbb\xe5\x79\x9a\xbe\xdc\xf5\xe1\xf3\x72\xea\x80\x92\x33\xf0\x06",
+       "\x58\xc4\x69\xe1\xa7\x68\x35\xcc\x1a\x89\x7b\x88\x5b\x1b\x2a\x33\xb0\xaa\xbc\xe4\xcf\xbb\x65\x52\x3d\x2e\x0d\x08\xd6\xd1\xa4\x13",
+       246 },
+      { GCRY_MD_SHA3_256,
+       "\x72\x16\x45\x63\x3a\x44\xa2\xc7\x8b\x19\x02\x4e\xae\xcf\x58\x57\x5a\xb2\x3c\x27\x19\x08\x33\xc2\x68\x75\xdc\x0f\x0d\x50\xb4\x6a\xea\x9c\x34\x3d\x82\xea\x7d\x5b\x3e\x50\xec\x70\x05\x45\xc6\x15\xda\xea\xea\x64\x72\x6a\x0f\x05\x60\x75\x76\xdc\xd3\x96\xd8\x12\xb0\x3f\xb6\x55\x1c\x64\x10\x87\x85\x6d\x05\x0b\x10\xe6\xa4\xd5\x57\x7b\x82\xa9\x8a\xfb\x89\xce\xe8\x59\x4c\x9d\xc1\x9e\x79\xfe\xff\x03\x82\xfc\xfd\x12\x7f\x1b\x80\x3a\x4b\x99\x46\xf4\xac\x9a\x43\x78\xe1\xe6\xe0\x41\xb1\x38\x9a\x53\xe3\x45\x0c\xd3\x2d\x9d\x29\x41\xb0\xcb\xab\xdb\x50\xda\x8e\xa2\x51\x31\x45\x16\x4c\x3a\xb6\xbc\xbd\x25\x1c\x44\x8d\x2d\x4b\x08\x7a\xc5\x7a\x59\xc2\x28\x5d\x56\x4f\x16\xda\x4e\xd5\xe6\x07\xed\x97\x95\x92\x14\x6f\xfb\x0e\xf3\xf3\xdb\x30\x8f\xb3\x42\xdf\x5e\xb5\x92\x4a\x48\x25\x6f\xc7\x63\x14\x1a\x27\x88\x14\xc8\x2d\x6d\x63\x48\x57\x75\x45\x87\x0a\xe3\xa8\x3c\x72\x30\xac\x02\xa1\x54\x0f\xe1\x79\x8f\x7e\xf0\x9e\x33\x5a\x86\x5a\x2a\xe0\x94\x9b\x21\xe4\xf7\x48\xfb\x8a\x51\xf4\x47\x50\xe2\x13\xa8\xfb",
+       "\x6c\x8d\xf8\x1b\x1e\x1e\xd7\x0a\x54\x13\x36\x80\x18\xdb\x96\x28\xb0\xe0\xb4\x56\x34\x23\xc0\x51\xa5\x4d\x00\x0a\xad\xde\x0c\x06",
+       247 },
+      { GCRY_MD_SHA3_256,
+       "\x6b\x86\x0d\x39\x72\x5a\x14\xb4\x98\xbb\x71\x45\x74\xb4\xd3\x7c\xa7\x87\x40\x47\x68\xf6\x4c\x64\x8b\x17\x51\xb3\x53\xac\x92\xba\xc2\xc3\xa2\x8e\xa9\x09\xfd\xf0\x42\x33\x36\x40\x1a\x02\xe6\x3e\xc2\x43\x25\x30\x0d\x82\x3b\x68\x64\xbb\x70\x1f\x9d\x7c\x7a\x1f\x8e\xc9\xd0\xae\x35\x84\xaa\x6d\xd6\x2e\xa1\x99\x7c\xd8\x31\xb4\xba\xbd\x9a\x4d\xa5\x09\x32\xd4\xef\xda\x74\x5c\x61\xe4\x13\x08\x90\xe1\x56\xae\xe6\x11\x37\x16\xda\xf9\x57\x64\x22\x2a\x91\x18\x7d\xb2\xef\xfe\xa4\x9d\x5d\x05\x96\x10\x2d\x61\x9b\xd2\x6a\x61\x6b\xbf\xda\x83\x35\x50\x5f\xbb\x0d\x90\xb4\xc1\x80\xd1\xa2\x33\x5b\x91\x53\x8e\x16\x68\xf9\xf9\x64\x27\x90\xb4\xe5\x5f\x9c\xab\x0f\xe2\xbd\xd2\x93\x5d\x00\x1e\xe6\x41\x9a\xba\xb5\x45\x78\x80\xd0\xdb\xff\x20\xed\x87\x58\xf4\xc2\x0f\xe7\x59\xef\xb3\x31\x41\xcf\x0e\x89\x25\x87\xfe\x81\x87\xe5\xfb\xc5\x77\x86\xb7\xe8\xb0\x89\x61\x2c\x93\x6d\xfc\x03\xd2\x7e\xfb\xbe\x7c\x86\x73\xf1\x60\x6b\xd5\x1d\x5f\xf3\x86\xf4\xa7\xab\x68\xed\xf5\x9f\x38\x5e\xb1\x29\x1f\x11\x7b\xfe\x71\x73\x99",
+       "\x10\x8f\xff\x41\xd5\xbc\xf6\x54\x07\x1b\x44\x14\xe6\x66\xfd\xeb\xbe\x87\x8c\x30\x9d\x6d\xdc\x90\xaf\xaf\x5c\x61\xdf\x85\x59\xf0",
+       248 },
+      { GCRY_MD_SHA3_256,
+       "\x6a\x01\x83\x0a\xf3\x88\x9a\x25\x18\x32\x44\xde\xcb\x50\x8b\xd0\x12\x53\xd5\xb5\x08\xab\x49\x0d\x31\x24\xaf\xbf\x42\x62\x6b\x2e\x70\x89\x4e\x9b\x56\x2b\x28\x8d\x0a\x24\x50\xcf\xac\xf1\x4a\x0d\xda\xe5\xc0\x47\x16\xe5\xa0\x08\x2c\x33\x98\x1f\x60\x37\xd2\x3d\x5e\x04\x5e\xe1\xef\x22\x83\xfb\x8b\x63\x78\xa9\x14\xc5\xd9\x44\x16\x27\xa7\x22\xc2\x82\xff\x45\x2e\x25\xa7\xea\x60\x8d\x69\xce\xe4\x39\x3a\x07\x25\xd1\x79\x63\xd0\x34\x26\x84\xf2\x55\x49\x6d\x8a\x18\xc2\x96\x11\x45\x31\x51\x30\x54\x93\x11\xfc\x07\xf0\x31\x2f\xb7\x8e\x60\x77\x33\x4f\x87\xea\xa8\x73\xbe\xe8\xaa\x95\x69\x89\x96\xeb\x21\x37\x5e\xb2\xb4\xef\x53\xc1\x44\x01\x20\x7d\xeb\x45\x68\x39\x8e\x5d\xd9\xa7\xcf\x97\xe8\xc9\x66\x3e\x23\x33\x4b\x46\x91\x2f\x83\x44\xc1\x9e\xfc\xf8\xc2\xba\x6f\x04\x32\x5f\x1a\x27\xe0\x62\xb6\x2a\x58\xd0\x76\x6f\xc6\xdb\x4d\x2c\x6a\x19\x28\x60\x4b\x01\x75\xd8\x72\xd1\x6b\x79\x08\xeb\xc0\x41\x76\x11\x87\xcc\x78\x55\x26\xc2\xa3\x87\x3f\xea\xc3\xa6\x42\xbb\x39\xf5\x35\x15\x50\xaf\x97\x70\xc3\x28\xaf\x7b",
+       "\x75\x1e\xaa\xaf\xa4\xae\xc8\xac\xd2\x66\x06\xd6\x43\x9c\x55\xb5\xc6\x6e\xc7\xdb\x80\x75\x79\xed\xc6\x89\x94\xb3\x00\xf7\xa0\x77",
+       249 },
+      { GCRY_MD_SHA3_256,
+       "\xb3\xc5\xe7\x4b\x69\x93\x3c\x25\x33\x10\x6c\x56\x3b\x4c\xa2\x02\x38\xf2\xb6\xe6\x75\xe8\x68\x1e\x34\xa3\x89\x89\x47\x85\xbd\xad\xe5\x96\x52\xd4\xa7\x3d\x80\xa5\xc8\x5b\xd4\x54\xfd\x1e\x9f\xfd\xad\x1c\x38\x15\xf5\x03\x8e\x9e\xf4\x32\xaa\xc5\xc3\xc4\xfe\x84\x0c\xc3\x70\xcf\x86\x58\x0a\x60\x11\x77\x8b\xbe\xda\xf5\x11\xa5\x1b\x56\xd1\xa2\xeb\x68\x39\x4a\xa2\x99\xe2\x6d\xa9\xad\xa6\xa2\xf3\x9b\x9f\xaf\xf7\xfb\xa4\x57\x68\x9b\x9c\x1a\x57\x7b\x2a\x1e\x50\x5f\xdf\x75\xc7\xa0\xa6\x4b\x1d\xf8\x1b\x3a\x35\x60\x01\xbf\x0d\xf4\xe0\x2a\x1f\xc5\x9f\x65\x1c\x9d\x58\x5e\xc6\x22\x4b\xb2\x79\xc6\xbe\xba\x29\x66\xe8\x88\x2d\x68\x37\x60\x81\xb9\x87\x46\x8e\x7a\xed\x1e\xf9\x0e\xbd\x09\x0a\xe8\x25\x79\x5c\xdc\xa1\xb4\xf0\x9a\x97\x9c\x8d\xfc\x21\xa4\x8d\x8a\x53\xcd\xbb\x26\xc4\xdb\x54\x7f\xc0\x6e\xfe\x2f\x98\x50\xed\xd2\x68\x5a\x46\x61\xcb\x49\x11\xf1\x65\xd4\xb6\x3e\xf2\x5b\x87\xd0\xa9\x6d\x3d\xff\x6a\xb0\x75\x89\x99\xaa\xd2\x14\xd0\x7b\xd4\xf1\x33\xa6\x73\x4f\xde\x44\x5f\xe4\x74\x71\x1b\x69\xa9\x8f\x7e\x2b",
+       "\x90\xc2\xd5\xf8\xe2\x6b\x0b\xdd\xea\x71\x90\x64\xbb\x02\xa6\x24\x2f\x2c\xc5\xa4\x29\x36\xb1\x4f\xe1\x7f\x86\x1b\x47\xb7\xe1\x86",
+       250 },
+      { GCRY_MD_SHA3_256,
+       "\x83\xaf\x34\x27\x9c\xcb\x54\x30\xfe\xbe\xc0\x7a\x81\x95\x0d\x30\xf4\xb6\x6f\x48\x48\x26\xaf\xee\x74\x56\xf0\x07\x1a\x51\xe1\xbb\xc5\x55\x70\xb5\xcc\x7e\xc6\xf9\x30\x9c\x17\xbf\x5b\xef\xdd\x7c\x6b\xa6\xe9\x68\xcf\x21\x8a\x2b\x34\xbd\x5c\xf9\x27\xab\x84\x6e\x38\xa4\x0b\xbd\x81\x75\x9e\x9e\x33\x38\x10\x16\xa7\x55\xf6\x99\xdf\x35\xd6\x60\x00\x7b\x5e\xad\xf2\x92\xfe\xef\xb7\x35\x20\x7e\xbf\x70\xb5\xbd\x17\x83\x4f\x7b\xfa\x0e\x16\xcb\x21\x9a\xd4\xaf\x52\x4a\xb1\xea\x37\x33\x4a\xa6\x64\x35\xe5\xd3\x97\xfc\x0a\x06\x5c\x41\x1e\xbb\xce\x32\xc2\x40\xb9\x04\x76\xd3\x07\xce\x80\x2e\xc8\x2c\x1c\x49\xbc\x1b\xec\x48\xc0\x67\x5e\xc2\xa6\xc6\xf3\xed\x3e\x5b\x74\x1d\x13\x43\x70\x95\x70\x7c\x56\x5e\x10\xd8\xa2\x0b\x8c\x20\x46\x8f\xf9\x51\x4f\xcf\x31\xb4\x24\x9c\xd8\x2d\xce\xe5\x8c\x0a\x2a\xf5\x38\xb2\x91\xa8\x7e\x33\x90\xd7\x37\x19\x1a\x07\x48\x4a\x5d\x3f\x3f\xb8\xc8\xf1\x5c\xe0\x56\xe5\xe5\xf8\xfe\xbe\x5e\x1f\xb5\x9d\x67\x40\x98\x0a\xa0\x6c\xa8\xa0\xc2\x0f\x57\x12\xb4\xcd\xe5\xd0\x32\xe9\x2a\xb8\x9f\x0a\xe1",
+       "\x32\x98\xa9\x5c\xfe\x59\xb9\xd6\xca\xb9\x9c\x36\xdc\x13\x24\x19\x4c\x09\xf9\x7f\x08\x94\x4a\x02\xd9\x57\x4b\xbc\xa3\x18\x6b\x41",
+       251 },
+      { GCRY_MD_SHA3_256,
+       "\xa7\xed\x84\x74\x9c\xcc\x56\xbb\x1d\xfb\xa5\x71\x19\xd2\x79\xd4\x12\xb8\xa9\x86\x88\x6d\x81\x0f\x06\x7a\xf3\x49\xe8\x74\x9e\x9e\xa7\x46\xa6\x0b\x03\x74\x26\x36\xc4\x64\xfc\x1e\xe2\x33\xac\xc5\x2c\x19\x83\x91\x46\x92\xb6\x43\x09\xed\xfd\xf2\x9f\x1a\xb9\x12\xec\x3e\x8d\xa0\x74\xd3\xf1\xd2\x31\x51\x1f\x57\x56\xf0\xb6\xee\xad\x3e\x89\xa6\xa8\x8f\xe3\x30\xa1\x0f\xac\xe2\x67\xbf\xfb\xfc\x3e\x30\x90\xc7\xfd\x9a\x85\x05\x61\xf3\x63\xad\x75\xea\x88\x1e\x72\x44\xf8\x0f\xf5\x58\x02\xd5\xef\x7a\x1a\x4e\x7b\x89\xfc\xfa\x80\xf1\x6d\xf5\x4d\x1b\x05\x6e\xe6\x37\xe6\x96\x4b\x9e\x0f\xfd\x15\xb6\x19\x6b\xdd\x7d\xb2\x70\xc5\x6b\x47\x25\x14\x85\x34\x8e\x49\x81\x3b\x4e\xb9\xed\x12\x2a\x01\xb3\xea\x45\xad\x5e\x1a\x92\x9d\xf6\x1d\x5c\x0f\x3e\x77\xe1\xfd\xc3\x56\xb6\x38\x83\xa6\x0e\x9c\xbb\x9f\xc3\xe0\x0c\x2f\x32\xdb\xd4\x69\x65\x98\x83\xf6\x90\xc6\x77\x2e\x33\x5f\x61\x7b\xc3\x3f\x16\x1d\x6f\x69\x84\x25\x2e\xe1\x2e\x62\xb6\x00\x0a\xc5\x23\x1e\x0c\x9b\xc6\x5b\xe2\x23\xd8\xdf\xd9\x4c\x50\x04\xa1\x01\xaf\x9f\xd6\xc0\xfb",
+       "\x1c\x41\x72\x92\x8c\xb1\x0e\x16\xab\x3c\xdb\x33\xf8\x15\x10\x3b\x00\x0a\x6c\x7d\x62\x37\x6c\xad\x29\xaf\x03\xf4\xb2\xb0\xe1\x03",
+       252 },
+      { GCRY_MD_SHA3_256,
+       "\xa6\xfe\x30\xdc\xfc\xda\x1a\x32\x9e\x82\xab\x50\xe3\x2b\x5f\x50\xeb\x25\xc8\x73\xc5\xd2\x30\x58\x60\xa8\x35\xae\xce\xe6\x26\x4a\xa3\x6a\x47\x42\x99\x22\xc4\xb8\xb3\xaf\xd0\x0d\xa1\x60\x35\x83\x0e\xdb\x89\x78\x31\xc4\xe7\xb0\x0f\x2c\x23\xfc\x0b\x15\xfd\xc3\x0d\x85\xfb\x70\xc3\x0c\x43\x1c\x63\x8e\x1a\x25\xb5\x1c\xaf\x1d\x7e\x8b\x05\x0b\x7f\x89\xbf\xb3\x0f\x59\xf0\xf2\x0f\xec\xff\x3d\x63\x9a\xbc\x42\x55\xb3\x86\x8f\xc4\x5d\xd8\x1e\x47\xeb\x12\xab\x40\xf2\xaa\xc7\x35\xdf\x5d\x1d\xc1\xad\x99\x7c\xef\xc4\xd8\x36\xb8\x54\xce\xe9\xac\x02\x90\x00\x36\xf3\x86\x7f\xe0\xd8\x4a\xff\xf3\x7b\xde\x33\x08\xc2\x20\x6c\x62\xc4\x74\x33\x75\x09\x41\x08\x87\x7c\x73\xb8\x7b\x25\x46\xfe\x05\xea\x13\x7b\xed\xfc\x06\xa2\x79\x62\x74\x09\x9a\x0d\x55\x4d\xa8\xf7\xd7\x22\x3a\x48\xcb\xf3\x1b\x7d\xec\xaa\x1e\xbc\x8b\x14\x57\x63\xe3\x67\x31\x68\xc1\xb1\xb7\x15\xc1\xcd\x99\xec\xd3\xdd\xb2\x38\xb0\x60\x49\x88\x5e\xca\xd9\x34\x7c\x24\x36\xdf\xf3\x2c\x77\x1f\x34\xa3\x85\x87\xa4\x4a\x82\xc5\xd3\xd1\x37\xa0\x3c\xaa\x27\xe6\x6c\x8f\xf6",
+       "\xf5\xcf\xb4\xdf\x3f\x7c\x5a\x77\x8f\x38\xa3\xb4\x3b\x26\x47\x9a\x0e\x8a\x49\x03\x0c\x59\xac\x19\xfb\x0c\xfa\x80\x60\x81\xca\x4a",
+       253 },
+      { GCRY_MD_SHA3_256,
+       "\x83\x16\x7f\xf5\x37\x04\xc3\xaa\x19\xe9\xfb\x33\x03\x53\x97\x59\xc4\x6d\xd4\x09\x1a\x52\xdd\xae\x9a\xd8\x64\x08\xb6\x93\x35\x98\x9e\x61\x41\x4b\xc2\x0a\xb4\xd0\x12\x20\xe3\x52\x41\xef\xf5\xc9\x52\x2b\x07\x9f\xba\x59\x76\x74\xc8\xd7\x16\xfe\x44\x1e\x56\x61\x10\xb6\x21\x15\x31\xce\xcc\xf8\xfd\x06\xbc\x8e\x51\x1d\x00\x78\x5e\x57\x78\x8e\xd9\xa1\xc5\xc7\x35\x24\xf0\x18\x30\xd2\xe1\x14\x8c\x92\xd0\xed\xc9\x71\x13\xe3\xb7\xb5\xcd\x30\x49\x62\x7a\xbd\xb8\xb3\x9d\xd4\xd6\x89\x0e\x0e\xe9\x19\x93\xf9\x2b\x03\x35\x4a\x88\xf5\x22\x51\xc5\x46\xe6\x44\x34\xd9\xc3\xd7\x45\x44\xf2\x3f\xb9\x3e\x5a\x2d\x2f\x1f\xb1\x55\x45\xb4\xe1\x36\x7c\x97\x33\x5b\x02\x91\x94\x4c\x8b\x73\x0a\xd3\xd4\x78\x92\x73\xfa\x44\xfb\x98\xd7\x8a\x36\xc3\xc3\x76\x4a\xbe\xea\xc7\xc5\x69\xc1\xe4\x3a\x35\x2e\x5b\x77\x0c\x35\x04\xf8\x70\x90\xde\xe0\x75\xa1\xc4\xc8\x5c\x0c\x39\xcf\x42\x1b\xdc\xc6\x15\xf9\xef\xf6\xcb\x4f\xe6\x46\x80\x04\xae\xce\x5f\x30\xe1\xec\xc6\xdb\x22\xad\x99\x39\xbb\x2b\x0c\xcc\x96\x52\x1d\xfb\xf4\xae\x00\x8b\x5b\x46\xbc\x00\x6e",
+       "\x06\xab\x8f\xdb\xe4\xdc\xe9\x35\xe4\x20\x03\xc1\x7f\xf6\x0b\xa2\x36\xf4\x3a\x84\x39\x95\xb7\xfe\xf3\xa2\x9d\xfe\x0c\x82\xf1\xd4",
+       254 },
+      { GCRY_MD_SHA3_256,
+       "\x3a\x3a\x81\x9c\x48\xef\xde\x2a\xd9\x14\xfb\xf0\x0e\x18\xab\x6b\xc4\xf1\x45\x13\xab\x27\xd0\xc1\x78\xa1\x88\xb6\x14\x31\xe7\xf5\x62\x3c\xb6\x6b\x23\x34\x67\x75\xd3\x86\xb5\x0e\x98\x2c\x49\x3a\xdb\xbf\xc5\x4b\x9a\x3c\xd3\x83\x38\x23\x36\xa1\xa0\xb2\x15\x0a\x15\x35\x8f\x33\x6d\x03\xae\x18\xf6\x66\xc7\x57\x3d\x55\xc4\xfd\x18\x1c\x29\xe6\xcc\xfd\xe6\x3e\xa3\x5f\x0a\xdf\x58\x85\xcf\xc0\xa3\xd8\x4a\x2b\x2e\x4d\xd2\x44\x96\xdb\x78\x9e\x66\x31\x70\xce\xf7\x47\x98\xaa\x1b\xbc\xd4\x57\x4e\xa0\xbb\xa4\x04\x89\xd7\x64\xb2\xf8\x3a\xad\xc6\x6b\x14\x8b\x4a\x0c\xd9\x52\x46\xc1\x27\xd5\x87\x1c\x4f\x11\x41\x86\x90\xa5\xdd\xf0\x12\x46\xa0\xc8\x0a\x43\xc7\x00\x88\xb6\x18\x36\x39\xdc\xfd\xa4\x12\x5b\xd1\x13\xa8\xf4\x9e\xe2\x3e\xd3\x06\xfa\xac\x57\x6c\x3f\xb0\xc1\xe2\x56\x67\x1d\x81\x7f\xc2\x53\x4a\x52\xf5\xb4\x39\xf7\x2e\x42\x4d\xe3\x76\xf4\xc5\x65\xcc\xa8\x23\x07\xdd\x9e\xf7\x6d\xa5\xb7\xc4\xeb\x7e\x08\x51\x72\xe3\x28\x80\x7c\x02\xd0\x11\xff\xbf\x33\x78\x53\x78\xd7\x9d\xc2\x66\xf6\xa5\xbe\x6b\xb0\xe4\xa9\x2e\xce\xeb\xae\xb1",
+       "\xc1\x1f\x35\x22\xa8\xfb\x7b\x35\x32\xd8\x0b\x6d\x40\x02\x3a\x92\xb4\x89\xad\xda\xd9\x3b\xf5\xd6\x4b\x23\xf3\x5e\x96\x63\x52\x1c",
+       255 },
diff --git a/tests/sha3-384.h b/tests/sha3-384.h
new file mode 100644 (file)
index 0000000..6733ca3
--- /dev/null
@@ -0,0 +1,1025 @@
+/* Generated from https://raw.githubusercontent.com/gvanas/KeccakCodePackage/master/TestVectors/ShortMsgKAT_SHA3-384.txt */
+      { GCRY_MD_SHA3_384,
+       "",
+       "\x0c\x63\xa7\x5b\x84\x5e\x4f\x7d\x01\x10\x7d\x85\x2e\x4c\x24\x85\xc5\x1a\x50\xaa\xaa\x94\xfc\x61\x99\x5e\x71\xbb\xee\x98\x3a\x2a\xc3\x71\x38\x31\x26\x4a\xdb\x47\xfb\x6b\xd1\xe0\x58\xd5\xf0\x04",
+       0 },
+      { GCRY_MD_SHA3_384,
+       "\xcc",
+       "\x5e\xe7\xf3\x74\x97\x3c\xd4\xbb\x3d\xc4\x1e\x30\x81\x34\x67\x98\x49\x7f\xf6\xe3\x6c\xb9\x35\x22\x81\xdf\xe0\x7d\x07\xfc\x53\x0c\xa9\xad\x8e\xf7\xaa\xd5\x6e\xf5\xd4\x1b\xe8\x3d\x5e\x54\x38\x07",
+       1 },
+      { GCRY_MD_SHA3_384,
+       "\x41\xfb",
+       "\x1d\xd8\x16\x09\xdc\xc2\x90\xef\xfd\x7a\xc0\xa9\x5d\x4a\x20\x82\x15\x80\xe5\x6b\xd5\x0d\xbd\x84\x39\x20\x65\x0b\xe7\xa8\x0a\x17\x19\x57\x7d\xa3\x37\xcf\xdf\x86\xe5\x1c\x76\x4c\xaa\x2e\x10\xbd",
+       2 },
+      { GCRY_MD_SHA3_384,
+       "\x1f\x87\x7c",
+       "\x14\xf6\xf4\x86\xfb\x98\xed\x46\xa4\xa1\x98\x04\x0d\xa8\x07\x9e\x79\xe4\x48\xda\xac\xeb\xe9\x05\xfb\x4c\xf0\xdf\x86\xef\x2a\x71\x51\xf6\x2f\xe0\x95\xbf\x85\x16\xeb\x06\x77\xfe\x60\x77\x34\xe2",
+       3 },
+      { GCRY_MD_SHA3_384,
+       "\xc1\xec\xfd\xfc",
+       "\xd9\x2b\xbd\x60\x4b\xdd\x24\xb9\x88\x95\x08\xf8\x55\x8b\x13\xe9\x65\x95\xac\x90\xbc\x8a\x44\x1d\xaf\x9b\x51\xd6\xab\xc1\x4f\xfd\x08\x35\xfb\x93\x66\xe3\x91\x25\x04\x26\x4c\xe8\x7e\x42\x1c\xb8",
+       4 },
+      { GCRY_MD_SHA3_384,
+       "\x21\xf1\x34\xac\x57",
+       "\xe2\x48\xd6\xff\x34\x2d\x35\xa3\x0e\xc2\x30\xba\x51\xcd\xb1\x61\x02\x5d\x6f\x1c\x25\x1a\xca\x6a\xe3\x53\x1f\x06\x82\xc1\x64\xa1\xfc\x07\x25\xb1\xbe\xff\x80\x8a\x20\x0c\x13\x15\x57\xa2\x28\x09",
+       5 },
+      { GCRY_MD_SHA3_384,
+       "\xc6\xf5\x0b\xb7\x4e\x29",
+       "\xd6\xdd\x2e\xd0\x8c\x1f\x64\x48\x57\xa1\x5d\xaf\xaf\x80\x53\x8b\xee\x59\x72\x78\xc9\xab\xe0\x47\xbf\xba\xbf\xb8\xb1\xfc\xb7\x54\x3e\x80\xae\x9f\x71\x43\xd0\x0f\x4d\xaa\xf3\x9b\x13\x8a\xb3\xff",
+       6 },
+      { GCRY_MD_SHA3_384,
+       "\x11\x97\x13\xcc\x83\xee\xef",
+       "\x49\xca\x1e\xb8\xd7\x1d\x1f\xdc\x7a\x72\xda\xa3\x20\xc8\xf9\xca\x54\x36\x71\xc2\xcb\x8f\xe9\xb2\x63\x8a\x84\x16\xdf\x50\xa7\x90\xa5\x0d\x0b\xb6\xb8\x87\x41\xd7\x81\x6d\x60\x61\xf4\x6a\xea\x89",
+       7 },
+      { GCRY_MD_SHA3_384,
+       "\x4a\x4f\x20\x24\x84\x51\x25\x26",
+       "\x89\xdb\xf4\xc3\x9b\x8f\xb4\x6f\xdf\x0a\x69\x26\xce\xc0\x35\x5a\x4b\xdb\xf9\xc6\xa4\x46\xe1\x40\xb7\xc8\xbd\x08\xff\x6f\x48\x9f\x20\x5d\xaf\x8e\xff\xe1\x60\xf4\x37\xf6\x74\x91\xef\x89\x7c\x23",
+       8 },
+      { GCRY_MD_SHA3_384,
+       "\x1f\x66\xab\x41\x85\xed\x9b\x63\x75",
+       "\xd6\x15\x46\x41\xd7\xd9\xdf\x62\xf0\xce\xdc\x2b\xd6\x4e\xe8\x24\x12\xb3\xa8\x0f\x6e\xac\xe7\xc4\x5f\x97\x03\x37\x33\x79\x00\x7e\xab\xf5\x92\xd2\xd2\x11\x6e\x09\x3d\xc3\x3d\xcb\xba\x46\x49\xe9",
+       9 },
+      { GCRY_MD_SHA3_384,
+       "\xee\xd7\x42\x22\x27\x61\x3b\x6f\x53\xc9",
+       "\x2e\xe5\xdf\x25\x91\xcf\xc4\xcb\x1e\x1d\x0b\xd8\xb2\x87\x27\xf0\xfa\x53\x59\xa7\x5f\x78\x19\xa9\x2a\x3c\xb8\x0d\xdb\x57\x08\xe4\x70\x51\x77\xb9\x81\x39\x6b\x48\x18\xd1\x1e\x3c\xa6\x15\xec\x93",
+       10 },
+      { GCRY_MD_SHA3_384,
+       "\xea\xee\xd5\xcd\xff\xd8\x9d\xec\xe4\x55\xf1",
+       "\x78\x6c\x3f\x73\xfb\x09\x2b\xe1\x84\xfc\x2b\x19\xf5\x92\x0f\x3d\x94\xf2\x5d\x45\x23\x16\x5a\xe8\x2f\x9b\x39\xb2\xc7\x24\xfd\x62\xdc\x9a\x32\x63\x09\x1a\x23\x9d\x5e\xf1\xad\x56\x2d\xd4\xfd\x26",
+       11 },
+      { GCRY_MD_SHA3_384,
+       "\x5b\xe4\x3c\x90\xf2\x29\x02\xe4\xfe\x8e\xd2\xd3",
+       "\x79\x18\x81\x39\xec\x2c\xad\x8d\x19\x7d\x30\x8b\x80\x6c\xf3\x83\x78\x2c\x29\xa8\xc2\x7e\xe2\x9c\x5e\x31\x42\x5b\x2d\xd1\x8b\x2f\x5f\x49\x1f\xbf\xb3\x8d\x70\x78\xf5\x85\x10\x12\x5c\x06\x4a\x0a",
+       12 },
+      { GCRY_MD_SHA3_384,
+       "\xa7\x46\x27\x32\x28\x12\x2f\x38\x1c\x3b\x46\xe4\xf1",
+       "\x0c\x82\xb8\xc7\x5c\x5d\x54\x0e\x7d\x62\x49\x28\x28\x1f\xba\x8b\x8d\x0b\x15\x83\xd7\x4f\x3f\x0e\xa4\xf2\x00\xf1\xce\x54\x75\x14\x9c\x28\x2e\x05\xdb\x69\x5d\xc6\x7b\xaf\x42\xde\xff\xdc\x3f\x55",
+       13 },
+      { GCRY_MD_SHA3_384,
+       "\x3c\x58\x71\xcd\x61\x9c\x69\xa6\x3b\x54\x0e\xb5\xa6\x25",
+       "\x83\x0d\x23\x25\xc0\x01\x62\x3e\xdf\xea\x97\xea\x1d\x0e\x65\x98\x2d\x4e\xd7\xab\xb8\xe6\x4e\xa6\x1c\x85\xe9\xbc\x18\x82\xd1\x1f\xc4\x15\x3c\x30\xbe\x63\xfc\x66\xf5\xfb\xce\x74\xbb\x39\x45\x96",
+       14 },
+      { GCRY_MD_SHA3_384,
+       "\xfa\x22\x87\x4b\xcc\x06\x88\x79\xe8\xef\x11\xa6\x9f\x07\x22",
+       "\x1d\xbe\x1b\xc6\x0a\x9c\x6f\xbe\x10\xa7\x27\xe2\xa6\xd3\x97\x93\x0d\x54\x7a\xd2\xc3\x90\x28\x69\x48\xc3\x16\x7e\xe7\x7f\xf6\xe2\x75\xec\x84\x31\xc5\xad\x4b\x4e\x4e\x5a\xe6\x7a\x4b\xc8\x8d\x05",
+       15 },
+      { GCRY_MD_SHA3_384,
+       "\x52\xa6\x08\xab\x21\xcc\xdd\x8a\x44\x57\xa5\x7e\xde\x78\x21\x76",
+       "\xfe\xee\x2e\xf3\x32\x51\x52\x84\xe0\xba\x24\x7c\x62\xf2\x64\x19\x90\x44\xd0\x38\x77\xc5\x8e\x54\xb5\x1a\x62\xe3\x9e\x91\xc2\x7a\xaa\xe3\x84\x83\x7e\xb9\xd4\x79\xb4\xc0\x30\x8c\xfc\x6b\x77\x9b",
+       16 },
+      { GCRY_MD_SHA3_384,
+       "\x82\xe1\x92\xe4\x04\x3d\xdc\xd1\x2e\xcf\x52\x96\x9d\x0f\x80\x7e\xed",
+       "\x18\x88\xe9\x53\x72\x7c\xb8\x37\xde\x40\xc6\x98\x69\x56\x0c\x20\x72\x9c\x50\x63\x8e\x45\x61\xb3\x85\x93\x7b\xfc\x4c\x29\x7e\x78\x9e\xa6\xc0\x3e\xfc\xf2\xdf\x32\x90\xb1\xfd\x36\xbe\x26\x8c\x32",
+       17 },
+      { GCRY_MD_SHA3_384,
+       "\x75\x68\x3d\xcb\x55\x61\x40\xc5\x22\x54\x3b\xb6\xe9\x09\x8b\x21\xa2\x1e",
+       "\x30\xde\x7b\x54\x42\x65\x42\x2c\xe6\x89\xe6\x67\xf4\x84\x98\xf4\x55\xe8\xbf\x10\x55\x65\x3f\x21\x29\x4e\xad\x7d\x2e\x89\x8b\x05\xfa\x75\xee\xca\x46\xdc\x25\x75\xc4\x75\xc4\x80\xaa\x49\xca\x62",
+       18 },
+      { GCRY_MD_SHA3_384,
+       "\x06\xe4\xef\xe4\x50\x35\xe6\x1f\xaa\xf4\x28\x7b\x4d\x8d\x1f\x12\xca\x97\xe5",
+       "\x04\x1b\x7c\x89\xbd\x4b\x58\x2a\x7d\x20\xe5\x79\xc6\xfd\xb1\x8b\xa0\xc1\x25\x1d\xab\xac\xc6\x87\xaf\x44\x8e\xb4\x91\x51\xbb\xc0\x4a\xdc\xb8\x1d\x79\x7d\x4b\xc5\x1f\x03\xbf\xff\x23\x0f\xfc\xc6",
+       19 },
+      { GCRY_MD_SHA3_384,
+       "\xe2\x61\x93\x98\x9d\x06\x56\x8f\xe6\x88\xe7\x55\x40\xae\xa0\x67\x47\xd9\xf8\x51",
+       "\xea\xf7\x51\xee\x6e\x75\xaa\x2c\x56\x45\x3f\x31\x6c\x01\x9b\xda\x7d\x7a\xe1\xfd\xa0\x3b\x79\xac\x41\x3b\xb1\xf2\x84\x0d\x58\xaa\xaa\xc7\x7f\x2d\xc1\x06\xd2\x2f\x1a\x71\x15\x7f\x9f\x84\x1c\x4b",
+       20 },
+      { GCRY_MD_SHA3_384,
+       "\xd8\xdc\x8f\xde\xfb\xdc\xe9\xd4\x4e\x4c\xba\xfe\x78\x44\x7b\xae\x3b\x54\x36\x10\x2a",
+       "\x16\xc4\xa7\xf7\xe8\xba\x7e\xa1\x3c\x59\x57\x6b\xe6\x02\xf8\x85\xe2\x1b\xe7\xc3\x4b\x3a\xc0\x5c\xac\x42\x62\xba\xad\x8a\xa3\xf9\x5b\xd9\x26\x0f\x13\xf0\x85\x50\xce\x33\x1e\xc7\x73\xba\x75\x8c",
+       21 },
+      { GCRY_MD_SHA3_384,
+       "\x57\x08\x5f\xd7\xe1\x42\x16\xab\x10\x2d\x83\x17\xb0\xcb\x33\x8a\x78\x6d\x5f\xc3\x2d\x8f",
+       "\x51\x19\xa4\xfc\x11\xda\xf2\xef\x5d\xeb\x7a\xeb\x35\x54\x91\x62\xd9\xaf\xc8\x27\x39\x2a\x88\x68\xe7\xf8\x59\x4a\x5c\x19\x4d\x9c\x8f\x6a\x43\x0c\xb3\x86\xb8\xd8\x25\xcc\x6d\xab\x4e\xdb\x74\x2a",
+       22 },
+      { GCRY_MD_SHA3_384,
+       "\xa0\x54\x04\xdf\x5d\xbb\x57\x69\x7e\x2c\x16\xfa\x29\xde\xfa\xc8\xab\x35\x60\xd6\x12\x6f\xa0",
+       "\xa9\x1f\x01\x70\x45\x7e\x78\xb3\xbb\x15\xb0\xbd\xc0\xff\x4e\xfe\x8d\x73\x13\xd2\x72\x5d\x8e\x8d\xb8\x75\xbc\xaf\xbc\x11\x31\x41\x26\x55\x9f\x45\xe8\x6e\x78\x13\x6e\xb2\x14\xff\x02\x76\x4c\xab",
+       23 },
+      { GCRY_MD_SHA3_384,
+       "\xae\xcb\xb0\x27\x59\xf7\x43\x3d\x6f\xcb\x06\x96\x3c\x74\x06\x1c\xd8\x3b\x5b\x3f\xfa\x6f\x13\xc6",
+       "\x98\xfe\x81\x74\x6c\xcf\x7c\xfe\x55\x71\xd6\xd8\xb0\x99\x43\xec\xae\x44\xf6\x06\x44\x4f\x9d\xab\xf1\xa5\x7f\xe4\xe8\x71\xf6\x96\x22\x66\xd1\x86\x52\xfd\x4e\xeb\xdb\xe4\x92\xcf\xc5\xb2\xb2\x1f",
+       24 },
+      { GCRY_MD_SHA3_384,
+       "\xaa\xfd\xc9\x24\x3d\x3d\x4a\x09\x65\x58\xa3\x60\xcc\x27\xc8\xd8\x62\xf0\xbe\x73\xdb\x5e\x88\xaa\x55",
+       "\x3d\xd9\x05\x4c\x10\x5c\x40\x79\x8d\xf4\x5c\xfb\x58\x80\xf9\x7a\x95\x36\xfa\x7b\xd1\x3f\x1d\x81\x6b\x8e\xe8\x87\xfc\xba\xfc\x10\x2a\x7d\x4b\xde\x9f\xe6\xe2\x65\x53\x8e\xec\x25\x25\xb5\x0d\x89",
+       25 },
+      { GCRY_MD_SHA3_384,
+       "\x7b\xc8\x48\x67\xf6\xf9\xe9\xfd\xc3\xe1\x04\x6c\xae\x3a\x52\xc7\x7e\xd4\x85\x86\x0e\xe2\x60\xe3\x0b\x15",
+       "\xde\xcd\x77\x8b\x89\xb4\x29\x50\x72\xdb\xf9\x86\x89\xe2\xeb\x60\x66\xe4\x06\x35\x6e\xa4\xb7\xca\xd5\x50\x01\x9f\x4a\x2a\xbb\x25\x16\x3e\x95\x71\xd0\xad\xb9\xad\xc6\xa8\x02\xb7\xe0\x3c\x15\x2c",
+       26 },
+      { GCRY_MD_SHA3_384,
+       "\xfa\xc5\x23\x57\x5a\x99\xec\x48\x27\x9a\x7a\x45\x9e\x98\xff\x90\x19\x18\xa4\x75\x03\x43\x27\xef\xb5\x58\x43",
+       "\x37\xf1\x4b\x31\x7d\x46\xbd\xb3\xe5\xdd\x6f\x68\x98\x6a\x08\xa0\x98\xc4\x6b\x9d\x85\xd1\xf2\x54\xa1\x78\x78\xc0\x08\xf9\x79\x26\xc8\xa1\x3c\x38\x38\x72\x1c\xfe\x3a\x58\x07\x6f\x39\x92\xf2\x6c",
+       27 },
+      { GCRY_MD_SHA3_384,
+       "\x0f\x8b\x2d\x8f\xcf\xd9\xd6\x8c\xff\xc1\x7c\xcf\xb1\x17\x70\x9b\x53\xd2\x64\x62\xa3\xf3\x46\xfb\x7c\x79\xb8\x5e",
+       "\x64\x1a\x7a\xf1\x3b\x88\x9d\x1a\x0f\x1a\xa3\xe4\xe4\xff\x8c\xc5\x90\x3c\x47\xe1\xa5\x2b\xde\xa2\x57\xd8\x0e\x37\xe5\x96\x56\x4a\xb3\x3e\xea\xd0\x67\x17\xcd\xb6\xb7\x06\xcb\x69\x86\x29\x3d\x4f",
+       28 },
+      { GCRY_MD_SHA3_384,
+       "\xa9\x63\xc3\xe8\x95\xff\x5a\x0b\xe4\x82\x44\x00\x51\x8d\x81\x41\x2f\x87\x5f\xa5\x05\x21\xe2\x6e\x85\xea\xc9\x0c\x04",
+       "\x12\x2b\x8b\x86\x10\x3f\xe3\xc1\x8f\xf2\x81\x78\xa2\x56\xac\xb0\xca\xb8\x51\x83\x38\xd2\xcb\xa6\x97\xe3\xf5\x60\xec\xfe\xe0\x9b\x02\x4b\x97\xd8\xd1\xf6\x96\x32\xad\x1f\x2c\x5f\x56\x28\xd3\xef",
+       29 },
+      { GCRY_MD_SHA3_384,
+       "\x03\xa1\x86\x88\xb1\x0c\xc0\xed\xf8\x3a\xdf\x0a\x84\x80\x8a\x97\x18\x38\x3c\x40\x70\xc6\xc4\xf2\x95\x09\x86\x99\xac\x2c",
+       "\xf3\x5a\x29\x2e\x19\x70\x07\xe2\x8c\xe6\x52\xa0\x67\x17\x3f\x36\x59\xc5\x1b\x70\x43\x8a\xa9\xe4\x33\x08\x1d\x3d\xf7\x1b\x4a\x11\xe3\xf3\xbe\x5a\xf3\x2e\x2c\x08\xd2\x3a\x0b\x44\xe3\x0b\x0b\xdf",
+       30 },
+      { GCRY_MD_SHA3_384,
+       "\x84\xfb\x51\xb5\x17\xdf\x6c\x5a\xcc\xb5\xd0\x22\xf8\xf2\x8d\xa0\x9b\x10\x23\x2d\x42\x32\x0f\xfc\x32\xdb\xec\xc3\x83\x5b\x29",
+       "\x2e\xa5\x96\xb4\x46\xd5\xcc\xd8\xf0\x92\x7a\x2e\x37\x90\x91\x1e\x00\xf1\xf5\x2c\xfb\xfc\x41\xf1\x22\x90\xcb\xac\xd1\xc9\x03\xc7\x4d\xee\xf8\x40\xfd\x13\x98\xe1\x2e\xe8\x63\xac\xd9\x2b\xae\xbf",
+       31 },
+      { GCRY_MD_SHA3_384,
+       "\x9f\x2f\xcc\x7c\x90\xde\x09\x0d\x6b\x87\xcd\x7e\x97\x18\xc1\xea\x6c\xb2\x11\x18\xfc\x2d\x5d\xe9\xf9\x7e\x5d\xb6\xac\x1e\x9c\x10",
+       "\xba\xae\x7a\xae\xd4\xfb\xf4\x2f\x93\x16\xc7\xe8\xf7\x22\xee\xb0\x6a\x59\x8b\x50\x9f\x18\x4b\x22\xfb\xd5\xa8\x1c\x93\xd9\x5f\xff\x71\x1f\x5d\xe9\x08\x47\xb3\x24\x8b\x6d\xf7\x6c\xab\xce\x07\xee",
+       32 },
+      { GCRY_MD_SHA3_384,
+       "\xde\x8f\x1b\x3f\xaa\x4b\x70\x40\xed\x45\x63\xc3\xb8\xe5\x98\x25\x31\x78\xe8\x7e\x4d\x0d\xf7\x5e\x4f\xf2\xf2\xde\xdd\x5a\x0b\xe0\x46",
+       "\x32\xcf\xc8\xa1\x8a\x71\x16\xd4\xb9\x02\x90\x51\x94\x18\x08\xc3\xb3\x32\xef\xdb\x13\x2c\x51\x5f\x91\x10\xe1\x9b\x83\x54\x35\x5d\x94\x61\x6c\x99\x65\xbc\x2d\x1f\x24\x89\xf8\x45\x2a\xf7\xfb\x2f",
+       33 },
+      { GCRY_MD_SHA3_384,
+       "\x62\xf1\x54\xec\x39\x4d\x0b\xc7\x57\xd0\x45\xc7\x98\xc8\xb8\x7a\x00\xe0\x65\x5d\x04\x81\xa7\xd2\xd9\xfb\x58\xd9\x3a\xed\xc6\x76\xb5\xa0",
+       "\x73\x44\x3e\xa3\x8a\x88\x01\x39\x5c\x04\x4e\x3c\xbe\xcd\x45\xdd\x62\xd6\xe3\x04\xc5\x44\x0f\xa9\xfe\x96\x51\xa4\x38\xc0\x10\xa7\x67\x12\x75\x9b\xe2\x06\x81\xf1\x41\x66\x61\xe7\x46\xe5\xeb\x77",
+       34 },
+      { GCRY_MD_SHA3_384,
+       "\xb2\xdc\xfe\x9f\xf1\x9e\x2b\x23\xce\x7d\xa2\xa4\x20\x7d\x3e\x5e\xc7\xc6\x11\x2a\x8a\x22\xae\xc9\x67\x5a\x88\x63\x78\xe1\x4e\x5b\xfb\xad\x4e",
+       "\x6e\x82\xf4\x60\x66\x0f\x3d\x2c\xc3\x3a\xa5\x9a\x37\xf3\x25\xee\xd0\x13\x3f\xe2\x9a\x9c\xb4\x28\xa3\xc2\x25\x72\xb6\xbf\x6c\x5d\xa2\xd0\xd4\x64\x5c\x49\x13\x56\x53\xa0\x49\x79\x5d\x4e\x2a\xd0",
+       35 },
+      { GCRY_MD_SHA3_384,
+       "\x47\xf5\x69\x7a\xc8\xc3\x14\x09\xc0\x86\x88\x27\x34\x7a\x61\x3a\x35\x62\x04\x1c\x63\x3c\xf1\xf1\xf8\x68\x65\xa5\x76\xe0\x28\x35\xed\x2c\x24\x92",
+       "\x22\x91\x60\xa6\x1c\xf2\x84\x2b\x37\xea\x85\x78\x8b\xb1\xce\x82\x94\xde\xd9\xea\xd2\x66\x35\x9d\x61\xdf\x3d\x6d\xf9\x8e\xe1\x55\xed\x03\xab\x1a\x51\xd6\x29\x1b\x41\x68\x0a\x00\x55\x32\x98\xeb",
+       36 },
+      { GCRY_MD_SHA3_384,
+       "\x51\x2a\x6d\x29\x2e\x67\xec\xb2\xfe\x48\x6b\xfe\x92\x66\x09\x53\xa7\x54\x84\xff\x4c\x4f\x2e\xca\x2b\x0a\xf0\xed\xcd\xd4\x33\x9c\x6b\x2e\xe4\xe5\x42",
+       "\xf5\xd8\x38\xde\xdf\x07\xac\x3a\x56\x46\x22\x1a\xdc\x6c\xa5\x90\x45\x97\x6d\xf9\xc3\x33\x67\xfd\xaa\x0b\xe3\xaf\xc5\x7e\xef\x0d\x43\x4e\xe9\x2c\xd6\x18\xb3\xfa\x26\xc7\xea\xbd\x18\xd7\x87\x72",
+       37 },
+      { GCRY_MD_SHA3_384,
+       "\x97\x3c\xf2\xb4\xdc\xf0\xbf\xa8\x72\xb4\x11\x94\xcb\x05\xbb\x4e\x16\x76\x0a\x18\x40\xd8\x34\x33\x01\x80\x25\x76\x19\x7e\xc1\x9e\x2a\x14\x93\xd8\xf4\xfb",
+       "\xd4\x1a\x32\x4a\x17\x39\xbb\xcf\xc9\x83\xa2\xb2\x50\x75\x0a\x11\x17\xe5\x7b\xd2\x65\x12\xcc\x5d\xca\x70\x66\xd8\xb9\x72\xad\x9e\xb0\xbb\x3c\x7e\x36\xb9\xb8\x4f\xc0\xe8\x12\x9b\x69\xcd\x38\x47",
+       38 },
+      { GCRY_MD_SHA3_384,
+       "\x80\xbe\xeb\xcd\x2e\x3f\x8a\x94\x51\xd4\x49\x99\x61\xc9\x73\x1a\xe6\x67\xcd\xc2\x4e\xa0\x20\xce\x3b\x9a\xa4\xbb\xc0\xa7\xf7\x9e\x30\xa9\x34\x46\x7d\xa4\xb0",
+       "\x17\x0d\x73\xba\xf7\x7e\xae\x7a\x85\x2a\x1b\xb1\x9b\xa6\x66\x5f\x9e\xf4\x25\xa6\x6f\x26\x49\xe9\x59\xb5\xca\xa8\x2d\x01\xfd\xb8\x9c\x8c\x7f\xa6\xf4\x07\x02\xf7\xc3\x39\x1b\x14\x6f\x6f\xa3\x3e",
+       39 },
+      { GCRY_MD_SHA3_384,
+       "\x7a\xba\xa1\x2e\xc2\xa7\x34\x76\x74\xe4\x44\x14\x0a\xe0\xfb\x65\x9d\x08\xe1\xc6\x6d\xec\xd8\xd6\xea\xe9\x25\xfa\x45\x1d\x65\xf3\xc0\x30\x8e\x29\x44\x6b\x8e\xd3",
+       "\xa8\xf4\xa6\x0a\x8f\xf5\xb3\xeb\xb4\xea\xdb\x9c\x46\xf1\xf4\x03\xab\x7f\xf6\x32\xc7\xa1\x1f\x80\xfc\x91\x53\x85\x8b\x48\x42\x91\xb3\x93\x67\x13\x07\x69\x55\x20\x7d\x0c\x7e\x19\x64\xdc\x13\x46",
+       40 },
+      { GCRY_MD_SHA3_384,
+       "\xc8\x8d\xee\x99\x27\x67\x9b\x8a\xf4\x22\xab\xcb\xac\xf2\x83\xb9\x04\xff\x31\xe1\xca\xc5\x8c\x78\x19\x80\x9f\x65\xd5\x80\x7d\x46\x72\x3b\x20\xf6\x7b\xa6\x10\xc2\xb7",
+       "\x58\x15\xd7\x8a\xca\x96\x00\x63\x22\x39\xb7\xce\x83\x85\xd7\xe8\x37\xf8\x83\x85\x76\x01\xef\xb7\x8f\x9c\x2d\xac\x9a\x96\xae\x0b\xfd\x10\x75\x26\xf2\x68\xd0\x6f\xb4\x22\x7d\x47\x74\xa9\xe7\x27",
+       41 },
+      { GCRY_MD_SHA3_384,
+       "\x01\xe4\x3f\xe3\x50\xfc\xec\x45\x0e\xc9\xb1\x02\x05\x3e\x6b\x5d\x56\xe0\x98\x96\xe0\xdd\xd9\x07\x4f\xe1\x38\xe6\x03\x82\x10\x27\x0c\x83\x4c\xe6\xea\xdc\x2b\xb8\x6b\xf6",
+       "\xa5\xd9\x1b\x01\x65\x0d\x24\xb4\x75\x3f\x41\x87\x1f\xa7\x00\xe9\x97\xd5\xf1\xef\x9c\x06\xd8\xf9\xb3\xa9\xb2\xd3\x18\x71\x64\x08\xe1\x56\x6b\xb0\x4b\x49\xb8\x4e\x77\xf5\xf7\x3d\x8f\x64\x05\x41",
+       42 },
+      { GCRY_MD_SHA3_384,
+       "\x33\x70\x23\x37\x0a\x48\xb6\x2e\xe4\x35\x46\xf1\x7c\x4e\xf2\xbf\x8d\x7e\xcd\x1d\x49\xf9\x0b\xab\x60\x4b\x83\x9c\x2e\x6e\x5b\xd2\x15\x40\xd2\x9b\xa2\x7a\xb8\xe3\x09\xa4\xb7",
+       "\xc7\xba\x06\x68\x81\xdb\x93\x1e\x9c\x67\x4d\x74\xce\x23\x09\xb3\x00\x2c\x6d\x5b\xc2\x20\x56\xc4\x54\x26\x1c\xdb\xc5\xd9\x3f\xe3\x10\xea\xdd\x75\x5e\x41\xfb\x1d\x78\x9f\xdb\x9a\x73\xfd\xa2\x8f",
+       43 },
+      { GCRY_MD_SHA3_384,
+       "\x68\x92\x54\x0f\x96\x4c\x8c\x74\xbd\x2d\xb0\x2c\x0a\xd8\x84\x51\x0c\xb3\x8a\xfd\x44\x38\xaf\x31\xfc\x91\x27\x56\xf3\xef\xec\x6b\x32\xb5\x8e\xbc\x38\xfc\x2a\x6b\x91\x35\x96\xa8",
+       "\xa5\x2c\xa3\x41\x3b\xb8\x39\x34\xb1\xea\xd4\x68\x6f\x63\x9b\x90\xc5\xee\x3c\xb5\xbe\x7e\x29\xa1\xa5\x29\x3c\x86\x84\x41\xd7\x9b\xe2\xef\x24\x6b\x42\x7f\xfc\xf0\x56\x8d\x4d\x01\xbe\x54\xff\x0d",
+       44 },
+      { GCRY_MD_SHA3_384,
+       "\xf5\x96\x1d\xfd\x2b\x1f\xff\xfd\xa4\xff\xbf\x30\x56\x0c\x16\x5b\xfe\xda\xb8\xce\x0b\xe5\x25\x84\x5d\xeb\x8d\xc6\x10\x04\xb7\xdb\x38\x46\x72\x05\xf5\xdc\xfb\x34\xa2\xac\xfe\x96\xc0",
+       "\x13\xe6\x05\x54\xfa\x18\xce\xf8\x7c\xea\xbe\x14\x75\x41\x88\x6d\x97\xc2\xfb\x5f\x40\xf1\x63\xd9\x53\x30\x6d\x2a\x26\xb0\x13\xb3\x3c\xb2\x02\xd7\x8a\xef\x49\xfd\x47\xe7\xec\x1c\x74\x59\x20\xcd",
+       45 },
+      { GCRY_MD_SHA3_384,
+       "\xca\x06\x1a\x2e\xb6\xce\xed\x88\x81\xce\x20\x57\x17\x2d\x86\x9d\x73\xa1\x95\x1e\x63\xd5\x72\x61\x38\x4b\x80\xce\xb5\x45\x1e\x77\xb0\x6c\xf0\xf5\xa0\xea\x15\xca\x90\x7e\xe1\xc2\x7e\xba",
+       "\xe4\xe0\x3c\xcb\xa9\x2b\xbd\x28\x18\x2d\x00\x5f\x69\xde\x4e\x71\xc6\x1c\x62\xcd\x32\x3d\xec\xfb\x2a\xdd\xbe\xef\xf7\xee\x74\x93\x3a\xa7\xa1\x67\xe4\xe1\xdb\xb3\xdf\x7e\x5c\x91\x18\x4f\x2d\x88",
+       46 },
+      { GCRY_MD_SHA3_384,
+       "\x17\x43\xa7\x72\x51\xd6\x92\x42\x75\x0c\x4f\x11\x40\x53\x2c\xd3\xc3\x3f\x9b\x5c\xcd\xf7\x51\x4e\x85\x84\xd4\xa5\xf9\xfb\xd7\x30\xbc\xf8\x4d\x0d\x47\x26\x36\x4b\x9b\xf9\x5a\xb2\x51\xd9\xbb",
+       "\x9b\x26\xe9\xbf\x13\xb6\xfc\x33\xfd\x33\x5d\xf9\x76\xc8\xe1\xb7\x81\xc8\x00\x89\x5e\xbd\x72\xe3\x4f\x96\xeb\x87\x5b\x41\xf0\x4a\xae\xe8\x25\xcd\x8f\x0e\xb6\xc4\x3d\x80\x3f\x4e\x6e\xf6\x88\xa9",
+       47 },
+      { GCRY_MD_SHA3_384,
+       "\xd8\xfa\xba\x1f\x51\x94\xc4\xdb\x5f\x17\x6f\xab\xff\xf8\x56\x92\x4e\xf6\x27\xa3\x7c\xd0\x8c\xf5\x56\x08\xbb\xa8\xf1\xe3\x24\xd7\xc7\xf1\x57\x29\x8e\xab\xc4\xdc\xe7\xd8\x9c\xe5\x16\x24\x99\xf9",
+       "\xa1\x27\xfe\xfc\xdd\x24\x0f\x76\x2c\xce\x3f\x5f\x15\x51\xfc\x7e\x1c\xde\xbc\x79\x50\xd1\xcd\x94\xc6\x88\x8f\x49\x0c\xb2\x28\x5a\x10\xfd\x0e\xe7\x97\xb1\x68\xc5\xca\x47\x61\xfa\x23\x2a\xaf\x05",
+       48 },
+      { GCRY_MD_SHA3_384,
+       "\xbe\x96\x84\xbe\x70\x34\x08\x60\x37\x3c\x9c\x48\x2b\xa5\x17\xe8\x99\xfc\x81\xba\xaa\x12\xe5\xc6\xd7\x72\x79\x75\xd1\xd4\x1b\xa8\xbe\xf7\x88\xcd\xb5\xcf\x46\x06\xc9\xc1\xc7\xf6\x1a\xed\x59\xf9\x7d",
+       "\xfe\xb5\xa2\x4e\xdb\x05\xbe\xf8\x46\xb0\xa1\xf3\xf4\x8d\xa2\x12\xdf\xc2\xd0\xba\xc7\x46\x89\x0d\x4a\xd7\x2f\xbe\x3a\x7b\x4f\xf8\xe2\xb5\x42\xb8\x27\x77\x94\x67\x12\x22\x71\xb1\xe0\xdf\x2b\xd2",
+       49 },
+      { GCRY_MD_SHA3_384,
+       "\x7e\x15\xd2\xb9\xea\x74\xca\x60\xf6\x6c\x8d\xfa\xb3\x77\xd9\x19\x8b\x7b\x16\xde\xb6\xa1\xba\x0e\xa3\xc7\xee\x20\x42\xf8\x9d\x37\x86\xe7\x79\xcf\x05\x3c\x77\x78\x5a\xa9\xe6\x92\xf8\x21\xf1\x4a\x7f\x51",
+       "\x8d\xa4\xf3\xd1\xa1\x31\x97\x17\x1b\x02\xe1\xcc\xb0\x7b\xf5\x1c\xdb\xab\xd8\x33\xfd\xc3\xc3\x79\x7a\x11\x3c\xfa\x5c\x71\x79\x57\x82\xc4\x7c\xe3\x6c\x38\x9f\xba\xd4\x61\xd0\xd5\xb5\x9c\xa6\x84",
+       50 },
+      { GCRY_MD_SHA3_384,
+       "\x9a\x21\x9b\xe4\x37\x13\xbd\x57\x80\x15\xe9\xfd\xa6\x6c\x0f\x2d\x83\xca\xc5\x63\xb7\x76\xab\x9f\x38\xf3\xe4\xf7\xef\x22\x9c\xb4\x43\x30\x4f\xba\x40\x1e\xfb\x2b\xdb\xd7\xec\xe9\x39\x10\x22\x98\x65\x1c\x86",
+       "\xd1\x9f\xe4\xa5\xf9\x3b\xcd\x48\x3d\xaa\x7a\xf8\xcb\x63\x68\x07\x96\x2d\x40\xaf\x9a\x50\x7d\xc4\xfa\x4e\x1f\xd4\x80\xa6\xe8\xfa\x3c\x25\xfa\x30\xeb\x6b\x74\x97\x9e\xe4\x56\xc1\x64\x4a\x5c\x1d",
+       51 },
+      { GCRY_MD_SHA3_384,
+       "\xc8\xf2\xb6\x93\xbd\x0d\x75\xef\x99\xca\xeb\xdc\x22\xad\xf4\x08\x8a\x95\xa3\x54\x2f\x63\x72\x03\xe2\x83\xbb\xc3\x26\x87\x80\xe7\x87\xd6\x8d\x28\xcc\x38\x97\x45\x2f\x6a\x22\xaa\x85\x73\xcc\xeb\xf2\x45\x97\x2a",
+       "\x63\xff\x30\x53\xac\xe6\x87\xfb\x91\x07\x0c\xa7\xfc\x6a\x51\xc2\x59\xe1\x3d\xa8\xac\x0d\xd7\x41\xab\x36\xd1\xfa\x93\x0e\x3b\xb9\xac\x6a\x1f\xad\x65\x4f\x72\x38\xcf\xc4\x48\x5c\x5f\x9f\x82\x52",
+       52 },
+      { GCRY_MD_SHA3_384,
+       "\xec\x0f\x99\x71\x10\x16\xc6\xa2\xa0\x7a\xd8\x0d\x16\x42\x75\x06\xce\x6f\x44\x10\x59\xfd\x26\x94\x42\xba\xaa\x28\xc6\xca\x03\x7b\x22\xee\xac\x49\xd5\xd8\x94\xc0\xbf\x66\x21\x9f\x2c\x08\xe9\xd0\xe8\xab\x21\xde\x52",
+       "\x39\xdd\xe0\x2a\x31\x9b\x5e\x86\x9f\x4c\x51\xa1\xd3\x0f\xf4\xd4\xd8\x8e\xbe\x50\x4c\x54\xf1\x55\xaa\x5f\xad\x33\x16\x40\x4f\xdb\xd1\x91\x80\x74\xd3\x5d\x14\xba\xc8\x8d\x6f\x35\x91\x08\xa1\xdc",
+       53 },
+      { GCRY_MD_SHA3_384,
+       "\x0d\xc4\x51\x81\x33\x7c\xa3\x2a\x82\x22\xfe\x7a\x3b\xf4\x2f\xc9\xf8\x97\x44\x25\x9c\xff\x65\x35\x04\xd6\x05\x1f\xe8\x4b\x1a\x7f\xfd\x20\xcb\x47\xd4\x69\x6c\xe2\x12\xa6\x86\xbb\x9b\xe9\xa8\xab\x1c\x69\x7b\x6d\x6a\x33",
+       "\x19\x59\x37\x8f\x32\x11\x7e\x58\xc0\x14\x11\x60\xe1\x6f\xac\xfe\x33\x65\x90\x19\x6b\xe8\x05\xd1\x49\xeb\x5a\xee\xa6\x41\xf9\xbb\x11\x9b\x3e\xdd\xfe\xfd\x81\x77\x01\xc8\x2d\x2f\x52\x8b\x82\x3e",
+       54 },
+      { GCRY_MD_SHA3_384,
+       "\xde\x28\x6b\xa4\x20\x6e\x8b\x00\x57\x14\xf8\x0f\xb1\xcd\xfa\xeb\xde\x91\xd2\x9f\x84\x60\x3e\x4a\x3e\xbc\x04\x68\x6f\x99\xa4\x6c\x9e\x88\x0b\x96\xc5\x74\x82\x55\x82\xe8\x81\x2a\x26\xe5\xa8\x57\xff\xc6\x57\x9f\x63\x74\x2f",
+       "\x7b\x17\x2a\x9b\xb3\x11\xb1\x37\x5e\x15\xec\xe1\xc1\xe8\xf0\x92\xbe\xcf\xaf\xec\x9f\x31\x44\xe9\x3f\x59\x6e\xb7\xe6\xab\xfb\x34\xfc\xed\xb0\x8e\xda\x78\x83\xeb\xbf\x40\x03\x8b\x7a\x75\x4f\x9f",
+       55 },
+      { GCRY_MD_SHA3_384,
+       "\xee\xbc\xc1\x80\x57\x25\x2c\xbf\x3f\x9c\x07\x0f\x1a\x73\x21\x33\x56\xd5\xd4\xbc\x19\xac\x2a\x41\x1e\xc8\xcd\xee\xe7\xa5\x71\xe2\xe2\x0e\xaf\x61\xfd\x0c\x33\xa0\xff\xeb\x29\x7d\xdb\x77\xa9\x7f\x0a\x41\x53\x47\xdb\x66\xbc\xaf",
+       "\x6b\xa3\x2e\xca\xaa\x0a\xa9\xc5\x9e\x72\x17\x3f\x2a\x78\x16\xac\x51\xf3\x13\xc4\x67\xa0\x17\x19\x0d\xb9\x83\x2c\x63\x11\xec\x23\xb8\xd5\x6b\x7b\x22\x0f\xa0\x9a\x90\x81\x96\x2e\xfe\xd5\x18\x3e",
+       56 },
+      { GCRY_MD_SHA3_384,
+       "\x41\x6b\x5c\xdc\x9f\xe9\x51\xbd\x36\x1b\xd7\xab\xfc\x12\x0a\x50\x54\x75\x8e\xba\x88\xfd\xd6\x8f\xd8\x4e\x39\xd3\xb0\x9a\xc2\x54\x97\xd3\x6b\x43\xcb\xe7\xb8\x5a\x6a\x3c\xeb\xda\x8d\xb4\xe5\x54\x9c\x3e\xe5\x1b\xb6\xfc\xb6\xac\x1e",
+       "\x55\xfd\xf2\xec\x27\xd3\x34\xb5\xb5\x9e\xfb\x9b\x6d\x51\x8e\x25\xbe\x0f\x5f\xf6\x37\x9f\x7b\x97\x94\x5f\x3e\x12\x35\xec\x70\x29\x5b\x39\xeb\xea\xbf\x70\xfc\xaf\x1e\x61\xed\xb1\xc2\x1a\x4c\x06",
+       57 },
+      { GCRY_MD_SHA3_384,
+       "\x5c\x5f\xaf\x66\xf3\x2e\x0f\x83\x11\xc3\x2e\x8d\xa8\x28\x4a\x4e\xd6\x08\x91\xa5\xa7\xe5\x0f\xb2\x95\x6b\x3c\xba\xa7\x9f\xc6\x6c\xa3\x76\x46\x0e\x10\x04\x15\x40\x1f\xc2\xb8\x51\x8c\x64\x50\x2f\x18\x7e\xa1\x4b\xfc\x95\x03\x75\x97\x05",
+       "\xd5\x1a\x3f\x33\x91\x9f\xe5\xda\x0e\xfe\xa6\xed\xad\x20\x1f\x01\xfa\x84\x16\xc3\x85\xa8\x9d\x96\xdf\x74\x3d\x24\x3a\x6a\xab\xa5\xb7\x69\x0d\x18\x7b\x95\xca\xff\xda\xcd\x1e\x85\xf5\x6b\x81\x3b",
+       58 },
+      { GCRY_MD_SHA3_384,
+       "\x71\x67\xe1\xe0\x2b\xe1\xa7\xca\x69\xd7\x88\x66\x6f\x82\x3a\xe4\xee\xf3\x92\x71\xf3\xc2\x6a\x5c\xf7\xce\xe0\x5b\xca\x83\x16\x10\x66\xdc\x2e\x21\x7b\x33\x0d\xf8\x21\x10\x37\x99\xdf\x6d\x74\x81\x0e\xed\x36\x3a\xdc\x4a\xb9\x9f\x36\x04\x6a",
+       "\xf1\xd6\xe8\xf9\x5c\x49\x7d\x5b\xea\xfb\x42\x15\xe0\x7c\xdb\x59\xe0\xe3\x70\x9c\xf5\x61\x61\x8f\x67\xe3\x01\x93\x1d\x20\x4c\x6c\xe4\x77\xe0\xf7\x50\x09\x95\x84\xb6\x45\xe2\xf7\x18\x65\x08\x13",
+       59 },
+      { GCRY_MD_SHA3_384,
+       "\x2f\xda\x31\x1d\xbb\xa2\x73\x21\xc5\x32\x95\x10\xfa\xe6\x94\x8f\x03\x21\x0b\x76\xd4\x3e\x74\x48\xd1\x68\x9a\x06\x38\x77\xb6\xd1\x4c\x4f\x6d\x0e\xaa\x96\xc1\x50\x05\x13\x71\xf7\xdd\x8a\x41\x19\xf7\xda\x5c\x48\x3c\xc3\xe6\x72\x3c\x01\xfb\x7d",
+       "\xb1\xd3\x47\xd0\x57\xcc\xd7\x28\x67\xb1\x2b\xf0\x0b\xf5\x11\xf8\x7d\xef\xcd\x0f\xa6\xad\xad\xaf\x4b\xb1\xad\x79\x0f\x06\xec\xbb\x1f\x44\x88\xa0\x31\x9b\x05\xc4\x6a\x78\x74\x85\x73\x70\xce\x76",
+       60 },
+      { GCRY_MD_SHA3_384,
+       "\x95\xd1\x47\x4a\x5a\xab\x5d\x24\x22\xac\xa6\xe4\x81\x18\x78\x33\xa6\x21\x2b\xd2\xd0\xf9\x14\x51\xa6\x7d\xd7\x86\xdf\xc9\x1d\xfe\xd5\x1b\x35\xf4\x7e\x1d\xeb\x8a\x8a\xb4\xb9\xcb\x67\xb7\x01\x79\xcc\x26\xf5\x53\xae\x7b\x56\x99\x69\xce\x15\x1b\x8d",
+       "\x4f\x19\x2e\xdf\xa5\x4f\xec\xe6\x4a\xc0\xb3\xec\x9e\x12\x0b\x29\x1a\xde\x99\x94\x88\x05\xa8\x7b\xbb\x04\x94\x7e\x92\x8b\xb5\xeb\xa8\x7e\x2e\xe5\x99\x96\x0c\x43\x6e\xa7\xc7\x88\x41\x87\xe7\x8c",
+       61 },
+      { GCRY_MD_SHA3_384,
+       "\xc7\x1b\xd7\x94\x1f\x41\xdf\x04\x4a\x29\x27\xa8\xff\x55\xb4\xb4\x67\xc3\x3d\x08\x9f\x09\x88\xaa\x25\x3d\x29\x4a\xdd\xbd\xb3\x25\x30\xc0\xd4\x20\x8b\x10\xd9\x95\x98\x23\xf0\xc0\xf0\x73\x46\x84\x00\x6d\xf7\x9f\x70\x99\x87\x0f\x6b\xf5\x32\x11\xa8\x8d",
+       "\x75\xe2\x3f\xed\x3b\x59\xdb\x6b\x1d\x33\x78\xb7\xe8\x77\x26\x42\xcb\xbf\xf7\x71\x0d\x8a\x91\xb2\x49\xbb\x6c\x68\xe3\x84\xcd\x41\x6f\x19\xac\x1e\x8e\xd9\x2b\x71\xd0\xca\x30\x3d\x24\x7e\xe9\xbd",
+       62 },
+      { GCRY_MD_SHA3_384,
+       "\xf5\x7c\x64\x00\x6d\x9e\xa7\x61\x89\x2e\x14\x5c\x99\xdf\x1b\x24\x64\x08\x83\xda\x79\xd9\xed\x52\x62\x85\x9d\xcd\xa8\xc3\xc3\x2e\x05\xb0\x3d\x98\x4f\x1a\xb4\xa2\x30\x24\x2a\xb6\xb7\x8d\x36\x8d\xc5\xaa\xa1\xe6\xd3\x49\x8d\x53\x37\x1e\x84\xb0\xc1\xd4\xba",
+       "\xc8\xd1\xe6\xbe\x54\x85\xfc\x13\xbf\x43\x3f\x11\xa5\x80\xab\xbe\x89\xb1\x2a\x66\xd0\xe5\xcb\x14\x1e\x1d\x62\xcd\xc6\xa3\x67\x72\x57\x93\xfb\x25\x84\x0b\x36\xcb\x70\x03\xf2\xe7\xdf\x3e\x5f\x2f",
+       63 },
+      { GCRY_MD_SHA3_384,
+       "\xe9\x26\xae\x8b\x0a\xf6\xe5\x31\x76\xdb\xff\xcc\x2a\x6b\x88\xc6\xbd\x76\x5f\x93\x9d\x3d\x17\x8a\x9b\xde\x9e\xf3\xaa\x13\x1c\x61\xe3\x1c\x1e\x42\xcd\xfa\xf4\xb4\xdc\xde\x57\x9a\x37\xe1\x50\xef\xbe\xf5\x55\x5b\x4c\x1c\xb4\x04\x39\xd8\x35\xa7\x24\xe2\xfa\xe7",
+       "\x42\x3b\xa1\x34\xd3\xbc\xb5\xe4\x40\xac\x83\x37\x2c\x7e\xdd\xba\x3a\xe3\xbd\xdf\x12\x22\xf5\x05\xc1\x9c\xde\x24\x6a\xd7\x6a\x2b\x0d\x07\x23\x9a\x54\xe1\xd0\x93\x4c\x9b\x3d\x29\xd4\x9e\x5f\xbd",
+       64 },
+      { GCRY_MD_SHA3_384,
+       "\x16\xe8\xb3\xd8\xf9\x88\xe9\xbb\x04\xde\x9c\x96\xf2\x62\x78\x11\xc9\x73\xce\x4a\x52\x96\xb4\x77\x2c\xa3\xee\xfe\xb8\x0a\x65\x2b\xdf\x21\xf5\x0d\xf7\x9f\x32\xdb\x23\xf9\xf7\x3d\x39\x3b\x2d\x57\xd9\xa0\x29\x7f\x7a\x2f\x2e\x79\xcf\xda\x39\xfa\x39\x3d\xf1\xac\x00",
+       "\x66\x2c\x48\x51\xd3\x11\xa7\x86\xde\x4c\xda\x7e\x9e\xa1\xef\xf0\xbf\xa4\x62\x76\x1f\xf6\xcf\x80\x4e\x59\x1e\xd9\xa1\x5b\x0d\xc9\x3a\x2b\xb6\xa6\xcf\xfd\xc8\xd7\xd2\x3a\x23\x3a\x52\xc8\x6e\xad",
+       65 },
+      { GCRY_MD_SHA3_384,
+       "\xfc\x42\x4e\xeb\x27\xc1\x8a\x11\xc0\x1f\x39\xc5\x55\xd8\xb7\x8a\x80\x5b\x88\xdb\xa1\xdc\x2a\x42\xed\x5e\x2c\x0e\xc7\x37\xff\x68\xb2\x45\x6d\x80\xeb\x85\xe1\x17\x14\xfa\x3f\x8e\xab\xfb\x90\x6d\x3c\x17\x96\x4c\xb4\xf5\xe7\x6b\x29\xc1\x76\x5d\xb0\x3d\x91\xbe\x37\xfc",
+       "\x5f\x54\xb1\xda\xfa\x67\xed\x9b\x49\x81\x25\xe0\x64\xf0\xb0\x7f\x54\xe7\x54\xe3\xf3\x07\x20\xdd\x4a\x47\x1e\x9b\xb6\xe3\x07\xf0\x5f\xb6\x9b\xc8\x1d\x39\x1f\x50\x3c\x95\xc3\xbb\x67\x1e\x69\x73",
+       66 },
+      { GCRY_MD_SHA3_384,
+       "\xab\xe3\x47\x2b\x54\xe7\x27\x34\xbd\xba\x7d\x91\x58\x73\x64\x64\x25\x1c\x4f\x21\xb3\x3f\xbb\xc9\x2d\x7f\xac\x9a\x35\xc4\xe3\x32\x2f\xf0\x1d\x23\x80\xcb\xaa\x4e\xf8\xfb\x07\xd2\x1a\x21\x28\xb7\xb9\xf5\xb6\xd9\xf3\x4e\x13\xf3\x9c\x7f\xfc\x2e\x72\xe4\x78\x88\x59\x9b\xa5",
+       "\xa2\x1b\x55\xde\xd8\xfe\x41\xfb\x2b\x19\x3f\xa4\x90\x42\x0a\x8b\x62\xfc\xae\x9a\x18\x5d\xa8\x5e\x25\x3d\xae\xfe\x85\x27\x0b\x69\x04\xba\x4e\xcc\x76\xbb\x51\x28\x92\x6f\xff\x9d\x79\xf7\x28\xad",
+       67 },
+      { GCRY_MD_SHA3_384,
+       "\x36\xf9\xf0\xa6\x5f\x2c\xa4\x98\xd7\x39\xb9\x44\xd6\xef\xf3\xda\x5e\xbb\xa5\x7e\x7d\x9c\x41\x59\x8a\x2b\x0e\x43\x80\xf3\xcf\x4b\x47\x9e\xc2\x34\x8d\x01\x5f\xfe\x62\x56\x27\x35\x11\x15\x4a\xfc\xf3\xb4\xb4\xbf\x09\xd6\xc4\x74\x4f\xdd\x0f\x62\xd7\x50\x79\xd4\x40\x70\x6b\x05",
+       "\x34\x1b\xe5\x67\x7a\x05\xee\xd8\x16\xa2\x19\x66\x9d\x68\x0b\xbf\x18\x5b\x31\xcf\x3e\xb0\xd2\x89\xf9\x02\x10\xfb\x1a\x79\x40\xd9\xbf\xf4\x90\x93\x20\xae\x4e\x3b\x72\x74\xe5\xbe\x47\x9c\x46\xf1",
+       68 },
+      { GCRY_MD_SHA3_384,
+       "\xab\xc8\x77\x63\xca\xe1\xca\x98\xbd\x8c\x5b\x82\xca\xba\x54\xac\x83\x28\x6f\x87\xe9\x61\x01\x28\xae\x4d\xe6\x8a\xc9\x5d\xf5\xe3\x29\xc3\x60\x71\x7b\xd3\x49\xf2\x6b\x87\x25\x28\x49\x2c\xa7\xc9\x4c\x2c\x1e\x1e\xf5\x6b\x74\xdb\xb6\x5c\x2a\xc3\x51\x98\x1f\xdb\x31\xd0\x6c\x77\xa4",
+       "\xd7\x0f\x78\x89\x4e\x29\x2b\x07\x5a\x0f\xe5\x6f\xb9\x52\xb2\xce\x87\xa9\x4c\xa0\x29\x34\x71\x59\xfb\xb1\x2b\x22\x10\x3d\xd4\xdc\x4c\x26\x5b\x7a\xe8\x89\x50\xcc\xa8\x9c\x40\xb5\x31\x43\x7a\xa4",
+       69 },
+      { GCRY_MD_SHA3_384,
+       "\x94\xf7\xca\x8e\x1a\x54\x23\x4c\x6d\x53\xcc\x73\x4b\xb3\xd3\x15\x0c\x8b\xa8\xc5\xf8\x80\xea\xb8\xd2\x5f\xed\x13\x79\x3a\x97\x01\xeb\xe3\x20\x50\x92\x86\xfd\x8e\x42\x2e\x93\x1d\x99\xc9\x8d\xa4\xdf\x7e\x70\xae\x44\x7b\xab\x8c\xff\xd9\x23\x82\xd8\xa7\x77\x60\xa2\x59\xfc\x4f\xbd\x72",
+       "\x89\xbd\x6b\x7c\xc9\xad\xdd\xff\xe4\x6b\xf8\x5c\x56\xb8\xce\x66\xe1\xb1\xb4\x69\x69\xb1\x97\xad\xbf\x2e\x34\xb7\x05\x9d\x8b\xb0\x5f\x9f\x53\xbd\x1a\x58\xa7\xe0\xa6\x6e\x5e\xf2\x08\xbf\x56\x95",
+       70 },
+      { GCRY_MD_SHA3_384,
+       "\x13\xbd\x28\x11\xf6\xed\x2b\x6f\x04\xff\x38\x95\xac\xee\xd7\xbe\xf8\xdc\xd4\x5e\xb1\x21\x79\x1b\xc1\x94\xa0\xf8\x06\x20\x6b\xff\xc3\xb9\x28\x1c\x2b\x30\x8b\x1a\x72\x9c\xe0\x08\x11\x9d\xd3\x06\x6e\x93\x78\xac\xdc\xc5\x0a\x98\xa8\x2e\x20\x73\x88\x00\xb6\xcd\xdb\xe5\xfe\x96\x94\xad\x6d",
+       "\xae\x65\x1e\xf5\x0a\x20\xb0\xf4\x96\xf1\x04\xf5\x6f\x84\x52\x06\xed\x54\x4b\x28\xd0\x37\x4c\xbb\x77\x91\x46\xdf\xf2\xea\x58\x94\xeb\x29\x30\x1f\xe3\x38\x72\xf9\xb2\x99\xa7\x9c\x0c\x0f\x28\xc4",
+       71 },
+      { GCRY_MD_SHA3_384,
+       "\x1e\xed\x9c\xba\x17\x9a\x00\x9e\xc2\xec\x55\x08\x77\x3d\xd3\x05\x47\x7c\xa1\x17\xe6\xd5\x69\xe6\x6b\x5f\x64\xc6\xbc\x64\x80\x1c\xe2\x5a\x84\x24\xce\x4a\x26\xd5\x75\xb8\xa6\xfb\x10\xea\xd3\xfd\x19\x92\xed\xdd\xee\xc2\xeb\xe7\x15\x0d\xc9\x8f\x63\xad\xc3\x23\x7e\xf5\x7b\x91\x39\x7a\xa8\xa7",
+       "\xa8\x42\x91\x8d\xfb\xbf\x3b\xff\xcc\xc5\x27\xb6\xdd\x2c\x0d\xf4\xeb\x3f\x10\x0f\x06\x92\x72\x7d\xa7\x7d\xaf\x44\xa6\x54\x87\x60\x13\xb3\x70\x31\xc4\x93\xac\x18\x95\x00\x03\xee\xbd\x10\x7a\x29",
+       72 },
+      { GCRY_MD_SHA3_384,
+       "\xba\x5b\x67\xb5\xec\x3a\x3f\xfa\xe2\xc1\x9d\xd8\x17\x6a\x2e\xf7\x5c\x0c\xd9\x03\x72\x5d\x45\xc9\xcb\x70\x09\xa9\x00\xc0\xb0\xca\x7a\x29\x67\xa9\x5a\xe6\x82\x69\xa6\xdb\xf8\x46\x6c\x7b\x68\x44\xa1\xd6\x08\xac\x66\x1f\x7e\xff\x00\x53\x8e\x32\x3d\xb5\xf2\xc6\x44\xb7\x8b\x2d\x48\xde\x1a\x08\xaa",
+       "\x20\xd1\x6c\xc6\xaf\x5b\x4d\x5a\xec\xce\xad\x09\xf3\x00\xb1\xdc\x1d\xa9\x3a\x60\x83\x70\xee\x0b\x2c\xf1\x5c\x31\x65\x08\xb5\xef\x8c\x9b\xe2\x7d\x0f\x72\x88\x61\x7b\x1e\x52\x9f\xc2\x93\x20\x38",
+       73 },
+      { GCRY_MD_SHA3_384,
+       "\x0e\xfa\x26\xac\x56\x73\x16\x7d\xca\xca\xb8\x60\x93\x2e\xd6\x12\xf6\x5f\xf4\x9b\x80\xfa\x9a\xe6\x54\x65\xe5\x54\x2c\xb6\x20\x75\xdf\x1c\x5a\xe5\x4f\xba\x4d\xb8\x07\xbe\x25\xb0\x70\x03\x3e\xfa\x22\x3b\xdd\x5b\x1d\x3c\x94\xc6\xe1\x90\x9c\x02\xb6\x20\xd4\xb1\xb3\xa6\xc9\xfe\xd2\x4d\x70\x74\x96\x04",
+       "\x69\xa3\xbb\x36\xf5\x2e\xb6\x50\xc6\xe8\x24\x2d\xb0\x56\x59\x57\x3a\xf8\x11\xa1\xa5\xdb\x90\x8f\x77\x3d\x65\xe7\x4d\x32\x7f\x5b\x65\x30\x3d\xd0\xdd\x9b\xd0\x7f\xf1\x00\xd0\x50\xe4\x6f\xe9\x7d",
+       74 },
+      { GCRY_MD_SHA3_384,
+       "\xbb\xfd\x93\x3d\x1f\xd7\xbf\x59\x4a\xc7\xf4\x35\x27\x7d\xc1\x7d\x8d\x5a\x5b\x8e\x4d\x13\xd9\x6d\x2f\x64\xe7\x71\xab\xbd\x51\xa5\xa8\xae\xa7\x41\xbe\xcc\xbd\xdb\x17\x7b\xce\xa0\x52\x43\xeb\xd0\x03\xcf\xde\xae\x87\x7c\xca\x4d\xa9\x46\x05\xb6\x76\x91\x91\x9d\x8b\x03\x3f\x77\xd3\x84\xca\x01\x59\x3c\x1b",
+       "\xd2\x39\xf2\xfa\x16\x75\xa1\xa0\x31\xe2\xf6\xe8\xa5\x3d\x6e\x2f\x37\xd0\x81\xcd\xb0\x29\x72\x7b\x3a\xcb\xdd\x7c\xbf\xc7\xd3\x58\x1b\xde\x8d\x30\x68\xaa\x9a\x30\x0a\xe1\x2b\x72\x45\x12\x45\x08",
+       75 },
+      { GCRY_MD_SHA3_384,
+       "\x90\x07\x89\x99\xfd\x3c\x35\xb8\xaf\xbf\x40\x66\xcb\xde\x33\x58\x91\x36\x5f\x0f\xc7\x5c\x12\x86\xcd\xd8\x8f\xa5\x1f\xab\x94\xf9\xb8\xde\xf7\xc9\xac\x58\x2a\x5d\xbc\xd9\x58\x17\xaf\xb7\xd1\xb4\x8f\x63\x70\x4e\x19\xc2\xba\xa4\xdf\x34\x7f\x48\xd4\xa6\xd6\x03\x01\x3c\x23\xf1\xe9\x61\x1d\x59\x5e\xba\xc3\x7c",
+       "\x2f\x8d\x74\x7d\xdf\x64\x32\x02\x97\xb4\x4f\x85\x47\xef\x42\xfc\xe7\x8a\x48\xf0\xa5\x9a\x18\xdb\x1c\xfb\x9f\x43\xc0\x49\x62\x8f\x97\xc0\xbb\x93\xad\xaa\xb9\x61\x71\x55\x27\x24\x24\xf7\x40\x27",
+       76 },
+      { GCRY_MD_SHA3_384,
+       "\x64\x10\x5e\xca\x86\x35\x15\xc2\x0e\x7c\xfb\xaa\x0a\x0b\x88\x09\x04\x61\x64\xf3\x74\xd6\x91\xcd\xbd\x65\x08\xaa\xab\xc1\x81\x9f\x9a\xc8\x4b\x52\xba\xfc\x1b\x0f\xe7\xcd\xdb\xc5\x54\xb6\x08\xc0\x1c\x89\x04\xc6\x69\xd8\xdb\x31\x6a\x09\x53\xa4\xc6\x8e\xce\x32\x4e\xc5\xa4\x9f\xfd\xb5\x9a\x1b\xd6\xa2\x92\xaa\x0e",
+       "\x71\x4b\xe6\xf2\xf9\x34\xe0\xb6\xfd\x69\xe3\x92\xd9\x9a\xcc\x98\x59\x2b\x01\x5e\x48\xa1\x63\x72\x62\xf9\x92\x86\x50\x2b\x06\x77\x47\x83\xbb\x9f\x37\x1c\x76\x0c\x3e\xb7\x8a\xea\xdf\xbd\x0d\xf0",
+       77 },
+      { GCRY_MD_SHA3_384,
+       "\xd4\x65\x4b\xe2\x88\xb9\xf3\xb7\x11\xc2\xd0\x20\x15\x97\x8a\x8c\xc5\x74\x71\xd5\x68\x0a\x09\x2a\xa5\x34\xf7\x37\x2c\x71\xce\xaa\xb7\x25\xa3\x83\xc4\xfc\xf4\xd8\xde\xaa\x57\xfc\xa3\xce\x05\x6f\x31\x29\x61\xec\xcf\x9b\x86\xf1\x49\x81\xba\x5b\xed\x6a\xb5\xb4\x49\x8e\x1f\x6c\x82\xc6\xca\xe6\xfc\x14\x84\x5b\x3c\x8a",
+       "\x22\xa4\x1b\x11\x74\x64\xf7\xf4\x96\x82\xe8\x13\x9a\x0d\x5b\xd2\x3f\xe0\x0d\x11\x90\xb1\xb4\x19\xf2\x7b\x49\x0b\x72\x9b\x56\xbb\xa9\xde\x64\x9d\xd7\xc9\x88\xb6\xb3\x08\x03\x86\x61\xe1\xc3\x62",
+       78 },
+      { GCRY_MD_SHA3_384,
+       "\x12\xd9\x39\x48\x88\x30\x5a\xc9\x6e\x65\xf2\xbf\x0e\x1b\x18\xc2\x9c\x90\xfe\x9d\x71\x4d\xd5\x9f\x65\x1f\x52\xb8\x8b\x30\x08\xc5\x88\x43\x55\x48\x06\x6e\xa2\xfc\x4c\x10\x11\x18\xc9\x1f\x32\x55\x62\x24\xa5\x40\xde\x6e\xfd\xdb\xca\x29\x6e\xf1\xfb\x00\x34\x1f\x5b\x01\xfe\xcf\xc1\x46\xbd\xb2\x51\xb3\xbd\xad\x55\x6c\xd2",
+       "\x77\x78\x0f\x36\x46\xd2\x88\x29\x17\x90\xf2\xa5\xf4\xaa\x9c\x98\xa6\x4a\x11\x15\x30\x69\x94\xcd\x65\xc7\x62\x0d\xde\x06\xd3\x51\x17\xce\x4b\x79\xda\xe0\x8b\x5b\x4e\x79\x84\x59\x01\x09\x41\xbb",
+       79 },
+      { GCRY_MD_SHA3_384,
+       "\x87\x1a\x0d\x7a\x5f\x36\xc3\xda\x1d\xfc\xe5\x7a\xcd\x8a\xb8\x48\x7c\x27\x4f\xad\x33\x6b\xc1\x37\xeb\xd6\xff\x46\x58\xb5\x47\xc1\xdc\xfa\xb6\x5f\x03\x7a\xa5\x8f\x35\xef\x16\xaf\xf4\xab\xe7\x7b\xa6\x1f\x65\x82\x6f\x7b\xe6\x81\xb5\xb6\xd5\xa1\xea\x80\x85\xe2\xae\x9c\xd5\xcf\x09\x91\x87\x8a\x31\x1b\x54\x9a\x6d\x6a\xf2\x30",
+       "\x5c\xed\x3b\x73\x68\x58\x2d\xd6\xde\xbf\xe4\x1d\x6a\xff\xd8\x2b\x72\x89\x4b\x51\xff\x4c\x4a\xcc\xba\x09\xc5\x95\xb3\x6e\x23\xe3\x47\xab\x4b\xaa\xb0\xe5\x19\x1d\x86\xe2\x6e\x65\x96\xd6\x2e\x23",
+       80 },
+      { GCRY_MD_SHA3_384,
+       "\xe9\x0b\x4f\xfe\xf4\xd4\x57\xbc\x77\x11\xff\x4a\xa7\x22\x31\xca\x25\xaf\x6b\x2e\x20\x6f\x8b\xf8\x59\xd8\x75\x8b\x89\xa7\xcd\x36\x10\x5d\xb2\x53\x8d\x06\xda\x83\xba\xd5\xf6\x63\xba\x11\xa5\xf6\xf6\x1f\x23\x6f\xd5\xf8\xd5\x3c\x5e\x89\xf1\x83\xa3\xce\xc6\x15\xb5\x0c\x7c\x68\x1e\x77\x3d\x10\x9f\xf7\x49\x1b\x5c\xc2\x22\x96\xc5",
+       "\x14\x10\xef\x9a\xbb\x8d\x98\xb1\xc6\x5e\x11\x3a\x61\x91\x5b\x0e\x69\x33\xbc\x59\xda\x31\xc8\xfc\xc3\x9b\x71\x65\xe7\x15\x91\x91\x84\x37\x5d\x82\x2a\x07\xc7\x78\xf6\x34\x31\xbe\x2a\xee\xcd\x99",
+       81 },
+      { GCRY_MD_SHA3_384,
+       "\xe7\x28\xde\x62\xd7\x58\x56\x50\x0c\x4c\x77\xa4\x28\x61\x2c\xd8\x04\xf3\x0c\x3f\x10\xd3\x6f\xb2\x19\xc5\xca\x0a\xa3\x07\x26\xab\x19\x0e\x5f\x3f\x27\x9e\x07\x33\xd7\x7e\x72\x67\xc1\x7b\xe2\x7d\x21\x65\x0a\x9a\x4d\x1e\x32\xf6\x49\x62\x76\x38\xdb\xad\xa9\x70\x2c\x7c\xa3\x03\x26\x9e\xd1\x40\x14\xb2\xf3\xcf\x8b\x89\x4e\xac\x85\x54",
+       "\x33\x0e\xd5\x1b\x04\x54\x71\xde\xa8\xcf\xf2\x65\x10\xd6\x84\x94\x61\x1e\xcf\xd6\x14\xd4\x9e\x5a\x9c\xc8\x84\x6a\x13\x25\x19\xbb\xcf\x49\x90\x76\x91\xac\x5a\xcc\xfc\x05\x28\xda\x0c\x14\xd4\x9e",
+       82 },
+      { GCRY_MD_SHA3_384,
+       "\x63\x48\xf2\x29\xe7\xb1\xdf\x3b\x77\x0c\x77\x54\x4e\x51\x66\xe0\x81\x85\x0f\xa1\xc6\xc8\x81\x69\xdb\x74\xc7\x6e\x42\xeb\x98\x3f\xac\xb2\x76\xad\x6a\x0d\x1f\xa7\xb5\x0d\x3e\x3b\x6f\xcd\x79\x9e\xc9\x74\x70\x92\x0a\x7a\xbe\xd4\x7d\x28\x8f\xf8\x83\xe2\x4c\xa2\x1c\x7f\x80\x16\xb9\x3b\xb9\xb9\xe0\x78\xbd\xb9\x70\x3d\x2b\x78\x1b\x61\x6e",
+       "\x38\x71\x11\xa2\x06\xfc\x64\x88\xf7\x8d\x41\x78\x68\x86\xa9\xe5\xec\x9f\x73\xe1\x13\x1d\x92\xf2\x90\xf6\x85\x12\x32\x0a\x40\x8d\x5f\x63\xea\xa5\xab\xa3\x2d\x98\x53\xeb\x11\xb5\xb0\x88\x7e\x62",
+       83 },
+      { GCRY_MD_SHA3_384,
+       "\x4b\x12\x7f\xde\x5d\xe7\x33\xa1\x68\x0c\x27\x90\x36\x36\x27\xe6\x3a\xc8\xa3\xf1\xb4\x70\x7d\x98\x2c\xae\xa2\x58\x65\x5d\x9b\xf1\x8f\x89\xaf\xe5\x41\x27\x48\x2b\xa0\x1e\x08\x84\x55\x94\xb6\x71\x30\x6a\x02\x5c\x9a\x5c\x5b\x6f\x93\xb0\xa3\x95\x22\xdc\x87\x74\x37\xbe\x5c\x24\x36\xcb\xf3\x00\xce\x7a\xb6\x74\x79\x34\xfc\xfc\x30\xae\xaa\xf6",
+       "\x78\x57\x3f\x5d\x07\x52\x00\xd3\x82\x31\x94\xa7\x1e\x55\x88\x0f\x4f\xe7\x84\x89\x23\x4d\xbf\x3d\xf3\xe3\x73\x4c\xbc\xae\x8d\xc1\xd8\xc1\xae\x95\xf9\xef\xa9\x90\x3d\xc4\xc4\x58\x1b\x59\xdd\xde",
+       84 },
+      { GCRY_MD_SHA3_384,
+       "\x08\x46\x1f\x00\x6c\xff\x4c\xc6\x4b\x75\x2c\x95\x72\x87\xe5\xa0\xfa\xab\xc0\x5c\x9b\xff\x89\xd2\x3f\xd9\x02\xd3\x24\xc7\x99\x03\xb4\x8f\xcb\x8f\x8f\x4b\x01\xf3\xe4\xdd\xb4\x83\x59\x3d\x25\xf0\x00\x38\x66\x98\xf5\xad\xe7\xfa\xad\xe9\x61\x5f\xdc\x50\xd3\x27\x85\xea\x51\xd4\x98\x94\xe4\x5b\xaa\x3d\xc7\x07\xe2\x24\x68\x8c\x64\x08\xb6\x8b\x11",
+       "\xfd\xfe\x4f\x1b\x03\x47\x33\xc2\xc9\x4a\x7b\x36\xe2\xb5\x27\x74\xa9\x5c\x2b\xde\x22\xfc\xdd\xfc\xef\x52\xf7\xfe\xf7\xc6\x7f\x08\xe2\xf7\xb9\xb8\x96\x7e\x44\x7f\x76\xef\x91\x96\x0d\xa7\x62\x88",
+       85 },
+      { GCRY_MD_SHA3_384,
+       "\x68\xc8\xf8\x84\x9b\x12\x0e\x6e\x0c\x99\x69\xa5\x86\x6a\xf5\x91\xa8\x29\xb9\x2f\x33\xcd\x9a\x4a\x31\x96\x95\x7a\x14\x8c\x49\x13\x8e\x1e\x2f\x5c\x76\x19\xa6\xd5\xed\xeb\xe9\x95\xac\xd8\x1e\xc8\xbb\x9c\x7b\x9c\xfc\xa6\x78\xd0\x81\xea\x9e\x25\xa7\x5d\x39\xdb\x04\xe1\x8d\x47\x59\x20\xce\x82\x8b\x94\xe7\x22\x41\xf2\x4d\xb7\x25\x46\xb3\x52\xa0\xe4",
+       "\x48\xd6\x6a\x41\x65\xaa\x54\x52\x8e\xce\x89\xbd\x9a\xa0\x0e\xab\x19\x6f\x32\xdf\xdc\x4d\x76\xf2\x36\x65\x58\x35\x52\x7a\xaa\x16\x42\xe6\xbf\x4e\xdf\x24\xf0\x30\xf5\xee\xef\x07\xfa\x40\xf5\xd2",
+       86 },
+      { GCRY_MD_SHA3_384,
+       "\xb8\xd5\x64\x72\x95\x4e\x31\xfb\x54\xe2\x8f\xca\x74\x3f\x84\xd8\xdc\x34\x89\x1c\xb5\x64\xc6\x4b\x08\xf7\xb7\x16\x36\xde\xbd\x64\xca\x1e\xdb\xdb\xa7\xfc\x5c\x3e\x40\x04\x9c\xe9\x82\xbb\xa8\xc7\xe0\x70\x30\x34\xe3\x31\x38\x46\x95\xe9\xde\x76\xb5\x10\x4f\x2f\xbc\x45\x35\xec\xbe\xeb\xc3\x3b\xc2\x7f\x29\xf1\x8f\x6f\x27\xe8\x02\x3b\x0f\xbb\x6f\x56\x3c",
+       "\x3c\x25\x75\x37\x2c\xe1\xf3\x80\xa6\xe6\x6b\xb0\x75\xfb\xae\x98\xfc\x2e\x6d\x3d\x26\x7a\x20\xff\x03\x13\xab\xc3\xde\x25\x2e\x03\xfd\x5b\xdf\xa8\xbc\x2b\x79\xfc\x87\x4c\xcd\xa4\xab\xdb\xb4\xa6",
+       87 },
+      { GCRY_MD_SHA3_384,
+       "\x0d\x58\xac\x66\x5f\xa8\x43\x42\xe6\x0c\xef\xee\x31\xb1\xa4\xea\xcd\xb0\x92\xf1\x22\xdf\xc6\x83\x09\x07\x7a\xed\x1f\x3e\x52\x8f\x57\x88\x59\xee\x9e\x4c\xef\xb4\xa7\x28\xe9\x46\x32\x49\x27\xb6\x75\xcd\x4f\x4a\xc8\x4f\x64\xdb\x3d\xac\xfe\x85\x0c\x1d\xd1\x87\x44\xc7\x4c\xec\xcd\x9f\xe4\xdc\x21\x40\x85\x10\x8f\x40\x4e\xab\x6d\x8f\x45\x2b\x54\x42\xa4\x7d",
+       "\x0e\xe6\xae\xca\x8d\xd8\x0b\x74\x22\x5a\xc4\x88\x2e\x2b\xc1\xe6\x81\x9c\x9b\x94\xf0\xd0\xbc\x0a\x1e\x21\xaa\xbf\x4b\x11\xcb\x74\xdb\x47\x34\xbc\x8d\x11\x79\xd7\xdc\xef\x53\x5b\xe9\xf3\xda\x28",
+       88 },
+      { GCRY_MD_SHA3_384,
+       "\x17\x55\xe2\xd2\xe5\xd1\xc1\xb0\x15\x64\x56\xb5\x39\x75\x3f\xf4\x16\x65\x1d\x44\x69\x8e\x87\x00\x2d\xcf\x61\xdc\xfa\x2b\x4e\x72\xf2\x64\xd9\xad\x59\x1d\xf1\xfd\xee\x7b\x41\xb2\xeb\x00\x28\x3c\x5a\xeb\xb3\x41\x13\x23\xb6\x72\xea\xa1\x45\xc5\x12\x51\x85\x10\x4f\x20\xf3\x35\x80\x4b\x02\x32\x5b\x6d\xea\x65\x60\x3f\x34\x9f\x4d\x5d\x8b\x78\x2d\xd3\x46\x9c\xcd",
+       "\x80\x27\xe5\x04\x49\x23\xf8\xee\xe1\xdf\x18\x48\x65\xcd\x97\xb6\x35\xa7\x8d\xa1\x99\xfd\x80\xad\x3d\x34\x3a\x5a\xe0\x3d\x1b\x16\x5e\x58\xd1\xb0\xbd\x09\x3e\xf9\x16\xa1\x6d\x66\x41\xbd\xa1\x7c",
+       89 },
+      { GCRY_MD_SHA3_384,
+       "\xb1\x80\xde\x1a\x61\x11\x11\xee\x75\x84\xba\x2c\x4b\x02\x05\x98\xcd\x57\x4a\xc7\x7e\x40\x4e\x85\x3d\x15\xa1\x01\xc6\xf5\xa2\xe5\xc8\x01\xd7\xd8\x5d\xc9\x52\x86\xa1\x80\x4c\x87\x0b\xb9\xf0\x0f\xd4\xdc\xb0\x3a\xa8\x32\x82\x75\x15\x88\x19\xdc\xad\x72\x53\xf3\xe3\xd2\x37\xae\xaa\x79\x79\x26\x8a\x5d\xb1\xc6\xce\x08\xa9\xec\x7c\x25\x79\x78\x3c\x8a\xfc\x1f\x91\xa7",
+       "\x79\x68\x18\xe0\x47\x91\x3d\x5a\xfb\x4a\xe4\xc5\xb7\xc5\xd5\xef\x69\x9a\x3a\x9e\xbe\xfb\x44\x46\x2e\xe8\xfe\x60\x3c\xa5\x62\x89\x73\x36\x9e\x4a\x9d\x8e\x10\x11\x5f\xdd\x75\xc8\x97\x07\xa8\xf9",
+       90 },
+      { GCRY_MD_SHA3_384,
+       "\xcf\x35\x83\xcb\xdf\xd4\xcb\xc1\x70\x63\xb1\xe7\xd9\x0b\x02\xf0\xe6\xe2\xee\x05\xf9\x9d\x77\xe2\x4e\x56\x03\x92\x53\x5e\x47\xe0\x50\x77\x15\x7f\x96\x81\x35\x44\xa1\x70\x46\x91\x4f\x9e\xfb\x64\x76\x2a\x23\xcf\x7a\x49\xfe\x52\xa0\xa4\xc0\x1c\x63\x0c\xfe\x87\x27\xb8\x1f\xb9\x9a\x89\xff\x7c\xc1\x1d\xca\x51\x73\x05\x7e\x04\x17\xb8\xfe\x7a\x9e\xfb\xa6\xd9\x5c\x55\x5f",
+       "\x1e\x96\xef\xf6\x2e\x9f\x46\x4b\x48\x02\x97\x2f\xda\xc7\x7c\x3e\xa1\x13\x1b\x28\x22\x61\x9d\x2c\x5d\x86\x3e\x35\x7d\x09\x45\xc1\x7f\x93\xed\xe6\x6a\xf0\x5d\x46\xe6\x3c\x28\x57\xa5\x4f\x67\xf4",
+       91 },
+      { GCRY_MD_SHA3_384,
+       "\x07\x2f\xc0\x23\x40\xef\x99\x11\x5b\xad\x72\xf9\x2c\x01\xe4\xc0\x93\xb9\x59\x9f\x6c\xfc\x45\xcb\x38\x0e\xe6\x86\xcb\x5e\xb0\x19\xe8\x06\xab\x9b\xd5\x5e\x63\x4a\xb1\x0a\xa6\x2a\x95\x10\xcc\x06\x72\xcd\x3e\xdd\xb5\x89\xc7\xdf\x2b\x67\xfc\xd3\x32\x9f\x61\xb1\xa4\x44\x1e\xca\x87\xa3\x3c\x8f\x55\xda\x4f\xbb\xad\x5c\xf2\xb2\x52\x7b\x8e\x98\x3b\xb3\x1a\x2f\xad\xec\x75\x23",
+       "\x4c\xc4\x1c\x2f\xb7\xd7\x1d\xa1\xad\x36\xd1\x80\x29\xf7\x55\xda\xf3\x42\xe7\x32\xec\x31\xf0\xc0\x6e\x27\x09\x13\x07\x71\x8a\xcb\x53\xfa\x11\x3a\xe5\x08\xdf\x38\xb8\xc9\x68\x34\xde\x33\xf9\xf1",
+       92 },
+      { GCRY_MD_SHA3_384,
+       "\x76\xee\xcf\x95\x6a\x52\x64\x9f\x87\x75\x28\x14\x6d\xe3\x3d\xf2\x49\xcd\x80\x0e\x21\x83\x0f\x65\xe9\x0f\x0f\x25\xca\x9d\x65\x40\xfd\xe4\x06\x03\x23\x0e\xca\x67\x60\xf1\x13\x9c\x7f\x26\x8d\xeb\xa2\x06\x06\x31\xee\xa9\x2b\x1f\xff\x05\xf9\x3f\xd5\x57\x2f\xbe\x29\x57\x9e\xcd\x48\xbc\x3a\x8d\x6c\x2e\xb4\xa6\xb2\x6e\x38\xd6\xc5\xfb\xf2\xc0\x80\x44\xae\xea\x47\x0a\x8f\x2f\x26",
+       "\x9a\x8d\x4b\x56\x04\x21\xc8\x29\x91\xbd\xfc\xa0\x89\x8a\x29\xa5\x9b\xdb\x09\xd2\x0f\x8a\x5b\x27\x90\x96\x72\x3b\xab\x38\x27\x89\xf0\x81\xea\xd5\x0d\x27\x3e\xca\x43\x6c\x52\x6a\xba\x6d\x5c\xfc",
+       93 },
+      { GCRY_MD_SHA3_384,
+       "\x7a\xdc\x0b\x66\x93\xe6\x1c\x26\x9f\x27\x8e\x69\x44\xa5\xa2\xd8\x30\x09\x81\xe4\x00\x22\xf8\x39\xac\x64\x43\x87\xbf\xac\x90\x86\x65\x00\x85\xc2\xcd\xc5\x85\xfe\xa4\x7b\x9d\x2e\x52\xd6\x5a\x2b\x29\xa7\xdc\x37\x04\x01\xef\x5d\x60\xdd\x0d\x21\xf9\xe2\xb9\x0f\xae\x91\x93\x19\xb1\x4b\x8c\x55\x65\xb0\x42\x3c\xef\xb8\x27\xd5\xf1\x20\x33\x02\xa9\xd0\x15\x23\x49\x8a\x4d\xb1\x03\x74",
+       "\x36\x7c\xb3\xfe\x03\xa3\xcb\xb5\x0f\xae\x1f\xe7\xea\x88\x3a\x0a\xe5\x3c\xbe\x77\x2f\x70\x9d\xc5\x50\x5f\x3c\x90\x75\x64\xc0\x8f\xc4\x97\x07\xcf\xf9\x63\x9b\x25\xc7\x46\xb6\x03\x9f\xf4\x8a\xe9",
+       94 },
+      { GCRY_MD_SHA3_384,
+       "\xe1\xff\xfa\x98\x26\xcc\xe8\xb8\x6b\xcc\xef\xb8\x79\x4e\x48\xc4\x6c\xdf\x37\x20\x13\xf7\x82\xec\xed\x1e\x37\x82\x69\xb7\xbe\x2b\x7b\xf5\x13\x74\x09\x22\x61\xae\x12\x0e\x82\x2b\xe6\x85\xf2\xe7\xa8\x36\x64\xbc\xfb\xe3\x8f\xe8\x63\x3f\x24\xe6\x33\xff\xe1\x98\x8e\x1b\xc5\xac\xf5\x9a\x58\x70\x79\xa5\x7a\x91\x0b\xda\x60\x06\x0e\x85\xb5\xf5\xb6\xf7\x76\xf0\x52\x96\x39\xd9\xcc\xe4\xbd",
+       "\xbb\xbd\x05\xd6\x9d\x7a\x08\x2f\xcd\xa8\xed\x53\x5d\x7e\x4e\x5d\xe1\x37\x7b\xd9\x1e\x72\xd4\x2d\xc9\x52\x95\xc9\xdb\x78\x01\x69\xe2\xf9\x62\x0e\xc7\xa5\xaf\xf9\x59\xff\x2d\x94\x6f\xd2\x0a\x72",
+       95 },
+      { GCRY_MD_SHA3_384,
+       "\x69\xf9\xab\xba\x65\x59\x2e\xe0\x1d\xb4\xdc\xe5\x2d\xba\xb9\x0b\x08\xfc\x04\x19\x36\x02\x79\x2e\xe4\xda\xa2\x63\x03\x3d\x59\x08\x15\x87\xb0\x9b\xbe\x49\xd0\xb4\x9c\x98\x25\xd2\x28\x40\xb2\xff\x5d\x9c\x51\x55\xf9\x75\xf8\xf2\xc2\xe7\xa9\x0c\x75\xd2\xe4\xa8\x04\x0f\xe3\x9f\x63\xbb\xaf\xb4\x03\xd9\xe2\x8c\xc3\xb8\x6e\x04\xe3\x94\xa9\xc9\xe8\x06\x5b\xd3\xc8\x5f\xa9\xf0\xc7\x89\x16\x00",
+       "\xbe\x8b\xec\x0c\x2e\xc7\x21\xe0\xc3\x26\x03\x7c\xe8\x6a\x15\x18\xfb\x39\x5c\x3a\x98\x02\xde\x01\xc3\xe2\x34\x26\x8e\xbb\x9a\xc9\xa3\x9a\x6e\x40\x4f\x25\xfb\x7f\xeb\xdc\xf1\xf7\xf2\x5d\xc0\x83",
+       96 },
+      { GCRY_MD_SHA3_384,
+       "\x38\xa1\x0a\x35\x2c\xa5\xae\xdf\xa8\xe1\x9c\x64\x78\x7d\x8e\x9c\x3a\x75\xdb\xf3\xb8\x67\x4b\xfa\xb2\x9b\x5d\xbf\xc1\x5a\x63\xd1\x0f\xae\x66\xcd\x1a\x6e\x6d\x24\x52\xd5\x57\x96\x7e\xaa\xd8\x9a\x4c\x98\x44\x97\x87\xb0\xb3\x16\x4c\xa5\xb7\x17\xa9\x3f\x24\xeb\x0b\x50\x6c\xeb\x70\xcb\xbc\xb8\xd7\x2b\x2a\x72\x99\x3f\x90\x9a\xad\x92\xf0\x44\xe0\xb5\xa2\xc9\xac\x9c\xb1\x6a\x0c\xa2\xf8\x1f\x49",
+       "\x2a\xee\xaf\x29\x2a\xd6\x25\x22\x1b\xa7\x9a\x62\x12\x17\xfd\x1b\x3f\x89\x78\xba\x83\xfe\x7f\xf1\x3b\x38\x57\x4f\xcf\xaf\xfb\xd2\x07\x29\x88\x54\xb6\xf9\xc2\x7d\x66\x77\x49\x42\x04\x22\x1f\xda",
+       97 },
+      { GCRY_MD_SHA3_384,
+       "\x6d\x8c\x6e\x44\x9b\xc1\x36\x34\xf1\x15\x74\x9c\x24\x8c\x17\xcd\x14\x8b\x72\x15\x7a\x2c\x37\xbf\x89\x69\xea\x83\xb4\xd6\xba\x8c\x0e\xe2\x71\x1c\x28\xee\x11\x49\x5f\x43\x04\x95\x96\x52\x0c\xe4\x36\x00\x4b\x02\x6b\x6c\x1f\x72\x92\xb9\xc4\x36\xb0\x55\xcb\xb7\x2d\x53\x0d\x86\x0d\x12\x76\xa1\x50\x2a\x51\x40\xe3\xc3\xf5\x4a\x93\x66\x3e\x4d\x20\xed\xec\x32\xd2\x84\xe2\x55\x64\xf6\x24\x95\x5b\x52",
+       "\x9a\x17\x61\xc5\x75\x9c\xe6\x7c\x9c\x09\x3e\xc5\xc8\x31\xc1\xff\x7c\xab\x64\xac\x7c\x80\x02\x06\x6e\xdc\xae\xd0\x44\xde\xf5\x7c\xea\x3e\xf6\xbe\x98\x57\x83\x63\xd2\xce\x3d\x1f\x5b\xa4\x48\xf8",
+       98 },
+      { GCRY_MD_SHA3_384,
+       "\x6e\xfc\xbc\xaf\x45\x1c\x12\x9d\xbe\x00\xb9\xce\xf0\xc3\x74\x9d\x3e\xe9\xd4\x1c\x7b\xd5\x00\xad\xe4\x0c\xdc\x65\xde\xdb\xbb\xad\xb8\x85\xa5\xb1\x4b\x32\xa0\xc0\xd0\x87\x82\x52\x01\xe3\x03\x28\x8a\x73\x38\x42\xfa\x7e\x59\x9c\x0c\x51\x4e\x07\x8f\x05\xc8\x21\xc7\xa4\x49\x8b\x01\xc4\x00\x32\xe9\xf1\x87\x2a\x1c\x92\x5f\xa1\x7c\xe2\x53\xe8\x93\x5e\x4c\x3c\x71\x28\x22\x42\xcb\x71\x6b\x20\x89\xcc\xc1",
+       "\x4a\x24\xa1\xaf\x68\xdb\x65\xc3\x97\x74\x31\xee\x81\x09\x2c\x77\x6f\x7c\xb3\x3d\x6f\x08\x94\x01\x00\xea\x24\x0a\x2d\x1f\x86\x23\xa4\x1d\x07\xce\x99\x37\xbc\xbe\xc8\xca\x10\x72\xa1\xa7\x8e\x8b",
+       99 },
+      { GCRY_MD_SHA3_384,
+       "\x43\x3c\x53\x03\x13\x16\x24\xc0\x02\x1d\x86\x8a\x30\x82\x54\x75\xe8\xd0\xbd\x30\x52\xa0\x22\x18\x03\x98\xf4\xca\x44\x23\xb9\x82\x14\xb6\xbe\xaa\xc2\x1c\x88\x07\xa2\xc3\x3f\x8c\x93\xbd\x42\xb0\x92\xcc\x1b\x06\xce\xdf\x32\x24\xd5\xed\x1e\xc2\x97\x84\x44\x4f\x22\xe0\x8a\x55\xaa\x58\x54\x2b\x52\x4b\x02\xcd\x3d\x5d\x5f\x69\x07\xaf\xe7\x1c\x5d\x74\x62\x22\x4a\x3f\x9d\x9e\x53\xe7\xe0\x84\x6d\xcb\xb4\xce",
+       "\x92\x8e\x94\xd1\x9f\xc6\x00\x65\xa5\xef\x7e\x48\x01\x83\x87\xc8\x0f\x2d\x35\x0f\x30\x6d\x0f\x61\x01\x73\x71\x9d\x5c\x87\x4d\x4a\x8a\xcc\x34\x0f\xea\xd4\xbe\x35\x7e\x1f\x78\x12\x41\x98\xad\x77",
+       100 },
+      { GCRY_MD_SHA3_384,
+       "\xa8\x73\xe0\xc6\x7c\xa6\x39\x02\x6b\x66\x83\x00\x8f\x7a\xa6\x32\x4d\x49\x79\x55\x0e\x9b\xce\x06\x4c\xa1\xe1\xfb\x97\xa3\x0b\x14\x7a\x24\xf3\xf6\x66\xc0\xa7\x2d\x71\x34\x8e\xde\x70\x1c\xf2\xd1\x7e\x22\x53\xc3\x4d\x1e\xc3\xb6\x47\xdb\xce\xf2\xf8\x79\xf4\xeb\x88\x1c\x48\x30\xb7\x91\x37\x8c\x90\x1e\xb7\x25\xea\x5c\x17\x23\x16\xc6\xd6\x06\xe0\xaf\x7d\xf4\xdf\x7f\x76\xe4\x90\xcd\x30\xb2\xba\xdf\x45\x68\x5f",
+       "\x78\xa1\x8d\x62\xf8\xa7\xef\xf5\xc6\xdd\x75\xb8\xcb\x07\x3f\xd3\x0e\xe6\x8c\x87\x8c\x2e\xc5\x8a\xad\x1c\x5d\xd0\xeb\x0a\xe4\x36\x98\xa6\x17\xbb\x0c\x67\x0f\xce\x2a\xa0\x98\xe0\xad\xf4\x25\xb2",
+       101 },
+      { GCRY_MD_SHA3_384,
+       "\x00\x69\x17\xb6\x4f\x9d\xcd\xf1\xd2\xd8\x7c\x8a\x61\x73\xb6\x4f\x65\x87\x16\x8e\x80\xfa\xa8\x0f\x82\xd8\x4f\x60\x30\x1e\x56\x1e\x31\x2d\x9f\xbc\xe6\x2f\x39\xa6\xfb\x47\x6e\x01\xe9\x25\xf2\x6b\xcc\x91\xde\x62\x14\x49\xbe\x65\x04\xc5\x04\x83\x0a\xae\x39\x40\x96\xc8\xfc\x76\x94\x65\x10\x51\x36\x5d\x4e\xe9\x07\x01\x01\xec\x9b\x68\x08\x6f\x2e\xa8\xf8\xab\x7b\x81\x1e\xa8\xad\x93\x4d\x5c\x9b\x62\xc6\x0a\x47\x71",
+       "\xee\xeb\x56\xc3\xe5\x4f\xa8\x33\xb9\x85\xef\xa5\x92\x3c\x3f\x02\x25\xf4\x19\x66\x4c\xed\xd8\x98\xc7\x9f\x64\xd7\x2d\x2a\xd4\xb1\x25\xa3\x8b\xe0\x20\x18\x46\xc4\x42\xea\xf0\x05\x1d\x51\x6d\xc9",
+       102 },
+      { GCRY_MD_SHA3_384,
+       "\xf1\x3c\x97\x2c\x52\xcb\x3c\xc4\xa4\xdf\x28\xc9\x7f\x2d\xf1\x1c\xe0\x89\xb8\x15\x46\x6b\xe8\x88\x63\x24\x3e\xb3\x18\xc2\xad\xb1\xa4\x17\xcb\x10\x41\x30\x85\x98\x54\x17\x20\x19\x7b\x9b\x1c\xb5\xba\x23\x18\xbd\x55\x74\xd1\xdf\x21\x74\xaf\x14\x88\x41\x49\xba\x9b\x2f\x44\x6d\x60\x9d\xf2\x40\xce\x33\x55\x99\x95\x7b\x8e\xc8\x08\x76\xd9\xa0\x85\xae\x08\x49\x07\xbc\x59\x61\xb2\x0b\xf5\xf6\xca\x58\xd5\xda\xb3\x8a\xdb",
+       "\x0a\x83\x4e\x11\x1b\x4e\x84\x0e\x78\x7c\x19\x74\x84\x65\xa4\x7d\x88\xb3\xf0\xf3\xda\xaf\x15\xdb\x25\x53\x6b\xdc\x60\x78\xfa\x9c\x05\xe6\xc9\x53\x83\x02\x74\x22\x39\x68\x84\x7d\xa8\xbf\xd2\x0d",
+       103 },
+      { GCRY_MD_SHA3_384,
+       "\xe3\x57\x80\xeb\x97\x99\xad\x4c\x77\x53\x5d\x4d\xdb\x68\x3c\xf3\x3e\xf3\x67\x71\x53\x27\xcf\x4c\x4a\x58\xed\x9c\xbd\xcd\xd4\x86\xf6\x69\xf8\x01\x89\xd5\x49\xa9\x36\x4f\xa8\x2a\x51\xa5\x26\x54\xec\x72\x1b\xb3\xaa\xb9\x5d\xce\xb4\xa8\x6a\x6a\xfa\x93\x82\x6d\xb9\x23\x51\x7e\x92\x8f\x33\xe3\xfb\xa8\x50\xd4\x56\x60\xef\x83\xb9\x87\x6a\xcc\xaf\xa2\xa9\x98\x7a\x25\x4b\x13\x7c\x6e\x14\x0a\x21\x69\x1e\x10\x69\x41\x38\x48",
+       "\xd1\xc0\xfa\x85\xc8\xd1\x83\xbe\xff\x99\xad\x9d\x75\x2b\x26\x3e\x28\x6b\x47\x7f\x79\xf0\x71\x0b\x01\x03\x17\x01\x73\x97\x81\x33\x44\xb9\x9d\xaf\x3b\xb7\xb1\xbc\x5e\x8d\x72\x2b\xac\x85\x94\x3a",
+       104 },
+      { GCRY_MD_SHA3_384,
+       "\x64\xec\x02\x1c\x95\x85\xe0\x1f\xfe\x6d\x31\xbb\x50\xd4\x4c\x79\xb6\x99\x3d\x72\x67\x81\x63\xdb\x47\x49\x47\xa0\x53\x67\x46\x19\xd1\x58\x01\x6a\xdb\x24\x3f\x5c\x8d\x50\xaa\x92\xf5\x0a\xb3\x6e\x57\x9f\xf2\xda\xbb\x78\x0a\x2b\x52\x93\x70\xda\xa2\x99\x20\x7c\xfb\xcd\xd3\xa9\xa2\x50\x06\xd1\x9c\x4f\x1f\xe3\x3e\x4b\x1e\xae\xc3\x15\xd8\xc6\xee\x1e\x73\x06\x23\xfd\x19\x41\x87\x5b\x92\x4e\xb5\x7d\x6d\x0c\x2e\xdc\x4e\x78\xd6",
+       "\x6a\xed\xcf\x44\x26\xb2\x48\x3c\x0d\x0d\x04\x69\x5b\xcc\x05\x2b\xed\xd0\x4f\xa4\xd1\x7a\x1b\xbb\x27\x97\xf6\x27\x2f\xa4\x76\xbf\xc1\x38\xe4\x09\x14\x09\xfe\xb1\xac\x0e\x8b\xff\x35\x0a\x66\x63",
+       105 },
+      { GCRY_MD_SHA3_384,
+       "\x59\x54\xba\xb5\x12\xcf\x32\x7d\x66\xb5\xd9\xf2\x96\x18\x00\x80\x40\x26\x24\xad\x76\x28\x50\x6b\x55\x5e\xea\x83\x82\x56\x23\x24\xcf\x45\x2f\xba\x4a\x21\x30\xde\x3e\x16\x5d\x11\x83\x1a\x27\x0d\x9c\xb9\x7c\xe8\xc2\xd3\x2a\x96\xf5\x0d\x71\x60\x0b\xb4\xca\x26\x8c\xf9\x8e\x90\xd6\x49\x6b\x0a\x66\x19\xa5\xa8\xc6\x3d\xb6\xd8\xa0\x63\x4d\xfc\x6c\x7e\xc8\xea\x9c\x00\x6b\x6c\x45\x6f\x1b\x20\xcd\x19\xe7\x81\xaf\x20\x45\x4a\xc8\x80",
+       "\xac\xb7\x01\x3c\xe7\x51\x24\x38\x81\x87\xdc\x0e\x74\x30\xcb\x74\xa3\x14\xd6\x01\xb6\xc8\xd7\xa7\xde\x5c\xf0\x31\x97\xa8\x4f\x78\x74\xff\x05\x88\x08\x57\x5c\xb2\xf1\x01\x85\xf5\x61\xbb\x06\xb1",
+       106 },
+      { GCRY_MD_SHA3_384,
+       "\x03\xd9\xf9\x2b\x2c\x56\x57\x09\xa5\x68\x72\x4a\x0a\xff\x90\xf8\xf3\x47\xf4\x3b\x02\x33\x8f\x94\xa0\x3e\xd3\x2e\x6f\x33\x66\x6f\xf5\x80\x2d\xa4\xc8\x1b\xdc\xe0\xd0\xe8\x6c\x04\xaf\xd4\xed\xc2\xfc\x8b\x41\x41\xc2\x97\x5b\x6f\x07\x63\x9b\x19\x94\xc9\x73\xd9\xa9\xaf\xce\x3d\x9d\x36\x58\x62\x00\x34\x98\x51\x3b\xfa\x16\x6d\x26\x29\xe3\x14\xd9\x74\x41\x66\x7b\x00\x74\x14\xe7\x39\xd7\xfe\xbf\x0f\xe3\xc3\x2c\x17\xaa\x18\x8a\x86\x83",
+       "\xf9\x47\x46\x9d\xb7\x12\xea\x26\xf2\x5f\x70\x9f\xf7\x87\x91\x36\xea\x2a\x79\xe0\xa2\xd0\xed\x5e\xe4\xad\xf0\xe1\x67\xf1\x06\xbc\x41\x0c\x93\xae\x1d\x98\x6e\xc2\x11\xe0\xfd\x9a\x40\x74\x18\x57",
+       107 },
+      { GCRY_MD_SHA3_384,
+       "\xf3\x1e\x8b\x4f\x9e\x06\x21\xd5\x31\xd2\x2a\x38\x0b\xe5\xd9\xab\xd5\x6f\xae\xc5\x3c\xbd\x39\xb1\xfa\xb2\x30\xea\x67\x18\x44\x40\xe5\xb1\xd1\x54\x57\xbd\x25\xf5\x62\x04\xfa\x91\x7f\xa4\x8e\x66\x90\x16\xcb\x48\xc1\xff\xc1\xe1\xe4\x52\x74\xb3\xb4\x73\x79\xe0\x0a\x43\x84\x3c\xf8\x60\x1a\x55\x51\x41\x1e\xc1\x25\x03\xe5\xaa\xc4\x3d\x86\x76\xa1\xb2\x29\x7e\xc7\xa0\x80\x0d\xbf\xee\x04\x29\x2e\x93\x7f\x21\xc0\x05\xf1\x74\x11\x47\x30\x41",
+       "\x65\x98\x9b\xf4\xeb\xbf\x4c\x21\xb3\xdd\x34\x55\x1d\x3f\x61\x67\x91\x02\x36\x67\x1b\xb7\xf3\x48\xdc\x55\x2a\xdb\x80\x28\xa4\x68\xfa\x40\xef\x4a\x8c\x12\x27\xa1\xa4\x1c\x28\x10\x5e\x64\xac\x20",
+       108 },
+      { GCRY_MD_SHA3_384,
+       "\x75\x8e\xa3\xfe\xa7\x38\x97\x3d\xb0\xb8\xbe\x7e\x59\x9b\xbe\xf4\x51\x93\x73\xd6\xe6\xdc\xd7\x19\x5e\xa8\x85\xfc\x99\x1d\x89\x67\x62\x99\x27\x59\xc2\xa0\x90\x02\x91\x2f\xb0\x8e\x0c\xb5\xb7\x6f\x49\x16\x2a\xeb\x8c\xf8\x7b\x17\x2c\xf3\xad\x19\x02\x53\xdf\x61\x2f\x77\xb1\xf0\xc5\x32\xe3\xb5\xfc\x99\xc2\xd3\x1f\x8f\x65\x01\x16\x95\xa0\x87\xa3\x5e\xe4\xee\xe5\xe3\x34\xc3\x69\xd8\xee\x5d\x29\xf6\x95\x81\x5d\x86\x6d\xa9\x9d\xf3\xf7\x94\x03",
+       "\xb7\x7a\x69\xe3\x73\xaf\x0f\x73\x3c\xda\xd3\x99\xc9\xb1\x26\x42\xa0\x46\xe1\xa7\x89\x3d\x33\x82\x94\x3a\x83\x67\xd3\x77\x40\xdf\x53\x91\x6f\x6d\xaf\x90\x51\x7b\x39\x62\x1c\x14\x34\x37\x54\xa2",
+       109 },
+      { GCRY_MD_SHA3_384,
+       "\x47\xc6\xe0\xc2\xb7\x49\x48\x46\x59\x21\x86\x88\x04\xf0\xf7\xbd\x50\xdd\x32\x35\x83\xdc\x78\x4f\x99\x8a\x93\xcd\x1c\xa4\xc6\xef\x84\xd4\x1d\xc8\x1c\x2c\x40\xf3\x4b\x5b\xee\x6a\x93\x86\x7b\x3b\xdb\xa0\x05\x2c\x5f\x59\xe6\xf3\x65\x79\x18\xc3\x82\xe7\x71\xd3\x31\x09\x12\x2c\xc8\xbb\x0e\x1e\x53\xc4\xe3\xd1\x3b\x43\xce\x44\x97\x0f\x5e\x0c\x07\x9d\x2a\xd7\xd7\xa3\x54\x9c\xd7\x57\x60\xc2\x1b\xb1\x5b\x44\x75\x89\xe8\x6e\x8d\x76\xb1\xe9\xce\xd2",
+       "\x3d\x14\xb6\xfa\xe6\x15\x6e\x78\x76\x36\x78\x97\xa4\x92\x69\x18\x1e\xa5\x8c\xc3\xca\x96\x21\xc0\xf8\x1d\x6a\x5f\xb6\xf6\x15\x68\x0d\x90\x9b\x29\xf6\xaf\x7e\x62\xfa\xd0\x4d\x70\x04\x6b\xe9\x97",
+       110 },
+      { GCRY_MD_SHA3_384,
+       "\xf6\x90\xa1\x32\xab\x46\xb2\x8e\xdf\xa6\x47\x92\x83\xd6\x44\x4e\x37\x1c\x64\x59\x10\x8a\xfd\x9c\x35\xdb\xd2\x35\xe0\xb6\xb6\xff\x4c\x4e\xa5\x8e\x75\x54\xbd\x00\x24\x60\x43\x3b\x21\x64\xca\x51\xe8\x68\xf7\x94\x7d\x7d\x7a\x0d\x79\x2e\x4a\xbf\x0b\xe5\xf4\x50\x85\x3c\xc4\x0d\x85\x48\x5b\x2b\x88\x57\xea\x31\xb5\xea\x6e\x4c\xcf\xa2\xf3\xa7\xef\x33\x80\x06\x6d\x7d\x89\x79\xfd\xac\x61\x8a\xad\x3d\x7e\x88\x6d\xea\x4f\x00\x5a\xe4\xad\x05\xe5\x06\x5f",
+       "\x45\x6a\xd0\x19\x08\xe1\x87\xca\x2c\xe9\xe7\xa4\xda\xed\x87\x88\xc9\x09\xe9\xbc\x97\x4e\xfd\x1c\x9a\x44\xac\x36\xdb\x9b\x6d\xa9\x85\xc9\x47\xc7\xe0\xa4\x7a\xb2\x7b\xf1\x0c\xd7\x60\xfa\x48\xaf",
+       111 },
+      { GCRY_MD_SHA3_384,
+       "\x58\xd6\xa9\x9b\xc6\x45\x88\x24\xb2\x56\x91\x67\x70\xa8\x41\x70\x40\x72\x1c\xcc\xfd\x4b\x79\xea\xcd\x8b\x65\xa3\x76\x7c\xe5\xba\x7e\x74\x10\x4c\x98\x5a\xc5\x6b\x8c\xc9\xae\xbd\x16\xfe\xbd\x4c\xda\x5a\xdb\x13\x0b\x0f\xf2\x32\x9c\xc8\xd6\x11\xeb\x14\xda\xc2\x68\xa2\xf9\xe6\x33\xc9\x9d\xe3\x39\x97\xfe\xa4\x1c\x52\xa7\xc5\xe1\x31\x7d\x5b\x5d\xae\xd3\x5e\xba\x7d\x5a\x60\xe4\x5d\x1f\xa7\xea\xab\xc3\x5f\x5c\x2b\x0a\x0f\x23\x79\x23\x19\x53\x32\x2c\x4e",
+       "\xc2\x6b\xda\xc4\x54\xe1\xad\xc0\xd0\x90\xd0\xc5\x25\x4a\x29\x96\x66\x11\xb6\x67\x30\x14\xcb\xac\xa2\x4d\x26\xb6\xf6\x3e\xc7\xe8\xf9\x93\xba\x3d\xf7\xdf\x89\x77\x0e\x90\x2d\x5f\x65\x74\xf6\xa8",
+       112 },
+      { GCRY_MD_SHA3_384,
+       "\xbe\xfa\xb5\x74\x39\x6d\x7f\x8b\x67\x05\xe2\xd5\xb5\x8b\x2c\x1c\x82\x0b\xb2\x4e\x3f\x4b\xae\x3e\x8f\xbc\xd3\x6d\xbf\x73\x4e\xe1\x4e\x5d\x6a\xb9\x72\xae\xdd\x35\x40\x23\x54\x66\xe8\x25\x85\x0e\xe4\xc5\x12\xea\x97\x95\xab\xfd\x33\xf3\x30\xd9\xfd\x7f\x79\xe6\x2b\xbb\x63\xa6\xea\x85\xde\x15\xbe\xae\xea\x6f\x8d\x20\x4a\x28\x95\x60\x59\xe2\x63\x2d\x11\x86\x1d\xfb\x0e\x65\xbc\x07\xac\x8a\x15\x93\x88\xd5\xc3\x27\x7e\x22\x72\x86\xf6\x5f\xf5\xe5\xb5\xae\xc1",
+       "\x1d\x85\xbf\x9a\xa2\xb6\xdc\xc3\x10\x5e\x7d\x7f\x91\x06\x9f\x01\xe4\xc9\x98\xd6\xf0\x3b\x77\x65\x0d\x75\x83\x9d\x65\xa7\xa0\x49\x19\x6f\xd9\x35\xaf\xef\xfd\xeb\x65\x7b\xc8\xf9\x6b\x7c\x17\xb5",
+       113 },
+      { GCRY_MD_SHA3_384,
+       "\x8e\x58\x14\x4f\xa9\x17\x9d\x68\x64\x78\x62\x2c\xe4\x50\xc7\x48\x26\x0c\x95\xd1\xba\x43\xb8\xf9\xb5\x9a\xbe\xca\x8d\x93\x48\x8d\xa7\x34\x63\xef\x40\x19\x8b\x4d\x16\xfb\x0b\x07\x07\x20\x13\x47\xe0\x50\x6f\xf1\x9d\x01\xbe\xa0\xf4\x2b\x8a\xf9\xe7\x1a\x1f\x1b\xd1\x68\x78\x10\x69\xd4\xd3\x38\xfd\xef\x00\xbf\x41\x9f\xbb\x00\x30\x31\xdf\x67\x1f\x4a\x37\x97\x95\x64\xf6\x92\x82\xde\x9c\x65\x40\x78\x47\xdd\x0d\xa5\x05\xab\x16\x41\xc0\x2d\xea\x4f\x0d\x83\x49\x86",
+       "\x08\x5c\xfa\x58\x1c\xf3\xf4\xf1\x94\x16\xbe\xe3\xed\x5a\xc2\x54\x46\x62\xaa\x51\xbd\xf1\xd2\xe3\x48\xd9\xbc\xc2\x73\x43\x48\x7d\xf2\x0b\x18\xd9\xf6\xfb\x64\x56\x58\x68\x50\x4a\x68\x05\xd1\x76",
+       114 },
+      { GCRY_MD_SHA3_384,
+       "\xb5\x5c\x10\xea\xe0\xec\x68\x4c\x16\xd1\x34\x63\xf2\x92\x91\xbf\x26\xc8\x2e\x2f\xa0\x42\x2a\x99\xc7\x1d\xb4\xaf\x14\xdd\x9c\x7f\x33\xed\xa5\x2f\xd7\x3d\x01\x7c\xc0\xf2\xdb\xe7\x34\xd8\x31\xf0\xd8\x20\xd0\x6d\x5f\x89\xda\xcc\x48\x57\x39\x14\x4f\x8c\xfd\x47\x99\x22\x3b\x1a\xff\x90\x31\xa1\x05\xcb\x6a\x02\x9b\xa7\x1e\x6e\x58\x67\xd8\x5a\x55\x49\x91\xc3\x8d\xf3\xc9\xef\x8c\x1e\x1e\x9a\x76\x30\xbe\x61\xca\xab\xca\x69\x28\x0c\x39\x9c\x1f\xb7\xa1\x2d\x12\xae\xfc",
+       "\x37\x60\x88\xf0\x90\x39\xca\xa4\x0b\xf1\x9f\xf5\xe5\xf1\x93\xfc\x9e\xcb\x61\x16\xa0\xac\xb3\x23\x7a\xaa\xb6\xcd\x80\x7b\xd7\xaf\x45\xd8\x04\xd8\x37\xa1\x8d\x2b\xd9\xa8\xc3\xda\xa3\xa1\xd1\x53",
+       115 },
+      { GCRY_MD_SHA3_384,
+       "\x2e\xee\xa6\x93\xf5\x85\xf4\xed\x6f\x6f\x88\x65\xbb\xae\x47\xa6\x90\x8a\xec\xd7\xc4\x29\xe4\xbe\xc4\xf0\xde\x1d\x0c\xa0\x18\x3f\xa2\x01\xa0\xcb\x14\xa5\x29\xb7\xd7\xac\x0e\x6f\xf6\x60\x7a\x32\x43\xee\x9f\xb1\x1b\xcf\x3e\x23\x04\xfe\x75\xff\xcd\xdd\x6c\x5c\x2e\x2a\x4c\xd4\x5f\x63\xc9\x62\xd0\x10\x64\x50\x58\xd3\x65\x71\x40\x4a\x6d\x2b\x4f\x44\x75\x54\x34\xd7\x69\x98\xe8\x34\x09\xc3\x20\x5a\xa1\x61\x5d\xb4\x40\x57\xdb\x99\x12\x31\xd2\xcb\x42\x62\x45\x74\xf5\x45",
+       "\xcd\x40\xb3\x5f\xbd\x90\xb0\x4d\x06\x41\xf7\x10\x88\xf7\xc6\x15\x9d\x8e\xb1\x6d\xe8\xaa\xe0\x9f\x35\x58\x77\xa0\x33\x3b\x53\x15\x0b\x81\xd3\x6c\x5c\x24\x46\xbf\x5a\xc4\x62\xef\x84\xd4\xe5\x72",
+       116 },
+      { GCRY_MD_SHA3_384,
+       "\xda\xb1\x1d\xc0\xb0\x47\xdb\x04\x20\xa5\x85\xf5\x6c\x42\xd9\x31\x75\x56\x28\x52\x42\x84\x99\xf6\x6a\x0d\xb8\x11\xfc\xdd\xda\xb2\xf7\xcd\xff\xed\x15\x43\xe5\xfb\x72\x11\x0b\x64\x68\x6b\xc7\xb6\x88\x7a\x53\x8a\xd4\x4c\x05\x0f\x1e\x42\x63\x1b\xc4\xec\x8a\x9f\x2a\x04\x71\x63\xd8\x22\xa3\x89\x89\xee\x4a\xab\x01\xb4\xc1\xf1\x61\xb0\x62\xd8\x73\xb1\xcf\xa3\x88\xfd\x30\x15\x14\xf6\x22\x24\x15\x7b\x9b\xef\x42\x3c\x77\x83\xb7\xaa\xc8\xd3\x0d\x65\xcd\x1b\xba\x8d\x68\x9c\x2d",
+       "\xdb\x14\x44\x24\x00\x59\x78\x71\xfa\x56\xd1\x0f\x53\xbe\x7b\xb4\x00\x2c\x44\x62\x4c\x44\xe8\x9c\x99\xb9\x51\x22\x67\x6a\x76\xff\x28\x84\x02\x85\x23\x9e\x2e\x4f\xbf\xb7\x51\xe4\x17\x95\x77\xd8",
+       117 },
+      { GCRY_MD_SHA3_384,
+       "\x42\xe9\x9a\x2f\x80\xae\xe0\xe0\x01\x27\x9a\x24\x34\xf7\x31\xe0\x1d\x34\xa4\x4b\x1a\x81\x01\x72\x69\x21\xc0\x59\x0c\x30\xf3\x12\x0e\xb8\x30\x59\xf3\x25\xe8\x94\xa5\xac\x95\x9d\xca\x71\xce\x22\x14\x79\x99\x16\x42\x4e\x85\x9d\x27\xd7\x89\x43\x7b\x9d\x27\x24\x0b\xf8\xc3\x5a\xdb\xaf\xce\xcc\x32\x2b\x48\xaa\x20\x5b\x29\x39\x62\xd8\x58\x65\x2a\xba\xcb\xd5\x88\xbc\xf6\xcb\xc3\x88\xd0\x99\x3b\xd6\x22\xf9\x6e\xd5\x46\x14\xc2\x5b\x6a\x9a\xa5\x27\x58\x9e\xaa\xff\xcf\x17\xdd\xf7",
+       "\x45\x09\xad\xb6\x17\x7b\xc6\xde\xbc\xa7\xe3\x69\x48\xf0\x70\x01\x15\x9a\x57\xec\x8c\xca\x2b\x76\xc7\x70\x73\x5c\x5b\xcc\xc6\x79\xda\x6a\xb4\xe6\x4d\x91\x5d\x0e\x1a\x75\x4c\x3f\xda\x11\xb5\x24",
+       118 },
+      { GCRY_MD_SHA3_384,
+       "\x3c\x9b\x46\x45\x0c\x0f\x2c\xae\x8e\x38\x23\xf8\xbd\xb4\x27\x7f\x31\xb7\x44\xce\x2e\xb1\x70\x54\xbd\xdc\x6d\xff\x36\xaf\x7f\x49\xfb\x8a\x23\x20\xcc\x3b\xdf\x8e\x0a\x2e\xa2\x9a\xd3\xa5\x5d\xe1\x16\x5d\x21\x9a\xde\xdd\xb5\x17\x52\x53\xe2\xd1\x48\x9e\x9b\x6f\xdd\x02\xe2\xc3\xd3\xa4\xb5\x4d\x60\xe3\xa4\x73\x34\xc3\x79\x13\xc5\x69\x53\x78\xa6\x69\xe9\xb7\x2d\xec\x32\xaf\x54\x34\xf9\x3f\x46\x17\x6e\xbf\x04\x4c\x47\x84\x46\x7c\x70\x04\x70\xd0\xc0\xb4\x0c\x8a\x08\x8c\x81\x58\x16",
+       "\x19\x3a\xf7\x1b\xdd\x22\x8a\xb3\xe8\xae\x50\xe1\xb1\xcb\xf1\x98\x4b\x0a\xf9\x2a\xac\x5a\x71\xcb\xe6\x18\xaf\xd4\x18\x7d\xed\x6b\x46\x14\x11\xa3\x9e\x72\xea\x4e\x21\x3f\xe0\xa5\x23\x1c\x49\x8d",
+       119 },
+      { GCRY_MD_SHA3_384,
+       "\xd1\xe6\x54\xb7\x7c\xb1\x55\xf5\xc7\x79\x71\xa6\x4d\xf9\xe5\xd3\x4c\x26\xa3\xca\xd6\xc7\xf6\xb3\x00\xd3\x9d\xeb\x19\x10\x09\x46\x91\xad\xaa\x09\x5b\xe4\xba\x5d\x86\x69\x0a\x97\x64\x28\x63\x5d\x55\x26\xf3\xe9\x46\xf7\xdc\x3b\xd4\xdb\xc7\x89\x99\xe6\x53\x44\x11\x87\xa8\x1f\x9a\xdc\xd5\xa3\xc5\xf2\x54\xbc\x82\x56\xb0\x15\x8f\x54\x67\x3d\xcc\x12\x32\xf6\xe9\x18\xeb\xfc\x6c\x51\xce\x67\xea\xeb\x04\x2d\x9f\x57\xee\xc4\xbf\xe9\x10\xe1\x69\xaf\x78\xb3\xde\x48\xd1\x37\xdf\x4f\x28\x40",
+       "\x3e\x41\x95\x69\xa4\x19\x7b\xb7\x1b\xaf\x41\x6b\x38\x77\x2e\xed\xd9\xc1\xd5\xa3\x25\x21\x11\x60\x9f\x0f\xf8\xa1\x8a\x74\x9d\x5a\x56\x14\x3a\x14\x92\x5a\x82\xcd\x35\xc4\x44\x00\xa4\x9a\xfd\xfb",
+       120 },
+      { GCRY_MD_SHA3_384,
+       "\x62\x6f\x68\xc1\x8a\x69\xa6\x59\x01\x59\xa9\xc4\x6b\xe0\x3d\x59\x65\x69\x8f\x2d\xac\x3d\xe7\x79\xb8\x78\xb3\xd9\xc4\x21\xe0\xf2\x1b\x95\x5a\x16\xc7\x15\xc1\xec\x1e\x22\xce\x3e\xb6\x45\xb8\xb4\xf2\x63\xf6\x06\x60\xea\x30\x28\x98\x1e\xeb\xd6\xc8\xc3\xa3\x67\x28\x5b\x69\x1c\x8e\xe5\x69\x44\xa7\xcd\x12\x17\x99\x7e\x1d\x9c\x21\x62\x0b\x53\x6b\xdb\xd5\xde\x89\x25\xff\x71\xde\xc6\xfb\xc0\x66\x24\xab\x6b\x21\xe3\x29\x81\x3d\xe9\x0d\x1e\x57\x2d\xfb\x89\xa1\x81\x20\xc3\xf6\x06\x35\x5d\x25",
+       "\x62\x15\xc0\x70\xd0\xcb\x38\x8a\x13\x47\x66\x03\x5c\x4b\xa9\x51\x43\xe6\x08\xd1\x5c\xaf\x74\x27\x96\x30\x4f\xfa\x1a\x62\xe5\x56\x60\xab\x9a\xb1\xf6\x53\x8b\x4a\xf1\xf3\xea\x89\xbe\x7d\x51\xff",
+       121 },
+      { GCRY_MD_SHA3_384,
+       "\x65\x1a\x6f\xb3\xc4\xb8\x0c\x7c\x68\xc6\x01\x16\x75\xe6\x09\x4e\xb5\x6a\xbf\x5f\xc3\x05\x73\x24\xeb\xc6\x47\x78\x25\x06\x1f\x9f\x27\xe7\xa9\x46\x33\xab\xd1\xfa\x59\x8a\x74\x6e\x4a\x57\x7c\xaf\x52\x4c\x52\xec\x17\x88\x47\x1f\x92\xb8\xc3\x7f\x23\x79\x5c\xa1\x9d\x55\x9d\x44\x6c\xab\x16\xcb\xcd\xce\x90\xb7\x9f\xa1\x02\x6c\xee\x77\xbf\x4a\xb1\xb5\x03\xc5\xb9\x4c\x22\x56\xad\x75\xb3\xea\xc6\xfd\x5d\xcb\x96\xac\xa4\xb0\x3a\x83\x4b\xfb\x4e\x9a\xf9\x88\xce\xcb\xf2\xae\x59\x7c\xb9\x09\x79\x40",
+       "\x0e\x27\xab\xad\x85\x25\x5a\x66\x21\x77\x22\xb7\xd4\xe0\x32\xbf\x29\xf6\x38\xba\xe9\x65\xb9\x9f\x8e\xaf\x30\x90\x71\xff\x8c\x10\x7f\x5b\x6b\xbb\x6a\xb1\x98\x52\x28\xe6\x97\xde\x60\x59\x5d\xf6",
+       122 },
+      { GCRY_MD_SHA3_384,
+       "\x8a\xaf\x07\x2f\xce\x8a\x2d\x96\xbc\x10\xb3\xc9\x1c\x80\x9e\xe9\x30\x72\xfb\x20\x5c\xa7\xf1\x0a\xbd\x82\xec\xd8\x2c\xf0\x40\xb1\xbc\x49\xea\x13\xd1\x85\x78\x15\xc0\xe9\x97\x81\xde\x3a\xdb\xb5\x44\x3c\xe1\xc8\x97\xe5\x51\x88\xce\xaf\x22\x1a\xa9\x68\x16\x38\xde\x05\xae\x1b\x32\x29\x38\xf4\x6b\xce\x51\x54\x3b\x57\xec\xdb\x4c\x26\x62\x72\x25\x9d\x17\x98\xde\x13\xbe\x90\xe1\x0e\xfe\xc2\xd0\x74\x84\xd9\xb2\x1a\x38\x70\xe2\xaa\x9e\x06\xc2\x1a\xa2\xd0\xc9\xcf\x42\x00\x80\xa8\x0a\x91\xde\xe1\x6f",
+       "\xab\x9f\xd5\x1b\x3a\xa4\xcd\x94\x4a\xbb\x6c\xdb\x06\x37\x08\xb2\xd1\x20\x3d\x65\xa1\xa2\xeb\xb4\x8e\x0c\x19\x72\x2a\x18\xb9\xef\x54\xd7\xa1\x1f\x76\x84\x46\x2b\x99\x5b\x6d\x38\xcd\xdc\x04\x63",
+       123 },
+      { GCRY_MD_SHA3_384,
+       "\x53\xf9\x18\xfd\x00\xb1\x70\x1b\xd5\x04\xf8\xcd\xea\x80\x3a\xcc\xa2\x1a\xc1\x8c\x56\x4a\xb9\x0c\x2a\x17\xda\x59\x2c\x7d\x69\x68\x8f\x65\x80\x57\x53\x95\x55\x1e\x8c\xd3\x3e\x0f\xef\x08\xca\x6e\xd4\x58\x8d\x4d\x14\x0b\x3e\x44\xc0\x32\x35\x5d\xf1\xc5\x31\x56\x4d\x7f\x48\x35\x75\x33\x44\x34\x5a\x67\x81\xe1\x1c\xd5\xe0\x95\xb7\x3d\xf5\xf8\x2c\x8a\xe3\xad\x00\x87\x79\x36\x89\x66\x71\xe9\x47\xcc\x52\xe2\xb2\x9d\xcd\x46\x3d\x90\xa0\xc9\x92\x91\x28\xda\x22\x2b\x5a\x21\x14\x50\xbb\xc0\xe0\x24\x48\xe2",
+       "\x03\x94\x53\x25\xac\x50\xe5\x6b\xc8\xb5\x15\x57\x65\x29\xab\xaa\x9a\x22\xbc\x2a\x7c\xed\x91\x42\xa7\x5c\xe9\x39\xa3\x88\xaf\x00\x22\xa4\xe7\x5a\x33\x96\x4b\xbb\x35\x80\x56\x4e\x0a\xf8\x09\xd3",
+       124 },
+      { GCRY_MD_SHA3_384,
+       "\xa6\x45\x99\xb8\xa6\x1b\x5c\xce\xc9\xe6\x7a\xed\x69\x44\x74\x59\xc8\xda\x3d\x1e\xc6\xc7\xc7\xc8\x2a\x74\x28\xb9\xb5\x84\xfa\x67\xe9\x0f\x68\xe2\xc0\x0f\xbb\xed\x46\x13\x66\x6e\x51\x68\xda\x4a\x16\xf3\x95\xf7\xa3\xc3\x83\x2b\x3b\x13\x4b\xfc\x9c\xba\xa9\x5d\x2a\x0f\xe2\x52\xf4\x4a\xc6\x68\x1e\xb6\xd4\x0a\xb9\x1c\x1d\x02\x82\xfe\xd6\x70\x1c\x57\x46\x3d\x3c\x5f\x2b\xb8\xc6\xa7\x30\x1f\xb4\x57\x6a\xa3\xb5\xf1\x55\x10\xdb\x89\x56\xff\x77\x47\x8c\x26\xa7\xc0\x9b\xea\x7b\x39\x8c\xfc\x83\x50\x3f\x53\x8e",
+       "\x59\x12\x69\x10\xa3\x46\x2e\x3b\x7a\xc2\x28\x92\xf6\x37\xd8\x7d\x90\x68\x6b\xc0\xa9\xbb\xd4\xa3\x2e\x2c\x4c\x71\xa1\x68\xba\x68\x5f\x21\x84\x56\x0e\x12\x5d\xb3\xdc\x23\xd9\x0b\x9e\x82\x0f\x1a",
+       125 },
+      { GCRY_MD_SHA3_384,
+       "\x0e\x3a\xb0\xe0\x54\x73\x9b\x00\xcd\xb6\xa8\x7b\xd1\x2c\xae\x02\x4b\x54\xcb\x5e\x55\x0e\x6c\x42\x53\x60\xc2\xe8\x7e\x59\x40\x1f\x5e\xc2\x4e\xf0\x31\x48\x55\xf0\xf5\x6c\x47\x69\x5d\x56\xa7\xfb\x14\x17\x69\x3a\xf2\xa1\xed\x52\x91\xf2\xfe\xe9\x5f\x75\xee\xd5\x4a\x1b\x1c\x2e\x81\x22\x6f\xbf\xf6\xf6\x3a\xde\x58\x49\x11\xc7\x19\x67\xa8\xeb\x70\x93\x3b\xc3\xf5\xd1\x5b\xc9\x1b\x5c\x26\x44\xd9\x51\x6d\x3c\x3a\x8c\x15\x4e\xe4\x8e\x11\x8b\xd1\x44\x2c\x04\x3c\x7a\x0d\xba\x5a\xc5\xb1\xd5\x36\x0a\xae\x5b\x90\x65",
+       "\xd3\x23\x9a\x33\xba\xa5\x5b\x0f\x21\x16\x9e\x0f\xde\x61\x14\xb0\x81\x06\xba\xf3\xf4\xba\x0c\xa1\x9d\x7b\x5c\xf4\x40\x30\x05\x7a\xc6\x72\xce\x52\x9e\xb0\xf3\xbd\xa3\x68\x19\x96\x78\x19\xaa\xfa",
+       126 },
+      { GCRY_MD_SHA3_384,
+       "\xa6\x2f\xc5\x95\xb4\x09\x6e\x63\x36\xe5\x3f\xcd\xfc\x8d\x1c\xc1\x75\xd7\x1d\xac\x9d\x75\x0a\x61\x33\xd2\x31\x99\xea\xac\x28\x82\x07\x94\x4c\xea\x6b\x16\xd2\x76\x31\x91\x5b\x46\x19\xf7\x43\xda\x2e\x30\xa0\xc0\x0b\xbd\xb1\xbb\xb3\x5a\xb8\x52\xef\x3b\x9a\xec\x6b\x0a\x8d\xcc\x6e\x9e\x1a\xba\xa3\xad\x62\xac\x0a\x6c\x5d\xe7\x65\xde\x2c\x37\x11\xb7\x69\xe3\xfd\xe4\x4a\x74\x01\x6f\xff\x82\xac\x46\xfa\x8f\x17\x97\xd3\xb2\xa7\x26\xb6\x96\xe3\xde\xa5\x53\x04\x39\xac\xee\x3a\x45\xc2\xa5\x1b\xc3\x2d\xd0\x55\x65\x0b",
+       "\x38\xa1\x15\x81\xd8\x74\xa5\x74\x92\x9c\x51\xf8\xdc\xc9\xe5\x01\x90\x07\x43\x86\x4a\xec\x3a\xc0\x88\x9e\x62\xc1\x07\x1c\xa5\xf8\xb6\xcc\xf9\xc0\xbd\xb3\xbb\x36\x59\x16\xeb\x43\x40\x97\x3d\xc7",
+       127 },
+      { GCRY_MD_SHA3_384,
+       "\x2b\x6d\xb7\xce\xd8\x66\x5e\xbe\x9d\xeb\x08\x02\x95\x21\x84\x26\xbd\xaa\x7c\x6d\xa9\xad\xd2\x08\x89\x32\xcd\xff\xba\xa1\xc1\x41\x29\xbc\xcd\xd7\x0f\x36\x9e\xfb\x14\x92\x85\x85\x8d\x2b\x1d\x15\x5d\x14\xde\x2f\xdb\x68\x0a\x8b\x02\x72\x84\x05\x51\x82\xa0\xca\xe2\x75\x23\x4c\xc9\xc9\x28\x63\xc1\xb4\xab\x66\xf3\x04\xcf\x06\x21\xcd\x54\x56\x5f\x5b\xff\x46\x1d\x3b\x46\x1b\xd4\x0d\xf2\x81\x98\xe3\x73\x25\x01\xb4\x86\x0e\xad\xd5\x03\xd2\x6d\x6e\x69\x33\x8f\x4e\x04\x56\xe9\xe9\xba\xf3\xd8\x27\xae\x68\x5f\xb1\xd8\x17",
+       "\x8f\xd0\x19\x09\x38\x1e\xb7\x13\x80\x34\x19\x36\x1d\x8e\x82\xe9\x24\x76\xa0\x8e\xdc\xc2\x25\xbb\x8a\x13\x5d\x21\x5c\xb4\x8d\x07\xb0\x74\x62\x4f\xcf\x2e\x73\xe6\x66\xdb\xa5\x93\x34\x71\x98\x39",
+       128 },
+      { GCRY_MD_SHA3_384,
+       "\x10\xdb\x50\x9b\x2c\xdc\xab\xa6\xc0\x62\xae\x33\xbe\x48\x11\x6a\x29\xeb\x18\xe3\x90\xe1\xbb\xad\xa5\xca\x0a\x27\x18\xaf\xbc\xd2\x34\x31\x44\x01\x06\x59\x48\x93\x04\x3c\xc7\xf2\x62\x52\x81\xbf\x7d\xe2\x65\x58\x80\x96\x6a\x23\x70\x5f\x0c\x51\x55\xc2\xf5\xcc\xa9\xf2\xc2\x14\x2e\x96\xd0\xa2\xe7\x63\xb7\x06\x86\xcd\x42\x1b\x5d\xb8\x12\xda\xce\xd0\xc6\xd6\x50\x35\xfd\xe5\x58\xe9\x4f\x26\xb3\xe6\xdd\xe5\xbd\x13\x98\x0c\xc8\x02\x92\xb7\x23\x01\x3b\xd0\x33\x28\x45\x84\xbf\xf2\x76\x57\x87\x1b\x0c\xf0\x7a\x84\x9f\x4a\xe2",
+       "\x5d\x7d\xc5\xfc\x9d\xe8\x8b\x1c\x0c\x46\xaa\x6d\x49\x27\x35\x05\xff\x7a\x76\xa1\x79\xe3\x1a\xb5\xd9\x76\xa6\x9d\x89\xb8\x3d\xfa\x6d\xea\xe9\xe1\xb9\x34\x40\xec\x05\x5d\xe1\xcc\x82\x4d\x6b\x15",
+       129 },
+      { GCRY_MD_SHA3_384,
+       "\x93\x34\xde\x60\xc9\x97\xbd\xa6\x08\x61\x01\xa6\x31\x4f\x64\xe4\x45\x8f\x5f\xf9\x45\x0c\x50\x9d\xf0\x06\xe8\xc5\x47\x98\x3c\x65\x1c\xa9\x78\x79\x17\x5a\xab\xa0\xc5\x39\xe8\x2d\x05\xc1\xe0\x2c\x48\x09\x75\xcb\xb3\x01\x18\x12\x10\x61\xb1\xeb\xac\x4f\x8d\x9a\x37\x81\xe2\xdb\x6b\x18\x04\x2e\x01\xec\xf9\x01\x7a\x64\xa0\xe5\x74\x47\xec\x7f\xcb\xe6\xa7\xf8\x25\x85\xf7\x40\x3e\xe2\x22\x3d\x52\xd3\x7b\x4b\xf4\x26\x42\x86\x13\xd6\xb4\x25\x79\x80\x97\x2a\x0a\xca\xb5\x08\xa7\x62\x0c\x1c\xb2\x8e\xb4\xe9\xd3\x0f\xc4\x13\x61\xec",
+       "\x3d\x6b\xba\x14\x5d\x7e\x69\xdb\xbb\x0f\x09\x9d\x47\xa1\xf2\x13\x8d\x4a\x00\xf2\x6b\x07\xc6\x2c\xf3\x84\x71\xf0\xfb\x9c\xa0\x22\xc6\x1f\x7a\x76\x90\x13\xa9\xbd\x8d\x5d\x87\xd8\xe0\x1d\x9b\x4d",
+       130 },
+      { GCRY_MD_SHA3_384,
+       "\xe8\x8a\xb0\x86\x89\x16\x93\xaa\x53\x5c\xeb\x20\xe6\x4c\x7a\xb9\x7c\x7d\xd3\x54\x8f\x37\x86\x33\x98\x97\xa5\xf0\xc3\x90\x31\x54\x9c\xa8\x70\x16\x6e\x47\x77\x43\xcc\xfb\xe0\x16\xb4\x42\x8d\x89\x73\x8e\x42\x6f\x5f\xfe\x81\x62\x61\x37\xf1\x7a\xec\xff\x61\xb7\x2d\xbe\xe2\xdc\x20\x96\x18\x80\xcf\xe2\x81\xdf\xab\x5e\xe3\x8b\x19\x21\x88\x14\x50\xe1\x60\x32\xde\x5e\x4d\x55\xad\x8d\x4f\xca\x60\x97\x21\xb0\x69\x2b\xac\x79\xbe\x5a\x06\xe1\x77\xfe\x8c\x80\xc0\xc8\x35\x19\xfb\x33\x47\xde\x9f\x43\xd5\x56\x1c\xb8\x10\x7b\x9b\x5e\xdc",
+       "\xfb\xce\xf8\x0d\xd0\x6e\x7e\x0b\x3b\x7a\x54\x85\xca\x5b\xc2\xb3\x88\xcb\x91\xa2\x89\x0f\x18\x1c\x85\x7b\x3e\x0a\xbe\xfd\x60\x65\x49\x9d\x82\xdd\x55\xf3\xfc\xd1\x7e\x35\x1c\x0a\x36\x36\xb8\x59",
+       131 },
+      { GCRY_MD_SHA3_384,
+       "\xfd\x19\xe0\x1a\x83\xeb\x6e\xc8\x10\xb9\x45\x82\xcb\x8f\xbf\xa2\xfc\xb9\x92\xb5\x36\x84\xfb\x74\x8d\x22\x64\xf0\x20\xd3\xb9\x60\xcb\x1d\x6b\x8c\x34\x8c\x2b\x54\xa9\xfc\xea\x72\x33\x0c\x2a\xaa\x9a\x24\xec\xdb\x00\xc4\x36\xab\xc7\x02\x36\x1a\x82\xbb\x88\x28\xb8\x53\x69\xb8\xc7\x2e\xce\x00\x82\xfe\x06\x55\x71\x63\x89\x9c\x2a\x0e\xfa\x46\x6c\x33\xc0\x43\x43\xa8\x39\x41\x70\x57\x39\x9a\x63\xa3\x92\x9b\xe1\xee\x48\x05\xd6\xce\x3e\x5d\x0d\x09\x67\xfe\x90\x04\x69\x6a\x56\x63\xf4\xca\xc9\x17\x90\x06\xa2\xce\xb7\x55\x42\xd7\x5d\x68",
+       "\x33\x8a\xac\xba\xc8\xac\x5b\xcc\x13\xfa\xfc\x0e\xc6\xd2\xec\xf4\xa8\x71\xf9\xb0\x9d\x7b\x1b\xc5\xbd\x6f\x8d\x7c\x9d\xd1\x35\x4b\x8e\x28\xc6\x81\x58\xa3\x65\x51\xdd\xda\xb8\xb6\x84\x57\x9e\xe1",
+       132 },
+      { GCRY_MD_SHA3_384,
+       "\x59\xae\x20\xb6\xf7\xe0\xb3\xc7\xa9\x89\xaf\xb2\x83\x24\xa4\x0f\xca\x25\xd8\x65\x1c\xf1\xf4\x6a\xe3\x83\xef\x6d\x84\x41\x58\x7a\xa1\xc0\x4c\x3e\x3b\xf8\x8e\x81\x31\xce\x61\x45\xcf\xb8\x97\x3d\x96\x1e\x84\x32\xb2\x02\xfa\x5a\xf3\xe0\x9d\x62\x5f\xaa\xd8\x25\xbc\x19\xda\x9b\x5c\x6c\x20\xd0\x2a\xbd\xa2\xfc\xc5\x8b\x5b\xd3\xfe\x50\x7b\xf2\x01\x26\x3f\x30\x54\x38\x19\x51\x0c\x12\xbc\x23\xe2\xdd\xb4\xf7\x11\xd0\x87\xa8\x6e\xdb\x1b\x35\x53\x13\x36\x3a\x2d\xe9\x96\xb8\x91\x02\x5e\x14\x70\x36\x08\x74\x01\xcc\xf3\xca\x78\x15\xbf\x3c\x49",
+       "\xff\xc9\x8d\x84\xc2\x68\xbd\x09\xca\xd0\x9c\xd7\xb4\xbf\x9d\x35\xed\xe9\x7e\xc5\x58\x85\xe8\x39\xe5\x57\xd2\x1e\xcc\x0e\x28\xa8\x55\x00\x03\x86\xe6\x8f\xaa\xe3\xe6\x4a\x19\xb4\x43\xb2\x58\x7d",
+       133 },
+      { GCRY_MD_SHA3_384,
+       "\x77\xee\x80\x4b\x9f\x32\x95\xab\x23\x62\x79\x8b\x72\xb0\xa1\xb2\xd3\x29\x1d\xce\xb8\x13\x98\x96\x35\x58\x30\xf3\x4b\x3b\x32\x85\x61\x53\x1f\x80\x79\xb7\x9a\x6e\x99\x80\x70\x51\x50\x86\x64\x02\xfd\xc1\x76\xc0\x58\x97\xe3\x59\xa6\xcb\x1a\x7a\xb0\x67\x38\x3e\xb4\x97\x18\x2a\x7e\x5a\xef\x70\x38\xe4\xc9\x6d\x13\x3b\x27\x82\x91\x74\x17\xe3\x91\x53\x5b\x5e\x1b\x51\xf4\x7d\x8e\xd7\xe4\xd4\x02\x5f\xe9\x8d\xc8\x7b\x9c\x16\x22\x61\x4b\xff\x3d\x10\x29\xe6\x8e\x37\x2d\xe7\x19\x80\x38\x57\xca\x52\x06\x7c\xdd\xaa\xd9\x58\x95\x1c\xb2\x06\x8c\xc6",
+       "\x47\x14\x65\x89\x0c\x3b\x9c\x03\xed\xfb\xf0\xf6\x88\x3d\x56\x57\x40\xba\xda\x3b\x76\x28\xad\x6a\x27\xf7\x29\xc3\x5c\x1a\x86\x66\x95\x3e\x8b\x99\xd2\xc8\x9e\xde\x0b\xd2\xd5\xd7\x0f\xde\xf1\x1b",
+       134 },
+      { GCRY_MD_SHA3_384,
+       "\xb7\x71\xd5\xce\xf5\xd1\xa4\x1a\x93\xd1\x56\x43\xd7\x18\x1d\x2a\x2e\xf0\xa8\xe8\x4d\x91\x81\x2f\x20\xed\x21\xf1\x47\xbe\xf7\x32\xbf\x3a\x60\xef\x40\x67\xc3\x73\x4b\x85\xbc\x8c\xd4\x71\x78\x0f\x10\xdc\x9e\x82\x91\xb5\x83\x39\xa6\x77\xb9\x60\x21\x8f\x71\xe7\x93\xf2\x79\x7a\xea\x34\x94\x06\x51\x28\x29\x06\x5d\x37\xbb\x55\xea\x79\x6f\xa4\xf5\x6f\xd8\x89\x6b\x49\xb2\xcd\x19\xb4\x32\x15\xad\x96\x7c\x71\x2b\x24\xe5\x03\x2d\x06\x52\x32\xe0\x2c\x12\x74\x09\xd2\xed\x41\x46\xb9\xd7\x5d\x76\x3d\x52\xdb\x98\xd9\x49\xd3\xb0\xfe\xd6\xa8\x05\x2f\xbb",
+       "\x0f\x8b\xa7\x21\x4d\xe0\xe3\xa9\xe1\x3c\x28\x2b\xfa\x09\xce\xa7\x82\xc3\x1c\x05\x2f\x51\x6d\x0a\xaa\x40\x3d\x97\x71\x6e\x0d\x08\xb1\xf7\xf9\xbb\x40\x85\xb5\x55\x74\x0c\x81\x3c\x4e\xce\x1b\x90",
+       135 },
+      { GCRY_MD_SHA3_384,
+       "\xb3\x2d\x95\xb0\xb9\xaa\xd2\xa8\x81\x6d\xe6\xd0\x6d\x1f\x86\x00\x85\x05\xbd\x8c\x14\x12\x4f\x6e\x9a\x16\x3b\x5a\x2a\xde\x55\xf8\x35\xd0\xec\x38\x80\xef\x50\x70\x0d\x3b\x25\xe4\x2c\xc0\xaf\x05\x0c\xcd\x1b\xe5\xe5\x55\xb2\x30\x87\xe0\x4d\x7b\xf9\x81\x36\x22\x78\x0c\x73\x13\xa1\x95\x4f\x87\x40\xb6\xee\x2d\x3f\x71\xf7\x68\xdd\x41\x7f\x52\x04\x82\xbd\x3a\x08\xd4\xf2\x22\xb4\xee\x9d\xbd\x01\x54\x47\xb3\x35\x07\xdd\x50\xf3\xab\x42\x47\xc5\xde\x9a\x8a\xbd\x62\xa8\xde\xce\xa0\x1e\x3b\x87\xc8\xb9\x27\xf5\xb0\x8b\xeb\x37\x67\x4c\x6f\x8e\x38\x0c\x04",
+       "\xca\xd2\xd2\x8f\xbd\xcc\x3a\x5d\x71\xfb\x3a\xdc\xee\xc5\x23\x13\xad\x41\xd4\xff\x1f\x91\x5c\xaa\x34\xee\x12\x78\x39\xdb\xf2\xe9\xa7\xb0\x6e\x1c\x4e\xcd\x62\x55\x92\x6c\x16\xc0\x6e\x51\xef\xd0",
+       136 },
+      { GCRY_MD_SHA3_384,
+       "\x04\x41\x0e\x31\x08\x2a\x47\x58\x4b\x40\x6f\x05\x13\x98\xa6\xab\xe7\x4e\x4d\xa5\x9b\xb6\xf8\x5e\x6b\x49\xe8\xa1\xf7\xf2\xca\x00\xdf\xba\x54\x62\xc2\xcd\x2b\xfd\xe8\xb6\x4f\xb2\x1d\x70\xc0\x83\xf1\x13\x18\xb5\x6a\x52\xd0\x3b\x81\xca\xc5\xee\xc2\x9e\xb3\x1b\xd0\x07\x8b\x61\x56\x78\x6d\xa3\xd6\xd8\xc3\x30\x98\xc5\xc4\x7b\xb6\x7a\xc6\x4d\xb1\x41\x65\xaf\x65\xb4\x45\x44\xd8\x06\xdd\xe5\xf4\x87\xd5\x37\x3c\x7f\x97\x92\xc2\x99\xe9\x68\x6b\x7e\x58\x21\xe7\xc8\xe2\x45\x83\x15\xb9\x96\xb5\x67\x7d\x92\x6d\xac\x57\xb3\xf2\x2d\xa8\x73\xc6\x01\x01\x6a\x0d",
+       "\x5b\x19\x2e\xba\xb4\x72\x15\xa8\xe9\xfb\x8e\x4d\x56\x1b\x22\x0b\x1d\xc3\x67\x07\xa3\xf0\x85\xf7\xbb\x01\x75\x33\x5c\x39\x32\x51\xe3\x46\x7f\x94\x55\x70\x42\x0c\x74\x33\x65\xd0\xf0\x9b\x9e\x09",
+       137 },
+      { GCRY_MD_SHA3_384,
+       "\x8b\x81\xe9\xba\xdd\xe0\x26\xf1\x4d\x95\xc0\x19\x97\x70\x24\xc9\xe1\x3d\xb7\xa5\xcd\x21\xf9\xe9\xfc\x49\x1d\x71\x61\x64\xbb\xac\xdc\x70\x60\xd8\x82\x61\x5d\x41\x14\x38\xae\xa0\x56\xc3\x40\xcd\xf9\x77\x78\x8f\x6e\x17\xd1\x18\xde\x55\x02\x68\x55\xf9\x32\x70\x47\x2d\x1f\xd1\x8b\x9e\x7e\x81\x2b\xae\x10\x7e\x0d\xfd\xe7\x06\x33\x01\xb7\x1f\x6c\xfe\x4e\x22\x5c\xab\x3b\x23\x29\x05\xa5\x6e\x99\x4f\x08\xee\x28\x91\xba\x92\x2d\x49\xc3\xda\xfe\xb7\x5f\x7c\x69\x75\x0c\xb6\x7d\x82\x2c\x96\x17\x6c\x46\xbd\x8a\x29\xf1\x70\x13\x73\xfb\x09\xa1\xa6\xe3\xc7\x15\x8f",
+       "\xdf\x6f\x80\xb6\xd5\x6c\xff\xa8\x54\x5a\x27\xa2\x45\xa5\x0e\x6c\x2d\x11\x7f\xc3\x59\x8f\x46\x5b\x6c\xd7\x85\x60\xf4\xb3\xc7\xd2\x12\x3f\x28\xf6\x7c\xa9\xe6\x5b\xfe\x0b\x7f\x56\x6c\x57\xb9\xef",
+       138 },
+      { GCRY_MD_SHA3_384,
+       "\xfa\x6e\xed\x24\xda\x66\x66\xa2\x22\x08\x14\x6b\x19\xa5\x32\xc2\xec\x9b\xa9\x4f\x09\xf1\xde\xf1\xe7\xfc\x13\xc3\x99\xa4\x8e\x41\xac\xc2\xa5\x89\xd0\x99\x27\x62\x96\x34\x8f\x39\x62\x53\xb5\x7c\xb0\xe4\x02\x91\xbd\x28\x27\x73\x65\x6b\x6e\x0d\x8b\xea\x1c\xda\x08\x4a\x37\x38\x81\x6a\x84\x04\x85\xfc\xf3\xfb\x30\x7f\x77\x7f\xa5\xfe\xac\x48\x69\x5c\x2a\xf4\x76\x97\x20\x25\x8c\x77\x94\x3f\xb4\x55\x6c\x36\x2d\x9c\xba\x8b\xf1\x03\xae\xb9\x03\x4b\xaa\x8e\xa8\xbf\xb9\xc4\xf8\xe6\x74\x2c\xe0\xd5\x2c\x49\xea\x8e\x97\x4f\x33\x96\x12\xe8\x30\xe9\xe7\xa9\xc2\x90\x65",
+       "\xce\x97\xe9\xdf\x08\x78\x9d\x84\x15\x1a\x95\xc8\x13\x4f\x0d\xb7\x4e\x5d\x4e\x07\x6e\x0c\x15\x96\x68\x25\xc3\x71\xb7\x9b\x31\x92\xfd\x7c\x9c\x6b\xda\xe8\x6b\x77\x58\x04\xb5\x36\x3d\x11\x52\xc7",
+       139 },
+      { GCRY_MD_SHA3_384,
+       "\x9b\xb4\xaf\x1b\x4f\x09\xc0\x71\xce\x3c\xaf\xa9\x2e\x4e\xb7\x3c\xe8\xa6\xf5\xd8\x2a\x85\x73\x34\x40\x36\x8d\xee\x4e\xb1\xcb\xc7\xb5\x5a\xc1\x50\x77\x3b\x6f\xe4\x7d\xbe\x03\x6c\x45\x58\x2e\xd6\x7e\x23\xf4\xc7\x45\x85\xda\xb5\x09\xdf\x1b\x83\x61\x05\x64\x54\x56\x42\xb2\xb1\xec\x46\x3e\x18\x04\x8f\xc2\x34\x77\xc6\xb2\xaa\x03\x55\x94\xec\xd3\x37\x91\xaf\x6a\xf4\xcb\xc2\xa1\x16\x6a\xba\x8d\x62\x8c\x57\xe7\x07\xf0\xb0\xe8\x70\x7c\xaf\x91\xcd\x44\xbd\xb9\x15\xe0\x29\x6e\x01\x90\xd5\x6d\x33\xd8\xdd\xe1\x0b\x5b\x60\x37\x78\x38\x97\x3c\x1d\x94\x3c\x22\xed\x33\x5e",
+       "\x89\xbf\x88\x9f\xbd\x7a\x38\x42\x90\xd3\xb1\xd5\x27\x09\xdb\xa6\x86\x35\x1e\x53\x93\x76\x30\xb7\xc7\xf0\x1b\xcd\xda\x19\xb1\x51\x7d\x31\x7d\x65\xe7\x99\xe6\x86\xc7\x1a\x0a\xb4\xd6\x5b\x60\xb8",
+       140 },
+      { GCRY_MD_SHA3_384,
+       "\x21\x67\xf0\x21\x18\xcc\x62\x04\x3e\x90\x91\xa6\x47\xca\xdb\xed\x95\x61\x1a\x52\x1f\xe0\xd6\x4e\x85\x18\xf1\x6c\x80\x8a\xb2\x97\x72\x55\x98\xae\x29\x68\x80\xa7\x73\x60\x7a\x79\x8f\x7c\x3c\xfc\xe8\x0d\x25\x1e\xbe\xc6\x88\x50\x15\xf9\xab\xf7\xea\xab\xae\x46\x79\x8f\x82\xcb\x59\x26\xde\x5c\x23\xf4\x4a\x3f\x9f\x95\x34\xb3\xc6\xf4\x05\xb5\x36\x4c\x2f\x8a\x8b\xdc\x5c\xa4\x9c\x74\x9b\xed\x8c\xe4\xba\x48\x89\x70\x62\xae\x84\x24\xca\x6d\xde\x5f\x55\xc0\xe4\x2a\x95\xd1\xe2\x92\xca\x54\xfb\x46\xa8\x4f\xbc\x9c\xd8\x7f\x2d\x0c\x9e\x74\x48\xde\x30\x43\xae\x22\xfd\xd2\x29",
+       "\x5d\x40\xe3\x92\xc2\xe5\xb2\x9c\x80\xc2\xd7\x60\xa9\x3a\xa1\xe1\x93\x47\x2d\x7e\xe5\x9e\x20\x3d\xd4\x78\xfe\x24\xc5\xa6\x26\x4e\x28\x73\xaf\x31\xab\xde\x81\x82\x78\x62\x90\x1a\xe5\x95\x71\xbb",
+       141 },
+      { GCRY_MD_SHA3_384,
+       "\x94\xb7\xfa\x0b\xc1\xc4\x4e\x94\x9b\x1d\x76\x17\xd3\x1b\x47\x20\xcb\xe7\xca\x57\xc6\xfa\x4f\x40\x94\xd4\x76\x15\x67\xe3\x89\xec\xc6\x4f\x69\x68\xe4\x06\x4d\xf7\x0d\xf8\x36\xa4\x7d\x0c\x71\x33\x36\xb5\x02\x8b\x35\x93\x0d\x29\xeb\x7a\x7f\x9a\x5a\xf9\xad\x5c\xf4\x41\x74\x5b\xae\xc9\xbb\x01\x4c\xee\xff\x5a\x41\xba\x5c\x1c\xe0\x85\xfe\xb9\x80\xba\xb9\xcf\x79\xf2\x15\x8e\x03\xef\x7e\x63\xe2\x9c\x38\xd7\x81\x6a\x84\xd4\xf7\x1e\x0f\x54\x8b\x7f\xc3\x16\x08\x5a\xe3\x8a\x06\x0f\xf9\xb8\xde\xc3\x6f\x91\xad\x9e\xbc\x0a\x5b\x6c\x33\x8c\xbb\x8f\x66\x59\xd3\x42\xa2\x43\x68\xcf",
+       "\x7c\x63\xa0\xdc\x1c\x39\xcf\x4f\xab\x2d\x22\xf6\x2c\x1b\x00\x75\x7a\xa4\xb8\x9e\xd0\xd7\x12\x8d\xa2\x43\xd9\x08\x2a\xd0\xc7\x87\x84\xac\x24\xdf\x34\xf5\xab\x30\x37\x5f\x1d\x58\x1e\x74\x20\xbd",
+       142 },
+      { GCRY_MD_SHA3_384,
+       "\xea\x40\xe8\x3c\xb1\x8b\x3a\x24\x2c\x1e\xcc\x6c\xcd\x0b\x78\x53\xa4\x39\xda\xb2\xc5\x69\xcf\xc6\xdc\x38\xa1\x9f\x5c\x90\xac\xbf\x76\xae\xf9\xea\x37\x42\xff\x3b\x54\xef\x7d\x36\xeb\x7c\xe4\xff\x1c\x9a\xb3\xbc\x11\x9c\xff\x6b\xe9\x3c\x03\xe2\x08\x78\x33\x35\xc0\xab\x81\x37\xbe\x5b\x10\xcd\xc6\x6f\xf3\xf8\x9a\x1b\xdd\xc6\xa1\xee\xd7\x4f\x50\x4c\xbe\x72\x90\x69\x0b\xb2\x95\xa8\x72\xb9\xe3\xfe\x2c\xee\x9e\x6c\x67\xc4\x1d\xb8\xef\xd7\xd8\x63\xcf\x10\xf8\x40\xfe\x61\x8e\x79\x36\xda\x3d\xca\x5c\xa6\xdf\x93\x3f\x24\xf6\x95\x4b\xa0\x80\x1a\x12\x94\xcd\x8d\x7e\x66\xdf\xaf\xec",
+       "\xed\x08\x5d\x83\x0a\xfd\x2d\x8f\x79\x62\x72\x81\xc2\xa8\x16\x3c\x39\x1f\xec\x2c\x58\x26\x8f\x66\xf7\x4c\xff\x97\x51\xbb\x29\xe0\xd0\x71\xea\x8f\xd2\xfc\xf9\x43\x02\x0d\x0a\xd7\x58\x28\x1b\xfd",
+       143 },
+      { GCRY_MD_SHA3_384,
+       "\x15\x7d\x5b\x7e\x45\x07\xf6\x6d\x9a\x26\x74\x76\xd3\x38\x31\xe7\xbb\x76\x8d\x4d\x04\xcc\x34\x38\xda\x12\xf9\x01\x02\x63\xea\x5f\xca\xfb\xde\x25\x79\xdb\x2f\x6b\x58\xf9\x11\xd5\x93\xd5\xf7\x9f\xb0\x5f\xe3\x59\x6e\x3f\xa8\x0f\xf2\xf7\x61\xd1\xb0\xe5\x70\x80\x05\x5c\x11\x8c\x53\xe5\x3c\xdb\x63\x05\x52\x61\xd7\xc9\xb2\xb3\x9b\xd9\x0a\xcc\x32\x52\x0c\xbb\xdb\xda\x2c\x4f\xd8\x85\x6d\xbc\xee\x17\x31\x32\xa2\x67\x91\x98\xda\xf8\x30\x07\xa9\xb5\xc5\x15\x11\xae\x49\x76\x6c\x79\x2a\x29\x52\x03\x88\x44\x4e\xbe\xfe\x28\x25\x6f\xb3\x3d\x42\x60\x43\x9c\xba\x73\xa9\x47\x9e\xe0\x0c\x63",
+       "\x29\x12\x47\x52\xcc\xd4\xac\x72\x4a\x9c\x3d\x53\xb0\xb3\x52\xaf\x2d\xbd\x76\x72\x9f\x8c\x5c\x64\x8b\x1e\x9d\x77\x81\x9f\x32\xe2\xa7\xde\x0e\x15\x28\x64\x78\xa2\x4d\xf9\xbb\x37\x0f\x85\x5c\x1c",
+       144 },
+      { GCRY_MD_SHA3_384,
+       "\x83\x6b\x34\xb5\x15\x47\x6f\x61\x3f\xe4\x47\xa4\xe0\xc3\xf3\xb8\xf2\x09\x10\xac\x89\xa3\x97\x70\x55\xc9\x60\xd2\xd5\xd2\xb7\x2b\xd8\xac\xc7\x15\xa9\x03\x53\x21\xb8\x67\x03\xa4\x11\xdd\xe0\x46\x6d\x58\xa5\x97\x69\x67\x2a\xa6\x0a\xd5\x87\xb8\x48\x1d\xe4\xbb\xa5\x52\xa1\x64\x57\x79\x78\x95\x01\xec\x53\xd5\x40\xb9\x04\x82\x1f\x32\xb0\xbd\x18\x55\xb0\x4e\x48\x48\xf9\xf8\xcf\xe9\xeb\xd8\x91\x1b\xe9\x57\x81\xa7\x59\xd7\xad\x97\x24\xa7\x10\x2d\xbe\x57\x67\x76\xb7\xc6\x32\xbc\x39\xb9\xb5\xe1\x90\x57\xe2\x26\x55\x2a\x59\x94\xc1\xdb\xb3\xb5\xc7\x87\x1a\x11\xf5\x53\x70\x11\x04\x4c\x53",
+       "\xfa\xea\xb5\x68\x7f\x39\xec\x98\x94\xc5\xcc\xff\xb5\x7e\x82\xa8\x4b\xbb\x7d\x49\x3c\xc6\xaf\xc0\x3d\x07\xac\x7b\x4f\x18\x1e\x61\x63\x9b\x9a\x47\x71\xc9\x99\x85\xed\x7f\xa1\x77\x3e\x1c\xa3\xf4",
+       145 },
+      { GCRY_MD_SHA3_384,
+       "\xcc\x77\x84\xa4\x91\x2a\x7a\xb5\xad\x36\x20\xaa\xb2\x9b\xa8\x70\x77\xcd\x3c\xb8\x36\x36\xad\xc9\xf3\xdc\x94\xf5\x1e\xdf\x52\x1b\x21\x61\xef\x10\x8f\x21\xa0\xa2\x98\x55\x79\x81\xc0\xe5\x3c\xe6\xce\xd4\x5b\xdf\x78\x2c\x1e\xf2\x00\xd2\x9b\xab\x81\xdd\x64\x60\x58\x69\x64\xed\xab\x7c\xeb\xdb\xbe\xc7\x5f\xd7\x92\x50\x60\xf7\xda\x2b\x85\x3b\x2b\x08\x95\x88\xfa\x0f\x8c\x16\xec\x64\x98\xb1\x4c\x55\xdc\xee\x33\x5c\xb3\xa9\x1d\x69\x8e\x4d\x39\x3a\xb8\xe8\xea\xc0\x82\x5f\x8a\xde\xbe\xee\x19\x6d\xf4\x12\x05\xc0\x11\x67\x4e\x53\x42\x6c\xaa\x45\x3f\x8d\xe1\xcb\xb5\x79\x32\xb0\xb7\x41\xd4\xc6",
+       "\xe4\xe3\x52\xb1\xd2\xd9\x87\xa3\x7c\x83\x16\x29\xfe\x0c\x6a\xb9\xea\xb2\xc3\x5e\x40\x1d\x1b\x5f\x44\x3a\xdc\x54\xa9\x6e\xf3\xc9\x1d\x08\x76\xcc\xf4\x6a\xde\xf8\x19\xc4\x60\x36\x91\x36\xda\x87",
+       146 },
+      { GCRY_MD_SHA3_384,
+       "\x76\x39\xb4\x61\xff\xf2\x70\xb2\x45\x5a\xc1\xd1\xaf\xce\x78\x29\x44\xae\xa5\xe9\x08\x7e\xb4\xa3\x9e\xb9\x6b\xb5\xc3\xba\xaf\x0e\x86\x8c\x85\x26\xd3\x40\x4f\x94\x05\xe7\x9e\x77\xbf\xac\x5f\xfb\x89\xbf\x19\x57\xb5\x23\xe1\x7d\x34\x1d\x73\x23\xc3\x02\xea\x70\x83\x87\x2d\xd5\xe8\x70\x56\x94\xac\xdd\xa3\x6d\x5a\x1b\x89\x5a\xaa\x16\xec\xa6\x10\x4c\x82\x68\x85\x32\xc8\xbf\xe1\x79\x0b\x5d\xc9\xf4\xec\x5f\xe9\x5b\xae\xd3\x7e\x1d\x28\x7b\xe7\x10\x43\x1f\x1e\x5e\x8e\xe1\x05\xbc\x42\xed\x37\xd7\x4b\x1e\x55\x98\x4b\xf1\xc0\x9f\xe6\xa1\xfa\x13\xef\x3b\x96\xfa\xea\xed\x6a\x2a\x19\x50\xa1\x21\x53",
+       "\x6c\x28\x8f\xe4\xa7\x4f\x0e\xd1\xb3\x6d\x12\xf2\xdb\x69\x7f\xbc\x44\x01\x7b\xb5\x7d\x38\xc9\xeb\xd4\x5f\x5a\x8b\x4f\xeb\x59\x14\x80\x60\xae\x4b\xa1\xff\xa1\x62\xe1\x0e\x69\x16\xce\xa1\xa7\x94",
+       147 },
+      { GCRY_MD_SHA3_384,
+       "\xeb\x65\x13\xfc\x61\xb3\x0c\xfb\xa5\x8d\x4d\x7e\x80\xf9\x4d\x14\x58\x90\x90\xcf\x1d\x80\xb1\xdf\x2e\x68\x08\x8d\xc6\x10\x49\x59\xba\x0d\x58\x3d\x58\x5e\x95\x78\xab\x0a\xec\x0c\xf3\x6c\x48\x43\x5e\xb5\x2e\xd9\xab\x4b\xbc\xe7\xa5\xab\xe6\x79\xc9\x7a\xe2\xdb\xe3\x5e\x8c\xc1\xd4\x5b\x06\xdd\xa3\xcf\x41\x86\x65\xc5\x7c\xbe\xe4\xbb\xb4\x7f\xa4\xca\xf7\x8f\x4e\xe6\x56\xfe\xc2\x37\xfe\x4e\xeb\xba\xfa\x20\x6e\x1e\xf2\xbd\x0e\xe4\xae\x71\xbd\x0e\x9b\x2f\x54\xf9\x1d\xaa\xdf\x1f\xeb\xfd\x70\x32\x38\x1d\x63\x6b\x73\x3d\xcb\x3b\xf7\x6f\xb1\x4e\x23\xaf\xf1\xf6\x8e\xd3\xdb\xcf\x75\xc9\xb9\x9c\x6f\x26",
+       "\xe1\xb6\xda\xc3\xf1\x38\xb5\xf3\x36\xf1\xf7\x58\x94\xf8\x25\xff\xc1\x97\x83\x6c\x92\xbf\x35\x9b\x55\xbb\x2a\x78\x23\x9f\x24\xf9\xc4\xaa\x1e\x06\x3c\x9c\x2b\x27\x3b\x9c\xfa\x76\x6f\xbf\xba\xe5",
+       148 },
+      { GCRY_MD_SHA3_384,
+       "\x15\x94\xd7\x4b\xf5\xdd\xe4\x44\x26\x5d\x4c\x04\xda\xd9\x72\x1f\xf3\xe3\x4c\xbf\x62\x2d\xaf\x34\x1f\xe1\x6b\x96\x43\x1f\x6c\x4d\xf1\xf7\x60\xd3\x4f\x29\x6e\xb9\x7d\x98\xd5\x60\xad\x52\x86\xfe\xc4\xdc\xe1\x72\x4f\x20\xb5\x4f\xd7\xdf\x51\xd4\xbf\x13\x7a\xdd\x65\x6c\x80\x54\x6f\xb1\xbf\x51\x6d\x62\xee\x82\xba\xa9\x92\x91\x0e\xf4\xcc\x18\xb7\x0f\x3f\x86\x98\x27\x6f\xcf\xb4\x4e\x0e\xc5\x46\xc2\xc3\x9c\xfd\x8e\xe9\x10\x34\xff\x93\x03\x05\x8b\x42\x52\x46\x2f\x86\xc8\x23\xeb\x15\xbf\x48\x1e\x6b\x79\xcc\x3a\x02\x21\x85\x95\xb3\x65\x8e\x8b\x37\x38\x2b\xd5\x04\x8e\xae\xd5\xfd\x02\xc3\x79\x44\xe7\x3b",
+       "\x6e\x07\xb5\x9e\x93\xb2\x24\x75\x63\x3b\x5b\xa1\xaa\x68\x91\x11\x9c\xff\x69\x06\x97\xac\x67\x9e\x93\x49\xe8\x69\x4c\x65\x40\x74\xd9\x65\xf0\xc3\x2f\xf5\x17\xb1\x0e\xe8\xf6\x99\x3f\x6e\x46\x46",
+       149 },
+      { GCRY_MD_SHA3_384,
+       "\x4c\xfa\x12\x78\x90\x30\x26\xf6\x6f\xed\xd4\x13\x74\x55\x8b\xe1\xb5\x85\xd0\x3c\x5c\x55\xda\xc9\x43\x61\xdf\x28\x6d\x4b\xd3\x9c\x7c\xb8\x03\x7e\xd3\xb2\x67\xb0\x7c\x34\x66\x26\x44\x9d\x0c\xc5\xb0\xdd\x2c\xf2\x21\xf7\xe4\xc3\x44\x9a\x4b\xe9\x99\x85\xd2\xd5\xe6\x7b\xff\x29\x23\x35\x7d\xde\xab\x5a\xbc\xb4\x61\x9f\x3a\x3a\x57\xb2\xcf\x92\x8a\x02\x2e\xb2\x76\x76\xc6\xcf\x80\x56\x89\x00\x4f\xca\x4d\x41\xea\x6c\x2d\x0a\x47\x89\xc7\x60\x5f\x7b\xb8\x38\xdd\x88\x3b\x3a\xd3\xe6\x02\x7e\x77\x5b\xcf\x26\x28\x81\x42\x80\x99\xc7\xff\xf9\x5b\x14\xc0\x95\xea\x13\x0e\x0b\x99\x38\xa5\xe2\x2f\xc5\x26\x50\xf5\x91",
+       "\x19\xeb\x2e\x15\x26\x2a\x83\x95\x38\x84\x6f\x72\x52\x67\x69\x71\x20\x79\x13\x27\x9b\x9a\xe9\xb6\xba\x36\x50\xd8\xf3\xa8\xe5\x58\xb1\x3c\x35\xb3\x1f\x1a\xb7\x42\x9e\x37\x62\x55\x33\x8c\x4a\xa2",
+       150 },
+      { GCRY_MD_SHA3_384,
+       "\xd3\xe6\x5c\xb9\x2c\xfa\x79\x66\x2f\x6a\xf4\x93\xd6\x96\xa0\x7c\xcf\x32\xaa\xad\xcc\xef\xf0\x6e\x73\xe8\xd9\xf6\xf9\x09\x20\x9e\x66\x71\x5d\x6e\x97\x87\x88\xc4\x9e\xfb\x90\x87\xb1\x70\xec\xf3\xaa\x86\xd2\xd4\xd1\xa0\x65\xae\x0e\xfc\x89\x24\xf3\x65\xd6\x76\xb3\xcb\x9e\x2b\xec\x91\x8f\xd9\x6d\x0b\x43\xde\xe8\x37\x27\xc9\xa9\x3b\xf5\x6c\xa2\xb2\xe5\x9a\xdb\xa8\x56\x96\x54\x6a\x81\x50\x67\xfc\x7a\x78\x03\x96\x29\xd4\x94\x8d\x15\x7e\x7b\x0d\x82\x6d\x1b\xf8\xe8\x12\x37\xba\xb7\x32\x13\x12\xfd\xaa\x4d\x52\x17\x44\xf9\x88\xdb\x6f\xdf\x04\x54\x9d\x0f\xdc\xa3\x93\xd6\x39\xc7\x29\xaf\x71\x6e\x9c\x8b\xba\x48",
+       "\xf4\xda\x80\xb2\x6f\xb5\xe6\xf7\xe5\xdf\xe4\x71\x28\xee\xe0\x95\xd4\x6d\x9a\xce\xfb\xe7\x6f\x74\xef\xbc\x8a\x1a\xd6\x8e\x84\x56\x63\x4e\x93\x76\x02\x56\x48\xef\x7a\x33\x50\x29\x9f\x36\x6e\x29",
+       151 },
+      { GCRY_MD_SHA3_384,
+       "\x84\x2c\xc5\x83\x50\x45\x39\x62\x2d\x7f\x71\xe7\xe3\x18\x63\xa2\xb8\x85\xc5\x6a\x0b\xa6\x2d\xb4\xc2\xa3\xf2\xfd\x12\xe7\x96\x60\xdc\x72\x05\xca\x29\xa0\xdc\x0a\x87\xdb\x4d\xc6\x2e\xe4\x7a\x41\xdb\x36\xb9\xdd\xb3\x29\x3b\x9a\xc4\xba\xae\x7d\xf5\xc6\xe7\x20\x1e\x17\xf7\x17\xab\x56\xe1\x2c\xad\x47\x6b\xe4\x96\x08\xad\x2d\x50\x30\x9e\x7d\x48\xd2\xd8\xde\x4f\xa5\x8a\xc3\xcf\xea\xfe\xee\x48\xc0\xa9\xee\xc8\x84\x98\xe3\xef\xc5\x1f\x54\xd3\x00\xd8\x28\xdd\xdc\xcb\x9d\x0b\x06\xdd\x02\x1a\x29\xcf\x5c\xb5\xb2\x50\x69\x15\xbe\xb8\xa1\x19\x98\xb8\xb8\x86\xe0\xf9\xb7\xa8\x0e\x97\xd9\x1a\x7d\x01\x27\x0f\x9a\x77\x17",
+       "\xbd\xba\x78\x38\xa1\xe7\xa6\x01\xd5\x59\xf4\x9e\xc1\x32\x3b\x7c\x5f\xab\xe1\xe1\x09\xfd\xca\xff\x3f\x78\x65\xf9\xaf\x41\x96\xab\xbf\x60\xac\x12\x30\x97\xa7\xb8\x60\xfe\x43\x86\x84\x35\x5e\xb0",
+       152 },
+      { GCRY_MD_SHA3_384,
+       "\x6c\x4b\x0a\x07\x19\x57\x3e\x57\x24\x86\x61\xe9\x8f\xeb\xe3\x26\x57\x1f\x9a\x1c\xa8\x13\xd3\x63\x85\x31\xae\x28\xb4\x86\x0f\x23\xc3\xa3\xa8\xac\x1c\x25\x00\x34\xa6\x60\xe2\xd7\x1e\x16\xd3\xac\xc4\xbf\x9c\xe2\x15\xc6\xf1\x5b\x1c\x0f\xc7\xe7\x7d\x3d\x27\x15\x7e\x66\xda\x9c\xee\xc9\x25\x8f\x8f\x2b\xf9\xe0\x2b\x4a\xc9\x37\x93\xdd\x6e\x29\xe3\x07\xed\xe3\x69\x5a\x0d\xf6\x3c\xbd\xc0\xfc\x66\xfb\x77\x08\x13\xeb\x14\x9c\xa2\xa9\x16\x91\x1b\xee\x49\x02\xc4\x7c\x78\x02\xe6\x9e\x40\x5f\xe3\xc0\x4c\xeb\x55\x22\x79\x2a\x55\x03\xfa\x82\x9f\x70\x72\x72\x22\x66\x21\xf7\xc4\x88\xa7\x69\x8c\x0d\x69\xaa\x56\x1b\xe9\xf3\x78",
+       "\x96\xdf\xe9\x99\x6b\xff\xa5\xe5\xd8\x3c\x39\xb1\x1f\x47\xf1\x2d\x11\x21\x0f\x7d\x43\x00\xb7\x18\x0d\x18\x91\xea\xaa\x7f\xe4\x80\x9f\x94\x89\xb1\xe2\x40\x7f\xf8\x7f\xb2\x62\x8d\xdf\x1f\xc0\x20",
+       153 },
+      { GCRY_MD_SHA3_384,
+       "\x51\xb7\xdb\xb7\xce\x2f\xfe\xb4\x27\xa9\x1c\xcf\xe5\x21\x8f\xd4\x0f\x9e\x0b\x7e\x24\x75\x6d\x4c\x47\xcd\x55\x60\x60\x08\xbd\xc2\x7d\x16\x40\x09\x33\x90\x6f\xd9\xf3\x0e\xff\xdd\x48\x80\x02\x2d\x08\x11\x55\x34\x2a\xf3\xfb\x6c\xd5\x36\x72\xab\x7f\xb5\xb3\xa3\xbc\xbe\x47\xbe\x1f\xd3\xa2\x27\x8c\xae\x8a\x5f\xd6\x1c\x14\x33\xf7\xd3\x50\x67\x5d\xd2\x18\x03\x74\x6c\xad\xca\x57\x41\x30\xf0\x12\x00\x02\x4c\x63\x40\xab\x0c\xc2\xcf\x74\xf2\x23\x46\x69\xf3\x4e\x90\x09\xef\x2e\xb9\x48\x23\xd6\x2b\x31\x40\x7f\x4b\xa4\x6f\x1a\x1e\xec\x41\x64\x1e\x84\xd7\x77\x27\xb5\x9e\x74\x6b\x8a\x67\x1b\xef\x93\x6f\x05\xbe\x82\x07\x59\xfa",
+       "\x79\xcf\x2a\x30\x17\xf8\x26\x93\xc0\xa5\x31\xa3\x67\x18\x6d\x05\x5f\xce\x63\x08\x1e\xdf\x98\x0c\x6a\x0b\x96\x7b\x6e\xcc\xe7\x5d\x63\x5b\x98\x48\x5e\x9b\x6b\x28\x5b\x08\x33\x6f\xf3\x4e\x61\xc9",
+       154 },
+      { GCRY_MD_SHA3_384,
+       "\x83\x59\x9d\x93\xf5\x56\x1e\x82\x1b\xd0\x1a\x47\x23\x86\xbc\x2f\xf4\xef\xbd\x4a\xed\x60\xd5\x82\x1e\x84\xaa\xe7\x4d\x80\x71\x02\x98\x10\xf5\xe2\x86\xf8\xf1\x76\x51\xcd\x27\xda\x07\xb1\xeb\x43\x82\xf7\x54\xcd\x1c\x95\x26\x87\x83\xad\x09\x22\x0f\x55\x02\x84\x03\x70\xd4\x94\xbe\xb1\x71\x24\x22\x0f\x6a\xfc\xe9\x1e\xc8\xa0\xf5\x52\x31\xf9\x65\x24\x33\xe5\xce\x34\x89\xb7\x27\x71\x6c\xf4\xae\xba\x7d\xcd\xa2\x0c\xd2\x9a\xa9\xa8\x59\x20\x12\x53\xf9\x48\xdd\x94\x39\x5a\xba\x9e\x38\x52\xbd\x1d\x60\xdd\xa7\xae\x5d\xc0\x45\xb2\x83\xda\x00\x6e\x1c\xba\xd8\x3c\xc1\x32\x92\xa3\x15\xdb\x55\x53\x30\x5c\x62\x8d\xd0\x91\x14\x65\x97",
+       "\x0e\xd3\xca\x16\x20\xce\x3a\x92\x3a\x22\xe9\xd1\x3b\xbf\x75\x43\xac\xee\x05\xf6\x6b\x67\xe6\xd6\xf4\x35\xbc\x51\x3f\x46\x98\x94\x9c\x27\x52\x80\x68\xf8\x92\xf0\x87\x19\x16\xfe\x2d\x04\x33\xc3",
+       155 },
+      { GCRY_MD_SHA3_384,
+       "\x2b\xe9\xbf\x52\x6c\x9d\x5a\x75\xd5\x65\xdd\x11\xef\x63\xb9\x79\xd0\x68\x65\x9c\x7f\x02\x6c\x08\xbe\xa4\xaf\x16\x1d\x85\xa4\x62\xd8\x0e\x45\x04\x0e\x91\xf4\x16\x5c\x07\x4c\x43\xac\x66\x13\x80\x31\x1a\x8c\xbe\xd5\x9c\xc8\xe4\xc4\x51\x8e\x80\xcd\x2c\x78\xab\x1c\xab\xf6\x6b\xff\x83\xea\xb3\xa8\x01\x48\x55\x03\x07\x31\x09\x50\xd0\x34\xa6\x28\x6c\x93\xa1\xec\xe8\x92\x9e\x63\x85\xc5\xe3\xbb\x6e\xa8\xa7\xc0\xfb\x6d\x63\x32\xe3\x20\xe7\x1c\xc4\xeb\x46\x2a\x2a\x62\xe2\xbf\xe0\x8f\x0c\xca\xd9\x3e\x61\xbe\xdb\x5d\xd0\xb7\x86\xa7\x28\xab\x66\x6f\x07\xe0\x57\x6d\x18\x9c\x92\xbf\x9f\xb2\x0d\xca\x49\xac\x2d\x39\x56\xd4\x73\x85\xe2",
+       "\x69\xa2\x7b\xbf\x08\x0e\x01\x55\x92\x89\x3d\x3b\x55\xd1\x95\x7d\x26\x77\x84\x56\x99\x23\xa4\x66\x16\x5a\x6f\xb1\x29\x61\x3d\x8e\xa6\xf6\x10\xf3\x76\x0e\x34\x9d\x46\xb0\x92\x77\xcb\x85\x45\x46",
+       156 },
+      { GCRY_MD_SHA3_384,
+       "\xca\x76\xd3\xa1\x25\x95\xa8\x17\x68\x26\x17\x00\x68\x48\x67\x55\x47\xd3\xe8\xf5\x0c\x22\x10\xf9\xaf\x90\x6c\x0e\x7c\xe5\x0b\x44\x60\x18\x6f\xe7\x04\x57\xa9\xe8\x79\xe7\x9f\xd4\xd1\xa6\x88\xc7\x0a\x34\x73\x61\xc8\x47\xba\x0d\xd6\xaa\x52\x93\x6e\xaf\x8e\x58\xa1\xbe\x2f\x5c\x1c\x70\x4e\x20\x14\x6d\x36\x6a\xeb\x38\x53\xbe\xd9\xde\x9b\xef\xe9\x56\x9a\xc8\xaa\xea\x37\xa9\xfb\x71\x39\xa1\xa1\xa7\xd5\xc7\x48\x60\x5a\x8d\xef\xb2\x97\x86\x9e\xbe\xdd\x71\xd6\x15\xa5\xda\x23\x49\x6d\x11\xe1\x1a\xbb\xb1\x26\xb2\x06\xfa\x0a\x77\x97\xee\x7d\xe1\x17\x98\x60\x12\xd0\x36\x2d\xce\xf7\x75\xc2\xfe\x14\x5a\xda\x6b\xda\x1c\xcb\x32\x6b\xf6\x44",
+       "\xe9\xc8\x83\x01\x40\x62\x96\x69\xa1\xdc\x5c\x8e\xe2\x7b\xe6\x69\xb7\x12\x2f\x4d\xc8\x82\x24\x63\x5c\xde\x33\x4a\xd9\x96\x15\xf3\xfd\xc4\x86\x9e\x56\x26\x3e\x3c\x7f\x44\x20\x73\x6f\x71\x4e\x26",
+       157 },
+      { GCRY_MD_SHA3_384,
+       "\xf7\x6b\x85\xdc\x67\x42\x10\x25\xd6\x4e\x93\x09\x6d\x1d\x71\x2b\x7b\xaf\x7f\xb0\x01\x71\x6f\x02\xd3\x3b\x21\x60\xc2\xc8\x82\xc3\x10\xef\x13\xa5\x76\xb1\xc2\xd3\x0e\xf8\xf7\x8e\xf8\xd2\xf4\x65\x00\x71\x09\xaa\xd9\x3f\x74\xcb\x9e\x7d\x7b\xef\x7c\x95\x90\xe8\xaf\x3b\x26\x7c\x89\xc1\x5d\xb2\x38\x13\x8c\x45\x83\x3c\x98\xcc\x4a\x47\x1a\x78\x02\x72\x3e\xf4\xc7\x44\xa8\x53\xcf\x80\xa0\xc2\x56\x8d\xd4\xed\x58\xa2\xc9\x64\x48\x06\xf4\x21\x04\xce\xe5\x36\x28\xe5\xbd\xf7\xb6\x3b\x0b\x33\x8e\x93\x1e\x31\xb8\x7c\x24\xb1\x46\xc6\xd0\x40\x60\x55\x67\xce\xef\x59\x60\xdf\x9e\x02\x2c\xb4\x69\xd4\xc7\x87\xf4\xcb\xa3\xc5\x44\xa1\xac\x91\xf9\x5f",
+       "\x4d\xf0\x60\x27\x61\x05\xbf\x00\x2f\x8e\x9f\x3f\x08\xd5\xb5\x1f\x7c\x2a\xdf\xe5\xaa\xb9\xa1\xa6\x83\xc0\x53\xe0\x45\xc8\x9a\x88\x30\x28\xb1\x09\x34\x61\x36\x82\x62\xea\x85\xf5\x23\x9a\xc7\xb1",
+       158 },
+      { GCRY_MD_SHA3_384,
+       "\x25\xb8\xc9\xc0\x32\xea\x6b\xcd\x73\x3f\xfc\x87\x18\xfb\xb2\xa5\x03\xa4\xea\x8f\x71\xde\xa1\x17\x61\x89\xf6\x94\x30\x4f\x0f\xf6\x8e\x86\x2a\x81\x97\xb8\x39\x95\x75\x49\xef\x24\x3a\x52\x79\xfc\x26\x46\xbd\x4c\x00\x9b\x6d\x1e\xde\xbf\x24\x73\x81\x97\xab\xb4\xc9\x92\xf6\xb1\xdc\x9b\xa8\x91\xf5\x70\x87\x9a\xcc\xd5\xa6\xb1\x86\x91\xa9\x3c\x7d\x0a\x8d\x38\xf9\x5b\x63\x9c\x1d\xae\xb4\x8c\x4c\x2f\x15\xcc\xf5\xb9\xd5\x08\xf8\x33\x3c\x32\xde\x78\x78\x1b\x41\x85\x0f\x26\x1b\x85\x5c\x4b\xeb\xcc\x12\x5a\x38\x0c\x54\xd5\x01\xc5\xd3\xbd\x07\xe6\xb5\x21\x02\x11\x60\x88\xe5\x3d\x76\x58\x3b\x01\x61\xe2\xa5\x8d\x07\x78\xf0\x91\x20\x6a\xab\xd5\xa1",
+       "\x81\x6a\xa6\xdb\x9b\x66\x32\x88\xe5\xf9\x32\xf0\xfe\xaf\xf0\xee\x78\x75\xc3\xb3\xe6\xfb\xac\x0c\xdd\xc4\x58\xbd\x64\x63\x71\x96\x9c\xf5\x0d\x2d\x09\x42\xfc\xc7\x40\x35\x73\xb0\x1b\x05\xb4\x55",
+       159 },
+      { GCRY_MD_SHA3_384,
+       "\x21\xcf\xdc\x2a\x7c\xcb\x7f\x33\x1b\x3d\x2e\xef\xff\x37\xe4\x8a\xd9\xfa\x9c\x78\x8c\x3f\x3c\x20\x0e\x01\x73\xd9\x99\x63\xe1\xcb\xca\x93\x62\x3b\x26\x4e\x92\x03\x94\xae\x48\xbb\x4c\x3a\x5b\xb9\x6f\xfb\xc8\xf0\xe5\x3f\x30\xe2\x29\x56\xad\xab\xc2\x76\x5f\x57\xfb\x76\x1e\x14\x7e\xcb\xf8\x56\x75\x33\xdb\x6e\x50\xc8\xa1\xf8\x94\x31\x0a\x94\xed\xf8\x06\xdd\x8c\xa6\xa0\xe1\x41\xc0\xfa\x7c\x9f\xae\x6c\x6a\xe6\x5f\x18\xc9\x3a\x85\x29\xe6\xe5\xb5\x53\xbf\x55\xf2\x5b\xe2\xe8\x0a\x98\x82\xbd\x37\xf1\x45\xfe\xcb\xeb\x3d\x44\x7a\x3c\x4e\x46\xc2\x15\x24\xcc\x55\xcd\xd6\x2f\x52\x1a\xb9\x2a\x8b\xa7\x2b\x89\x79\x96\xc4\x9b\xb2\x73\x19\x8b\x7b\x1c\x9e",
+       "\x12\x5b\x51\xc2\x53\x39\x16\x77\xc5\x9c\x03\x32\xc6\xa1\x3d\x07\xde\x55\xea\xb8\x08\x57\x59\x3f\x08\x39\xa5\x6f\xa6\x78\xc5\xe2\xf7\xcb\x2f\x93\x4a\xbe\x5e\x58\x87\x80\x4a\xab\x5d\x8f\x13\xe1",
+       160 },
+      { GCRY_MD_SHA3_384,
+       "\x4e\x45\x2b\xa4\x21\x27\xdc\xc9\x56\xef\x4f\x8f\x35\xdd\x68\xcb\x22\x5f\xb7\x3b\x5b\xc7\xe1\xec\x5a\x89\x8b\xba\x29\x31\x56\x3e\x74\xfa\xff\x3b\x67\x31\x4f\x24\x1e\xc4\x9f\x4a\x70\x61\xe3\xbd\x02\x13\xae\x82\x6b\xab\x38\x0f\x1f\x14\xfa\xab\x8b\x0e\xfd\xdd\x5f\xd1\xbb\x49\x37\x38\x53\xa0\x8f\x30\x55\x3d\x5a\x55\xcc\xbb\xb8\x15\x3d\xe4\x70\x4f\x29\xca\x2b\xde\xef\x04\x19\x46\x8e\x05\xdd\x51\x55\x7c\xcc\x80\xc0\xa9\x61\x90\xbb\xcc\x4d\x77\xec\xff\x21\xc6\x6b\xdf\x48\x64\x59\xd4\x27\xf9\x86\x41\x0f\x88\x3a\x80\xa5\xbc\xc3\x2c\x20\xf0\x47\x8b\xb9\xa9\x7a\x12\x6f\xc5\xf9\x54\x51\xe4\x0f\x29\x2a\x46\x14\x93\x0d\x05\x4c\x85\x1a\xcd\x01\x9c\xcf",
+       "\x13\x0c\x4b\x06\xa5\x5f\x11\xc8\x0c\x41\x60\x8a\xdf\xd7\xb4\xce\x87\x95\x87\x1b\xcf\x16\x90\x0f\x20\xd2\x75\x1e\x12\x3b\x41\xd3\xb2\x04\x8f\xd0\x52\x67\xc2\xf9\x65\x3e\xce\x36\x30\xbd\xd3\x30",
+       161 },
+      { GCRY_MD_SHA3_384,
+       "\xfa\x85\x67\x1d\xf7\xda\xdf\x99\xa6\xff\xee\x97\xa3\xab\x99\x91\x67\x1f\x56\x29\x19\x50\x49\x88\x04\x97\x48\x78\x67\xa6\xc4\x46\xb6\x00\x87\xfa\xc9\xa0\xf2\xfc\xc8\xe3\xb2\x4e\x97\xe4\x23\x45\xb9\x3b\x5f\x7d\x36\x91\x82\x9d\x3f\x8c\xcd\x4b\xb3\x64\x11\xb8\x5f\xc2\x32\x8e\xb0\xc5\x1c\xb3\x15\x1f\x70\x86\x0a\xd3\x24\x6c\xe0\x62\x3a\x8d\xc8\xb3\xc4\x9f\x95\x8f\x86\x90\xf8\xe3\x86\x0e\x71\xeb\x2b\x14\x79\xa5\xce\xa0\xb3\xf8\xbe\xfd\x87\xac\xaf\x53\x62\x43\x5e\xae\xcc\xb5\x2f\x38\x61\x7b\xc6\xc5\xc2\xc6\xe2\x69\xea\xd1\xfb\xd6\x9e\x94\x1d\x4a\xd2\x01\x2d\xa2\xc5\xb2\x1b\xcf\xbf\x98\xe4\xa7\x7a\xb2\xaf\x1f\x3f\xda\x32\x33\xf0\x46\xd3\x8f\x1d\xc8",
+       "\x3e\xa0\xfa\x3f\xc0\x35\xea\x40\xcb\xbe\x9a\x3c\x1c\x6f\x7e\x5a\x43\x7b\xa2\x0f\x26\x73\x6f\x28\x95\xf8\x1d\x53\xbe\xc9\x2a\x18\x6e\x74\x76\x29\x10\xc4\xaa\x62\x56\x53\x73\xd3\x8b\x28\xd5\xfd",
+       162 },
+      { GCRY_MD_SHA3_384,
+       "\xe9\x08\x47\xae\x67\x97\xfb\xc0\xb6\xb3\x6d\x6e\x58\x8c\x0a\x74\x3d\x72\x57\x88\xca\x50\xb6\xd7\x92\x35\x2e\xa8\x29\x4f\x5b\xa6\x54\xa1\x53\x66\xb8\xe1\xb2\x88\xd8\x4f\x51\x78\x24\x08\x27\x97\x5a\x76\x3b\xc4\x5c\x7b\x04\x30\xe8\xa5\x59\xdf\x44\x88\x50\x5e\x00\x9c\x63\xda\x99\x4f\x14\x03\xf4\x07\x95\x82\x03\xce\xbb\x6e\x37\xd8\x9c\x94\xa5\xea\xcf\x60\x39\xa3\x27\xf6\xc4\xdb\xbc\x7a\x2a\x30\x7d\x97\x6a\xa3\x9e\x41\xaf\x65\x37\x24\x3f\xc2\x18\xdf\xa6\xab\x4d\xd8\x17\xb6\xa3\x97\xdf\x5c\xa6\x91\x07\xa9\x19\x87\x99\xed\x24\x86\x41\xb6\x3b\x42\xcb\x4c\x29\xbf\xdd\x79\x75\xac\x96\xed\xfc\x27\x4a\xc5\x62\xd0\x47\x4c\x60\x34\x7a\x07\x8c\xe4\xc2\x5e\x88",
+       "\x7c\x1f\x1a\x46\xe4\x09\x04\x6b\x5a\x31\x47\x67\xe8\xb7\xe7\xb1\xd9\xa9\x29\x31\x44\x3c\x5d\x02\xa5\x81\x37\x1b\x38\x0a\xfa\x18\x67\xe5\x54\xc3\xf7\xdf\x2e\x45\x57\xac\xfd\x9f\x8e\x23\x0c\x44",
+       163 },
+      { GCRY_MD_SHA3_384,
+       "\xf6\xd5\xc2\xb6\xc9\x39\x54\xfc\x62\x76\x02\xc0\x0c\x4c\xa9\xa7\xd3\xed\x12\xb2\x71\x73\xf0\xb2\xc9\xb0\xe4\xa5\x93\x93\x98\xa6\x65\xe6\x7e\x69\xd0\xb1\x2f\xb7\xe4\xce\xb2\x53\xe8\x08\x3d\x1c\xeb\x72\x4a\xc0\x7f\x00\x9f\x09\x4e\x42\xf2\xd6\xf2\x12\x94\x89\xe8\x46\xea\xff\x07\x00\xa8\xd4\x45\x3e\xf4\x53\xa3\xed\xdc\x18\xf4\x08\xc7\x7a\x83\x27\x56\x17\xfa\xbc\x4e\xa3\xa2\x83\x3a\xa7\x34\x06\xc0\xe9\x66\x27\x60\x79\xd3\x8e\x8e\x38\x53\x9a\x70\xe1\x94\xcc\x55\x13\xaa\xa4\x57\xc6\x99\x38\x3f\xd1\x90\x0b\x1e\x72\xbd\xfb\x83\x5d\x1f\xd3\x21\xb3\x7b\xa8\x05\x49\xb0\x78\xa4\x9e\xa0\x81\x52\x86\x9a\x91\x8c\xa5\x7f\x5b\x54\xed\x71\xe4\xfd\x3a\xc5\xc0\x67\x29",
+       "\x2a\xd2\x38\x17\x00\x2c\x8f\x00\x89\xd4\x23\x76\x0f\x55\x69\xeb\x67\xcb\xee\xd2\xf0\xf2\xaa\x12\xf8\xed\xe7\x85\x6e\xe2\x2a\xa6\xeb\x68\x4f\x86\xae\x91\x74\x1a\x4a\xa3\xc8\x0a\xc9\x7c\x4a\x0b",
+       164 },
+      { GCRY_MD_SHA3_384,
+       "\xcf\x85\x62\xb1\xbe\xd8\x98\x92\xd6\x7d\xda\xaf\x3d\xee\xb2\x82\x46\x45\x6e\x97\x23\x26\xdb\xcd\xb5\xcf\x3f\xb2\x89\xac\xa0\x1e\x68\xda\x5d\x59\x89\x6e\x3a\x61\x65\x35\x8b\x07\x1b\x30\x4d\x6a\xb3\xd0\x18\x94\x4b\xe5\x04\x9d\x5e\x0e\x2b\xb8\x19\xac\xf6\x7a\x60\x06\x11\x10\x89\xe6\x76\x71\x32\xd7\x2d\xd8\x5b\xed\xdc\xbb\x2d\x64\x49\x6d\xb0\xcc\x92\x95\x5a\xb4\xc6\x23\x4f\x1e\xea\x24\xf2\xd5\x14\x83\xf2\xe2\x09\xe4\x58\x9b\xf9\x51\x9f\xac\x51\xb4\xd0\x61\xe8\x01\x12\x5e\x60\x5f\x80\x93\xbb\x69\x97\xbc\x16\x3d\x55\x15\x96\xfe\x4a\xb7\xcf\xae\x8f\xb9\xa9\x0f\x69\x80\x48\x0c\xe0\xc2\x29\xfd\x16\x75\x40\x9b\xd7\x88\x35\x4d\xaf\x31\x62\x40\xcf\xe0\xaf\x93\xeb",
+       "\xd3\x49\x74\x75\x9c\x6a\x4a\xa9\xd1\xa4\xed\x3d\xe3\x41\xa2\xba\x02\x2d\xf1\x27\xbe\x92\xeb\x0b\xbc\x19\x00\xeb\x5a\xc7\xb8\xaf\xe9\x09\xb5\x2d\xa5\x71\x46\x68\xc3\xc4\xb7\xdb\x93\x9f\x24\x36",
+       165 },
+      { GCRY_MD_SHA3_384,
+       "\x2a\xce\x31\xab\xb0\xa2\xe3\x26\x79\x44\xd2\xf7\x5e\x15\x59\x98\x5d\xb7\x35\x4c\x6e\x60\x5f\x18\xdc\x84\x70\x42\x3f\xca\x30\xb7\x33\x1d\x9b\x33\xc4\xa4\x32\x67\x83\xd1\xca\xae\x1b\x4f\x07\x06\x0e\xff\x97\x8e\x47\x46\xbf\x0c\x7e\x30\xcd\x61\x04\x0b\xd5\xec\x27\x46\xb2\x98\x63\xeb\x7f\x10\x3e\xbd\xa6\x14\xc4\x29\x1a\x80\x5b\x6a\x4c\x82\x14\x23\x05\x64\xa0\x55\x7b\xc7\x10\x2e\x0b\xd3\xed\x23\x71\x92\x52\xf7\x43\x5d\x64\xd2\x10\xee\x2a\xaf\xc5\x85\xbe\x90\x3f\xa4\x1e\x19\x68\xc5\x0f\xd5\xd5\x36\x79\x26\xdf\x7a\x05\xe3\xa4\x2c\xf0\x7e\x65\x6f\xf9\x2d\xe7\x3b\x03\x6c\xf8\xb1\x98\x98\xc0\xcb\x34\x55\x7c\x0c\x12\xc2\xd8\xb8\x4e\x91\x18\x1a\xf4\x67\xbc\x75\xa9\xd1",
+       "\x0f\xb3\x8a\xe2\x33\x52\x0d\x4f\x57\x46\x94\x63\xe1\xe6\x8d\x55\x18\xea\x4e\x96\x57\x55\xc0\x3a\xd4\x58\xdd\x28\x5a\xfb\x2d\xf5\x18\xc3\xd3\x89\xbd\x36\x1c\xbd\xce\x46\xb6\x54\x63\x1a\x18\xc2",
+       166 },
+      { GCRY_MD_SHA3_384,
+       "\x0d\x8d\x09\xae\xd1\x9f\x10\x13\x96\x9c\xe5\xe7\xeb\x92\xf8\x3a\x20\x9a\xe7\x6b\xe3\x1c\x75\x48\x44\xea\x91\x16\xce\xb3\x9a\x22\xeb\xb6\x00\x30\x17\xbb\xcf\x26\x55\x5f\xa6\x62\x41\x85\x18\x7d\xb8\xf0\xcb\x35\x64\xb8\xb1\xc0\x6b\xf6\x85\xd4\x7f\x32\x86\xed\xa2\x0b\x83\x35\x8f\x59\x9d\x20\x44\xbb\xf0\x58\x3f\xab\x8d\x78\xf8\x54\xfe\x0a\x59\x61\x83\x23\x0c\x5e\xf8\xe5\x44\x26\x75\x0e\xaf\x2c\xc4\xe2\x9d\x3b\xdd\x03\x7e\x73\x4d\x86\x3c\x2b\xd9\x78\x9b\x4c\x24\x30\x96\x13\x8f\x76\x72\xc2\x32\x31\x4e\xff\xdf\xc6\x51\x34\x27\xe2\xda\x76\x91\x6b\x52\x48\x93\x3b\xe3\x12\xeb\x5d\xde\x4c\xf7\x08\x04\xfb\x25\x8a\xc5\xfb\x82\xd5\x8d\x08\x17\x7a\xc6\xf4\x75\x60\x17\xff\xf5",
+       "\xcb\x8f\x1c\xc9\xeb\x72\x46\x51\x76\xb9\x7b\x62\x26\xa8\x7e\x69\xd7\x7c\x65\x19\x01\x14\xcc\xe1\xf8\x30\xa3\xdf\xef\xa5\xa8\xa2\x78\xd5\xcf\x59\x4b\x17\x3a\xc5\x8c\x06\xec\x74\x95\x8f\xf8\xc6",
+       167 },
+      { GCRY_MD_SHA3_384,
+       "\xc3\x23\x6b\x73\xde\xb7\x66\x2b\xf3\xf3\xda\xa5\x8f\x13\x7b\x35\x8b\xa6\x10\x56\x0e\xf7\x45\x57\x85\xa9\xbe\xfd\xb0\x35\xa0\x66\xe9\x07\x04\xf9\x29\xbd\x96\x89\xce\xf0\xce\x3b\xda\x5a\xcf\x44\x80\xbc\xeb\x8d\x09\xd1\x0b\x09\x8a\xd8\x50\x0d\x9b\x60\x71\xdf\xc3\xa1\x4a\xf6\xc7\x75\x11\xd8\x1e\x3a\xa8\x84\x49\x86\xc3\xbe\xa6\xf4\x69\xf9\xe0\x21\x94\xc9\x28\x68\xcd\x5f\x51\x64\x62\x56\x79\x8f\xf0\x42\x49\x54\xc1\x43\x4b\xdf\xed\x9f\xac\xb3\x90\xb0\x7d\x34\x2e\x99\x29\x36\xe0\xf8\x8b\xfd\x0e\x88\x4a\x0d\xdb\x67\x9d\x05\x47\xcc\xde\xc6\x38\x42\x85\xa4\x54\x29\xd1\x15\xac\x7d\x23\x5a\x71\x72\x42\x02\x1d\x1d\xc3\x56\x41\xf5\xf0\xa4\x8e\x84\x45\xdb\xa5\x8e\x6c\xb2\xc8\xea",
+       "\x87\x77\x6d\x70\x22\xdc\x18\x59\x2b\x57\x8c\x53\x4e\x2f\xcf\x57\x94\x6e\x0f\x74\xc4\x7d\xf8\x56\x12\xf8\x9c\x65\x93\xfd\x50\xa9\xe4\x45\xc0\x48\xd6\xcd\xa9\xa1\xd1\xd1\x0e\xa3\xb3\xc9\x73\xd0",
+       168 },
+      { GCRY_MD_SHA3_384,
+       "\xb3\x9f\xeb\x82\x83\xea\xdc\x63\xe8\x18\x4b\x51\xdf\x5a\xe3\xfd\x41\xaa\xc8\xa9\x63\xbb\x0b\xe1\xcd\x08\xaa\x58\x67\xd8\xd9\x10\xc6\x69\x22\x1e\x73\x24\x33\x60\x64\x6f\x65\x53\xd1\xca\x05\xa8\x4e\x8d\xc0\xde\x05\xb6\x41\x9e\xc3\x49\xca\x99\x44\x80\x19\x3d\x01\xc9\x25\x25\xf3\xfb\x3d\xce\xfb\x08\xaf\xc6\xd2\x69\x47\xbd\xbb\xfd\x85\x19\x3f\x53\xb5\x06\x09\xc6\x14\x09\x05\xc5\x3a\x66\x86\xb5\x8e\x53\xa3\x19\xa5\x7b\x96\x23\x31\xed\xe9\x81\x49\xaf\x3d\xe3\x11\x8a\x81\x9d\xa4\xd7\x67\x06\xa0\x42\x4b\x4e\x1d\x29\x10\xb0\xed\x26\xaf\x61\xd1\x50\xeb\xcb\x46\x59\x5d\x42\x66\xa0\xbd\x7f\x65\x1b\xa4\x7d\x0c\x7f\x17\x9c\xa2\x85\x45\x00\x7d\x92\xe8\x41\x9d\x48\xfd\xfb\xd7\x44\xce",
+       "\x83\xf4\x44\x21\x47\xfe\xfc\x8e\x5b\xad\x3e\x9e\xe4\xc6\x66\x1a\x77\x1a\xe8\xc8\x74\x58\xab\x67\x15\x3d\xec\xd3\x5d\xaf\x67\x56\xee\xf2\x8e\x4a\xe7\x2e\x65\xeb\xfa\xe0\x88\x86\xa6\xe7\x73\xe0",
+       169 },
+      { GCRY_MD_SHA3_384,
+       "\xa9\x83\xd5\x4f\x50\x38\x03\xe8\xc7\x99\x9f\x4e\xdb\xbe\x82\xe9\x08\x4f\x42\x21\x43\xa9\x32\xdd\xdd\xc4\x7a\x17\xb0\xb7\x56\x4a\x7f\x37\xa9\x9d\x07\x86\xe9\x94\x76\x42\x8d\x29\xe2\x9d\x3c\x19\x7a\x72\xbf\xab\x13\x42\xc1\x2a\x0f\xc4\x78\x7f\xd7\x01\x7d\x7a\x61\x74\x04\x9e\xa4\x3b\x57\x79\x16\x9e\xf7\x47\x2b\xdb\xbd\x94\x1d\xcb\x82\xfc\x73\xaa\xc4\x5a\x8a\x94\xc9\xf2\xbd\x34\x77\xf6\x1f\xd3\xb7\x96\xf0\x2a\x1b\x82\x64\xa2\x14\xc6\xfe\xa7\x4b\x70\x51\xb2\x26\xc7\x22\x09\x9e\xc7\x88\x3a\x46\x2b\x83\xb6\xaf\xdd\x40\x09\x24\x8b\x8a\x23\x7f\x60\x5f\xe5\xa0\x8f\xe7\xd8\xb4\x53\x21\x42\x1e\xbb\xa6\x7b\xd7\x0a\x0b\x00\xdd\xbf\x94\xba\xab\x7f\x35\x9d\x5d\x1e\xea\x10\x5f\x28\xdc\xfb",
+       "\x51\x35\x81\x59\x07\x4d\x96\x0c\x0b\x9d\x73\xd5\xf1\x2a\xfd\xaf\xb8\xf5\xd7\x90\x5b\xda\x62\x37\x9a\x6e\x0d\x67\x27\xd0\x3e\xfd\x26\xee\xa5\x1b\x43\x43\x68\xe2\xe5\x66\xcb\x47\x47\xd0\xba\x35",
+       170 },
+      { GCRY_MD_SHA3_384,
+       "\xe4\xd1\xc1\x89\x7a\x0a\x86\x6c\xe5\x64\x63\x5b\x74\x22\x2f\x96\x96\xbf\x2c\x7f\x64\x0d\xd7\x8d\x7e\x2a\xca\x66\xe1\xb6\x1c\x64\x2b\xb0\x3e\xa7\x53\x6a\xae\x59\x78\x11\xe9\xbf\x4a\x7b\x45\x3e\xde\x31\xf9\x7b\x46\xa5\xf0\xef\x51\xa0\x71\xa2\xb3\x91\x8d\xf1\x6b\x15\x25\x19\xae\x37\x76\xf9\xf1\xed\xab\x4c\x2a\x37\x7c\x32\x92\xe9\x64\x08\x35\x9d\x36\x13\x84\x4d\x5e\xb3\x93\x00\x02\x83\xd5\xad\x34\x01\xa3\x18\xb1\x2f\xd1\x47\x4b\x86\x12\xf2\xbb\x50\xfb\x6a\x8b\x9e\x02\x3a\x54\xd7\xdd\xe2\x8c\x43\xd6\xd8\x85\x4c\x8d\x9d\x11\x55\x93\x5c\x19\x98\x11\xdb\xfc\x87\xe9\xe0\x07\x2e\x90\xeb\x88\x68\x1c\xc7\x52\x97\x14\xf8\xfb\x8a\x2c\x9d\x88\x56\x7a\xdf\xb9\x74\xee\x20\x5a\x9b\xf7\xb8\x48",
+       "\x3e\xce\xa8\xca\xf0\xd8\xef\xa4\x2d\x54\xac\x5e\xf3\x6e\x62\x42\x37\xd9\xf5\x50\x8e\xd6\xfc\xb6\x43\x4d\x67\xf3\xfb\x78\x8c\x53\x8c\x63\x57\x98\xf5\x2b\x2f\x07\x3a\x4a\x73\x76\xfd\x31\xc4\xa3",
+       171 },
+      { GCRY_MD_SHA3_384,
+       "\xb1\x0c\x59\x72\x3e\x3d\xca\xdd\x6d\x75\xdf\x87\xd0\xa1\x58\x0e\x73\x13\x3a\x9b\x7d\x00\xcb\x95\xec\x19\xf5\x54\x70\x27\x32\x3b\xe7\x51\x58\xb1\x1f\x80\xb6\xe1\x42\xc6\xa7\x85\x31\x88\x6d\x90\x47\xb0\x8e\x55\x1e\x75\xe6\x26\x1e\x79\x78\x53\x66\xd7\x02\x4b\xd7\xcd\x9c\xf3\x22\xd9\xbe\x7d\x57\xfb\x66\x10\x69\xf2\x48\x1c\x7b\xb7\x59\xcd\x71\xb4\xb3\x6c\xa2\xbc\x2d\xf6\xd3\xa3\x28\xfa\xeb\xdb\x99\x5a\x97\x94\xa8\xd7\x21\x55\xed\x55\x1a\x1f\x87\xc8\x0b\xf6\x05\x9b\x43\xfc\x76\x49\x00\xb1\x8a\x1c\x24\x41\xf7\x48\x77\x43\xcf\x84\xe5\x65\xf6\x1f\x8d\xd2\xec\xe6\xb6\xcc\xc9\x44\x40\x49\x19\x7a\xaa\xf5\x3e\x92\x6f\xbe\xe3\xbf\xca\x8b\xe5\x88\xec\x77\xf2\x9d\x21\x1b\xe8\x9d\xe1\x8b\x15\xf6",
+       "\xa8\x87\x6f\xe4\x65\x2a\xcf\x72\xdc\xc8\xfd\x51\x33\xe5\xd4\xca\x4e\x37\x66\xab\x98\x7c\xf6\x6e\xae\x5e\x37\x70\xe2\x52\xd2\xfd\x2a\x89\x05\x25\x01\x66\x23\xee\x69\x06\x46\x90\x82\x8c\x72\x7b",
+       172 },
+      { GCRY_MD_SHA3_384,
+       "\xdb\x11\xf6\x09\xba\xba\x7b\x0c\xa6\x34\x92\x6b\x1d\xd5\x39\xc8\xcb\xad\xa2\x49\x67\xd7\xad\xd4\xd9\x87\x6f\x77\xc2\xd8\x0c\x0f\x4d\xce\xfb\xd7\x12\x15\x48\x37\x35\x82\x70\x5c\xca\x24\x95\xbd\x2a\x43\x71\x6f\xe6\x4e\xd2\x6d\x05\x9c\xfb\x56\x6b\x33\x64\xbd\x49\xee\x07\x17\xbd\xd9\x81\x0d\xd1\x4d\x8f\xad\x80\xdb\xbd\xc4\xca\xfb\x37\xcc\x60\xfb\x0f\xe2\xa8\x0f\xb4\x54\x1b\x8c\xa9\xd5\x9d\xce\x45\x77\x38\xa9\xd3\xd8\xf6\x41\xaf\x8c\x3f\xd6\xda\x16\x2d\xc1\x6f\xc0\x1a\xac\x52\x7a\x4a\x02\x55\xb4\xd2\x31\xc0\xbe\x50\xf4\x4f\x0d\xb0\xb7\x13\xaf\x03\xd9\x68\xfe\x7f\x0f\x61\xed\x08\x24\xc5\x5c\x4b\x52\x65\x54\x8f\xeb\xd6\xaa\xd5\xc5\xee\xdf\x63\xef\xe7\x93\x48\x9c\x39\xb8\xfd\x29\xd1\x04\xce",
+       "\x6a\x09\x73\x57\x36\x78\x0f\x19\x9d\x75\xc6\x09\x03\xaa\x24\xd7\xf8\xaa\x17\x51\x66\x90\x85\x4f\x75\x22\xef\x0b\xbf\x47\xd4\x1c\xbd\xc8\xbd\xb2\xcb\x2f\x3c\x55\x96\x51\x05\x39\x67\x76\x07\xe9",
+       173 },
+      { GCRY_MD_SHA3_384,
+       "\xbe\xbd\x4f\x1a\x84\xfc\x8b\x15\xe4\x45\x2a\x54\xbd\x02\xd6\x9e\x30\x4b\x7f\x32\x61\x6a\xad\xd9\x05\x37\x93\x71\x06\xae\x4e\x28\xde\x9d\x8a\xab\x02\xd1\x9b\xc3\xe2\xfd\xe1\xd6\x51\x55\x9e\x29\x64\x53\xe4\xdb\xa9\x43\x70\xa1\x4d\xbb\xb2\xd1\xd4\xe2\x02\x23\x02\xee\x90\xe2\x08\x32\x1e\xfc\xd8\x52\x8a\xd8\x9e\x46\xdc\x83\x9e\xa9\xdf\x61\x8e\xa8\x39\x4a\x6b\xff\x30\x8e\x77\x26\xba\xe0\xc1\x9b\xcd\x4b\xe5\x2d\xa6\x25\x8e\x2e\xf4\xe9\x6a\xa2\x12\x44\x42\x9f\x49\xef\x5c\xb4\x86\xd7\xff\x35\xca\xc1\xba\xcb\x7e\x95\x71\x19\x44\xbc\xcb\x2a\xb3\x47\x00\xd4\x2d\x1e\xb3\x8b\x5d\x53\x6b\x94\x73\x48\xa4\x58\xed\xe3\xdc\x6b\xd6\xec\x54\x7b\x1b\x0c\xae\x5b\x25\x7b\xe3\x6a\x71\x24\xe1\x06\x0c\x17\x0f\xfa",
+       "\x83\xfc\x2b\x91\xab\x81\xd4\xb1\x53\x63\xf1\x5e\x53\xbf\x63\x90\x63\xba\xc5\x55\x02\xb4\x42\x1c\xf9\xa5\x3b\xca\xb9\xff\x47\xfd\x77\xde\x5a\xc6\x93\x4f\x67\xa4\x12\xea\x19\x10\xfa\xd6\x77\x68",
+       174 },
+      { GCRY_MD_SHA3_384,
+       "\x5a\xca\x56\xa0\x3a\x13\x78\x4b\xdc\x32\x89\xd9\x36\x4f\x79\xe2\xa8\x5c\x12\x27\x6b\x49\xb9\x2d\xb0\xad\xaa\x4f\x20\x6d\x50\x28\xf2\x13\xf6\x78\xc3\x51\x0e\x11\x1f\x9d\xc4\xc1\xc1\xf8\xb6\xac\xb1\x7a\x64\x13\xaa\x22\x76\x07\xc5\x15\xc6\x2a\x73\x38\x17\xba\x5e\x76\x2c\xc6\x74\x8e\x7e\x0d\x68\x72\xc9\x84\xd7\x23\xc9\xbb\x3b\x11\x7e\xb8\x96\x31\x85\x30\x0a\x80\xbf\xa6\x5c\xde\x49\x5d\x70\xa4\x6c\x44\x85\x86\x05\xfc\xcb\xed\x08\x6c\x2b\x45\xce\xf9\x63\xd3\x32\x94\xdb\xe9\x70\x6b\x13\xaf\x22\xf1\xb7\xc4\xcd\x5a\x00\x1c\xfe\xc2\x51\xfb\xa1\x8e\x72\x2c\x6e\x1c\x4b\x11\x66\x91\x8b\x4f\x6f\x48\xa9\x8b\x64\xb3\xc0\x7f\xc8\x6a\x6b\x17\xa6\xd0\x48\x0a\xb7\x9d\x4e\x64\x15\xb5\x20\xf1\xc4\x84\xd6\x75\xb1",
+       "\x77\xc0\x48\x0b\x91\xf3\x2e\xf8\x09\xd8\xc2\x3a\xb2\x36\x58\x1f\x0b\xca\x8b\x94\x47\xa4\xd3\x62\x28\x05\x2b\x3a\xbb\x6a\xb6\x9c\x61\xd1\x9d\x72\x04\x86\xa3\xff\x49\x7a\x46\x73\xb8\x4c\xb9\x51",
+       175 },
+      { GCRY_MD_SHA3_384,
+       "\xa5\xaa\xd0\xe4\x64\x6a\x32\xc8\x5c\xfc\xac\x73\xf0\x2f\xc5\x30\x0f\x19\x82\xfa\xbb\x2f\x21\x79\xe2\x83\x03\xe4\x47\x85\x40\x94\xcd\xfc\x85\x43\x10\xe5\xc0\xf6\x09\x93\xce\xff\x54\xd8\x4d\x6b\x46\x32\x3d\x93\x0a\xdb\x07\xc1\x75\x99\xb3\x5b\x50\x5f\x09\xe7\x84\xbc\xa5\x98\x5e\x01\x72\x25\x77\x97\xfb\x53\x64\x9e\x2e\x97\x23\xef\xd1\x68\x65\xc3\x1b\x5c\x3d\x51\x13\xb5\x8b\xb0\xbf\xc8\x92\x0f\xab\xdd\xa0\x86\xd7\x53\x7e\x66\xd7\x09\xd0\x50\xbd\x14\xd0\xc9\x60\x87\x3f\x15\x6f\xad\x5b\x3d\x38\x40\xcd\xfc\xdc\x9b\xe6\xaf\x51\x9d\xb2\x62\xa2\x7f\x40\x89\x6a\xb2\x5c\xc3\x9f\x96\x98\x4d\x65\x06\x11\xc0\xd5\xa3\x08\x0d\x5b\x3a\x1b\xf1\x86\xab\xd4\x29\x56\x58\x8b\x3b\x58\xcd\x94\x89\x70\xd2\x98\x77\x60\x60",
+       "\x78\x14\x66\xe2\x57\xd2\xfa\x59\x4e\x39\xdc\x22\x0a\x26\x0c\x74\x78\xd2\x15\x8b\xb7\x0e\x42\x6f\x9e\x95\x87\xf5\xa5\x1a\x7c\x29\xfd\xc7\xaf\x23\xe7\xab\x9c\x77\x4e\x33\xc0\x8a\xb3\x8c\xed\xb7",
+       176 },
+      { GCRY_MD_SHA3_384,
+       "\x06\xcb\xbe\x67\xe9\x4a\x97\x82\x03\xea\xd6\xc0\x57\xa1\xa5\xb0\x98\x47\x8b\x4b\x4c\xbe\xf5\xa9\x7e\x93\xc8\xe4\x2f\x55\x72\x71\x35\x75\xfc\x2a\x88\x45\x31\xd7\x62\x2f\x8f\x87\x93\x87\xa8\x59\xa8\x0f\x10\xef\x02\x70\x8c\xd8\xf7\x41\x3a\xb3\x85\xaf\xc3\x57\x67\x8b\x95\x78\xc0\xeb\xf6\x41\xef\x07\x6a\x1a\x30\xf1\xf7\x53\x79\xe9\xdc\xb2\xa8\x85\xbd\xd2\x95\x90\x5e\xe8\x0c\x01\x68\xa6\x2a\x95\x97\xd1\x0c\xf1\x2d\xd2\xd8\xce\xe4\x66\x45\xc7\xe5\xa1\x41\xf6\xe0\xe2\x3a\xa4\x82\xab\xe5\x66\x1c\x16\xe6\x9e\xf1\xe2\x83\x71\xe2\xe2\x36\xc3\x59\xba\x4e\x92\xc2\x56\x26\xa7\xb7\xff\x13\xf6\xea\x4a\xe9\x06\xe1\xcf\xe1\x63\xe9\x17\x19\xb1\xf7\x50\xa9\x6c\xbd\xe5\xfb\xc9\x53\xd9\xe5\x76\xcd\x21\x6a\xfc\x90\x32\x3a",
+       "\x51\xbe\xbf\xb5\xaa\xfe\x77\x7f\x39\x0e\x28\x51\xb7\xeb\x9a\xa3\x80\x91\x94\xfe\x3b\xa1\x68\x9a\xbe\xe7\xe4\x3d\x44\xa5\x87\x4e\x0c\x25\x27\x93\xdf\xd4\x2c\x12\x70\xc6\x3c\x40\x7a\xef\x67\x80",
+       177 },
+      { GCRY_MD_SHA3_384,
+       "\xf1\xc5\x28\xcf\x77\x39\x87\x47\x07\xd4\xd8\xad\x5b\x98\xf7\xc7\x71\x69\xde\x0b\x57\x18\x8d\xf2\x33\xb2\xdc\x8a\x5b\x31\xed\xa5\xdb\x42\x91\xdd\x9f\x68\xe6\xba\xd3\x7b\x8d\x7f\x6c\x9c\x00\x44\xb3\xbf\x74\xbb\xc3\xd7\xd1\x79\x8e\x13\x87\x09\xb0\xd7\x5e\x7c\x59\x3d\x3c\xcc\xdc\x1b\x20\xc7\x17\x4b\x4e\x69\x2a\xdd\x82\x0a\xce\x26\x2d\x45\xcc\xfa\xe2\x07\x7e\x87\x87\x96\x34\x71\x68\x06\x0a\x16\x2e\xcc\xa8\xc3\x8c\x1a\x88\x35\x0b\xd6\x3b\xb5\x39\x13\x4f\x70\x0f\xd4\xad\xdd\x59\x59\xe2\x55\x33\x7d\xaa\x06\xbc\x86\x35\x8f\xab\xcb\xef\xdf\xb5\xbc\x88\x97\x83\xd8\x43\xc0\x8a\xad\xc6\xc4\xf6\xc3\x6f\x65\xf1\x56\xe8\x51\xc9\xa0\xf9\x17\xe4\xa3\x67\xb5\xad\x93\xd8\x74\x81\x2a\x1d\xe6\xa7\xb9\x3c\xd5\x3a\xd9\x72\x32",
+       "\xfc\xdf\x00\x32\xf3\x4b\xa6\xc4\x2d\x67\x9b\x18\x2d\x07\xb1\x0f\x4d\xff\x21\x89\xb0\xa5\xef\x66\x42\xfb\xb7\x1b\x16\xf9\x10\xe3\x24\x0e\xd9\xb5\x02\xb1\xc6\xb3\x95\xbe\xe7\x4a\xd0\xfb\x41\x91",
+       178 },
+      { GCRY_MD_SHA3_384,
+       "\x9d\x9f\x3a\x7e\xcd\x51\xb4\x1f\x65\x72\xfd\x0d\x08\x81\xe3\x03\x90\xdf\xb7\x80\x99\x1d\xae\x7d\xb3\xb4\x76\x19\x13\x47\x18\xe6\xf9\x87\x81\x0e\x54\x26\x19\xdf\xaa\x7b\x50\x5c\x76\xb7\x35\x0c\x64\x32\xd8\xbf\x1c\xfe\xbd\xf1\x06\x9b\x90\xa3\x5f\x0d\x04\xcb\xdf\x13\x0b\x0d\xfc\x78\x75\xf4\xa4\xe6\x2c\xdb\x8e\x52\x5a\xad\xd7\xce\x84\x25\x20\xa4\x82\xac\x18\xf0\x94\x42\xd7\x83\x05\xfe\x85\xa7\x4e\x39\xe7\x60\xa4\x83\x74\x82\xed\x2f\x43\x7d\xd1\x3b\x2e\xc1\x04\x2a\xfc\xf9\xde\xcd\xc3\xe8\x77\xe5\x0f\xf4\x10\x6a\xd1\x0a\x52\x52\x30\xd1\x19\x20\x32\x4a\x81\x09\x4d\xa3\x1d\xea\xb6\x47\x6a\xa4\x2f\x20\xc8\x48\x43\xcf\xc1\xc5\x85\x45\xee\x80\x35\x2b\xdd\x37\x40\xdd\x6a\x16\x79\x2a\xe2\xd8\x6f\x11\x64\x1b\xb7\x17\xc2",
+       "\x92\xaa\xdc\x02\xbb\x97\x95\xa4\x8b\x03\x10\x34\xee\x6a\xb8\x73\xdf\x48\x1d\x23\x29\x32\xfb\x5f\xd6\xc3\x76\x2e\x50\xe5\x8d\xa4\x6d\x1f\x5e\x5e\x87\x45\x97\xf1\x5c\x83\x12\x7f\x0a\x30\x42\xb1",
+       179 },
+      { GCRY_MD_SHA3_384,
+       "\x51\x79\x88\x87\x24\x81\x9f\xba\xd3\xaf\xa9\x27\xd3\x57\x77\x96\x66\x0e\x6a\x81\xc5\x2d\x98\xe9\x30\x32\x61\xd5\xa4\xa8\x32\x32\xf6\xf7\x58\x93\x4d\x50\xaa\x83\xff\x9e\x20\xa5\x92\x6d\xfe\xba\xac\x49\x52\x9d\x00\x6e\xb9\x23\xc5\xae\x50\x48\xed\x54\x4e\xc4\x71\xed\x71\x91\xed\xf4\x63\x63\x38\x38\x24\xf9\x15\x76\x9b\x3e\x68\x80\x94\xc6\x82\xb0\x21\x51\xe5\xee\x01\xe5\x10\xb4\x31\xc8\x86\x5a\xff\x8b\x6b\x6f\x2f\x59\xcb\x6d\x12\x9d\xa7\x9e\x97\xc6\xd2\xb8\xfa\x6c\x6d\xa3\xf6\x03\x19\x9d\x2d\x1b\xca\xb5\x47\x68\x2a\x81\xcd\x6c\xf6\x5f\x65\x51\x12\x13\x91\xd7\x8b\xcc\x23\xb5\xbd\x0e\x92\x2e\xc6\xd8\xbf\x97\xc9\x52\xe8\x4d\xd2\x8a\xef\x90\x9a\xba\x31\xed\xb9\x03\xb2\x8f\xbf\xc3\x3b\x77\x03\xcd\x99\x62\x15\xa1\x12\x38",
+       "\x0d\x0c\xcd\xbf\xeb\x0a\x93\x3f\x21\x1e\xaa\x94\xeb\x45\x29\x00\x32\x43\x40\x50\x5c\xcf\x8d\xb7\xad\x93\xe9\x76\x27\x1f\x81\x2f\xb8\x90\x78\x05\xf6\x31\x3d\x0b\x09\x31\xf5\xc9\x20\x3b\xdb\xa5",
+       180 },
+      { GCRY_MD_SHA3_384,
+       "\x57\x6e\xf3\x52\x0d\x30\xb7\xa4\x89\x9b\x8c\x0d\x5e\x35\x9e\x45\xc5\x18\x9a\xdd\x10\x0e\x43\xbe\x42\x9a\x02\xfb\x3d\xe5\xff\x4f\x8f\xd0\xe7\x9d\x96\x63\xac\xca\x72\xcd\x29\xc9\x45\x82\xb1\x92\x92\xa5\x57\xc5\xb1\x31\x52\x97\xd1\x68\xfb\xb5\x4e\x9e\x2e\xcd\x13\x80\x9c\x2b\x5f\xce\x99\x8e\xdc\x65\x70\x54\x5e\x14\x99\xdb\xe7\xfb\x74\xd4\x7c\xd7\xf3\x58\x23\xb2\x12\xb0\x5b\xf3\xf5\xa7\x9c\xaa\x34\x22\x4f\xdd\x67\x0d\x33\x5f\xcb\x10\x6f\x5d\x92\xc3\x94\x6f\x44\xd3\xaf\xcb\xae\x2e\x41\xac\x55\x4d\x8e\x67\x59\xf3\x32\xb7\x6b\xe8\x9a\x03\x24\xaa\x12\xc5\x48\x2d\x1e\xa3\xee\x89\xde\xd4\x93\x6f\x3e\x3c\x08\x04\x36\xf5\x39\xfa\x13\x7e\x74\xc6\xd3\x38\x9b\xdf\x5a\x45\x07\x4c\x47\xbc\x7b\x20\xb0\x94\x84\x07\xa6\x6d\x85\x5e\x2f",
+       "\xfe\xf6\xb1\xf2\x7b\x0c\xeb\xc4\x56\x85\x88\xe6\x27\xd2\x8d\xd5\x69\xa5\x8a\x8f\x9a\x51\xa1\xd2\x88\x7b\x40\xf5\x54\x7b\x2c\x67\xc7\x19\x17\xbe\x99\x8d\x19\x87\xac\x78\xe9\x07\x7c\xc7\x90\xab",
+       181 },
+      { GCRY_MD_SHA3_384,
+       "\x0d\xf2\x15\x2f\xa4\xf4\x35\x7c\x87\x41\x52\x9d\xd7\x7e\x78\x39\x25\xd3\xd7\x6e\x95\xba\xfa\x2b\x54\x2a\x2c\x33\xf3\xd1\xd1\x17\xd1\x59\xcf\x47\x3f\x82\x31\x03\x56\xfe\xe4\xc9\x0a\x9e\x50\x5e\x70\xf8\xf2\x48\x59\x65\x63\x68\xba\x09\x38\x1f\xa2\x45\xeb\x6c\x3d\x76\x3f\x30\x93\xf0\xc8\x9b\x97\x2e\x66\xb5\x3d\x59\x40\x6d\x9f\x01\xae\xa0\x7f\x8b\x3b\x61\x5c\xac\x4e\xe4\xd0\x5f\x54\x2e\x7d\x0d\xab\x45\xd6\x7c\xcc\xcd\x3a\x60\x6c\xcb\xeb\x31\xea\x1f\xa7\x00\x5b\xa0\x71\x76\xe6\x0d\xab\x7d\x78\xf6\x81\x0e\xf0\x86\xf4\x2f\x08\xe5\x95\xf0\xec\x21\x73\x72\xb9\x89\x70\xcc\x63\x21\x57\x6d\x92\xce\x38\xf7\xc3\x97\xa4\x03\xba\xda\x15\x48\xd2\x05\xc3\x43\xac\x09\xde\xca\x86\x32\x53\x73\xc3\xb7\x6d\x9f\x32\x02\x8f\xea\x8e\xb3\x25\x15",
+       "\xe9\x95\x77\x32\xe7\xda\xb6\x45\x50\xf0\x03\xee\x6d\x03\x53\xae\x89\xbd\xc6\xd6\x9d\x05\x76\x60\x24\xcf\xf1\x89\xe4\xfc\x8f\xaa\x41\xdb\x72\x95\x4e\x8e\x5a\xc0\xb2\x92\x65\xc8\xf7\x85\xe7\x37",
+       182 },
+      { GCRY_MD_SHA3_384,
+       "\x3e\x15\x35\x0d\x87\xd6\xeb\xb5\xc8\xad\x99\xd4\x25\x15\xcf\xe1\x79\x80\x93\x3c\x7a\x8f\x6b\x8b\xbb\xf0\xa6\x37\x28\xce\xfa\xad\x20\x52\x62\x3c\x0b\xd5\x93\x18\x39\x11\x2a\x48\x63\x3f\xb3\xc2\x00\x4e\x07\x49\xc8\x7a\x41\xb2\x6a\x8b\x48\x94\x55\x39\xd1\xff\x41\xa4\xb2\x69\x46\x2f\xd1\x99\xbf\xec\xd4\x53\x74\x75\x6f\x55\xa9\x11\x6e\x92\x09\x3a\xc9\x94\x51\xae\xfb\x2a\xf9\xfd\x32\xd6\xd7\xf5\xfb\xc7\xf7\xa5\x40\xd5\x09\x7c\x09\x6e\xbc\x3b\x3a\x72\x15\x41\xde\x07\x3a\x1c\xc0\x2f\x7f\xb0\xfb\x1b\x93\x27\xfb\x0b\x12\x18\xca\x49\xc9\x48\x7a\xb5\x39\x66\x22\xa1\x3a\xe5\x46\xc9\x7a\xbd\xef\x6b\x56\x38\x0d\xda\x70\x12\xa8\x38\x40\x91\xb6\x65\x6d\x0a\xb2\x72\xd3\x63\xce\xa7\x81\x63\xff\x76\x5c\xdd\x13\xab\x17\x38\xb9\x40\xd1\x6c\xae",
+       "\x98\xd7\x3b\x35\x55\xf0\x03\x05\x8f\x7b\x5a\x14\x5d\x89\xfa\xec\x46\xc1\x70\x99\xa3\x54\xef\x38\x34\xa2\x01\x42\xdb\xd5\x0a\x0e\x80\x54\x59\x8c\xe7\x94\x1b\xf5\xdd\x4d\xf7\xcc\xf2\x18\xf0\x2f",
+       183 },
+      { GCRY_MD_SHA3_384,
+       "\xc3\x8d\x6b\x0b\x75\x7c\xb5\x52\xbe\x40\x94\x0e\xce\x00\x09\xef\x3b\x0b\x59\x30\x7c\x14\x51\x68\x6f\x1a\x22\x70\x29\x22\x80\x0d\x58\xbc\xe7\xa6\x36\xc1\x72\x7e\xe5\x47\xc0\x1b\x21\x47\x79\xe8\x98\xfc\x0e\x56\x0f\x8a\xe7\xf6\x1b\xef\x4d\x75\xea\xa6\x96\xb9\x21\xfd\x6b\x73\x5d\x17\x15\x35\xe9\xed\xd2\x67\xc1\x92\xb9\x98\x80\xc8\x79\x97\x71\x10\x02\x00\x90\x95\xd8\xa7\xa4\x37\xe2\x58\x10\x4a\x41\xa5\x05\xe5\xef\x71\xe5\x61\x3d\xdd\x20\x08\x19\x5f\x0c\x57\x4e\x6b\xa3\xfe\x40\x09\x9c\xfa\x11\x6e\x5f\x1a\x2f\xa8\xa6\xda\x04\xba\xdc\xb4\xe2\xd5\xd0\xde\x31\xfd\xc4\x80\x08\x91\xc4\x57\x81\xa0\xaa\xc7\xc9\x07\xb5\x6d\x63\x1f\xca\x5c\xe8\xb2\xcd\xe6\x20\xd1\x1d\x17\x77\xed\x9f\xa6\x03\x54\x1d\xe7\x94\xdd\xc5\x75\x8f\xcd\x5f\xad\x78\xc0",
+       "\x37\x95\xde\x49\x0f\x43\xb9\x89\x99\x47\xc1\xc3\x05\xc3\x0e\x26\x33\x1b\xa0\xe6\x11\xdc\xe7\x96\x11\x72\xb2\xe4\x29\x99\x32\x14\x7b\xc9\xe2\x41\xc3\x2e\x61\xfa\x96\x4d\x4f\x43\x6e\xcc\xfd\x37",
+       184 },
+      { GCRY_MD_SHA3_384,
+       "\x8d\x2d\xe3\xf0\xb3\x7a\x63\x85\xc9\x07\x39\x80\x5b\x17\x00\x57\xf0\x91\xcd\x0c\x7a\x0b\xc9\x51\x54\x0f\x26\xa5\xa7\x5b\x3e\x69\x46\x31\xbb\x64\xc7\x63\x5e\xed\x31\x6f\x51\x31\x8e\x9d\x8d\xe1\x3c\x70\xa2\xab\xa0\x4a\x14\x83\x68\x55\xf3\x5e\x48\x05\x28\xb7\x76\xd0\xa1\xe8\xa2\x3b\x54\x7c\x8b\x8d\x6a\x0d\x09\xb2\x41\xd3\xbe\x93\x77\x16\x0c\xca\x4e\x67\x93\xd0\x0a\x51\x5d\xc2\x99\x2c\xb7\xfc\x74\x1d\xac\xa1\x71\x43\x1d\xa9\x9c\xce\x6f\x77\x89\xf1\x29\xe2\xac\x5c\xf6\x5b\x40\xd7\x03\x03\x5c\xd2\x18\x5b\xb9\x36\xc8\x20\x02\xda\xf8\xcb\xc2\x7a\x7a\x9e\x55\x4b\x06\x19\x66\x30\x44\x6a\x6f\x0a\x14\xba\x15\x5e\xd2\x6d\x95\xbd\x62\x7b\x72\x05\xc0\x72\xd0\x2b\x60\xdb\x0f\xd7\xe4\x9e\xa0\x58\xc2\xe0\xba\x20\x2d\xaf\xf0\xde\x91\xe8\x45\xcf\x79",
+       "\xe9\xf2\x89\xe6\x71\x54\x1f\xec\x45\x99\x91\x5a\x0d\x99\x35\xbf\x5c\x20\xa1\x2c\x20\x3b\xcd\xe8\x8a\x46\xea\xf5\xca\xb2\xd4\x37\xf9\xfc\xde\xf6\x7b\x98\x76\x8b\xb8\x0c\x9a\x87\x4b\x3f\x46\xc7",
+       185 },
+      { GCRY_MD_SHA3_384,
+       "\xc4\x64\xbb\xda\xd2\x75\xc5\x0d\xcd\x98\x3b\x65\xad\x10\x19\xb9\xff\x85\xa1\xe7\x1c\x80\x7f\x32\x04\xbb\x2c\x92\x1d\xc3\x1f\xbc\xd8\xc5\xfc\x45\x86\x8a\xe9\xef\x85\xb6\xc9\xb8\x3b\xba\x2a\x5a\x82\x22\x01\xed\x68\x58\x6e\xc5\xec\x27\xfb\x28\x57\xa5\xd1\xa2\xd0\x9d\x09\x11\x5f\x22\xdc\xc3\x9f\xe6\x1f\x5e\x1b\xa0\xff\x6e\x8b\x4a\xcb\x4c\x6d\xa7\x48\xbe\x7f\x3f\x08\x39\x73\x93\x94\xff\x7f\xa8\xe3\x9f\x7f\x7e\x84\xa3\x3c\x38\x66\x87\x5c\x01\xbc\xb1\x26\x3c\x94\x05\xd9\x19\x08\xe9\xe0\xb5\x0e\x74\x59\xfa\xbb\x63\xd8\xc6\xbb\xb7\x3d\x8e\x34\x83\xc0\x99\xb5\x5b\xc3\x0f\xf0\x92\xff\x68\xb6\xad\xed\xfd\x47\x7d\x63\x57\x0c\x9f\x55\x15\x84\x7f\x36\xe2\x4b\xa0\xb7\x05\x55\x71\x30\xce\xc5\x7e\xba\xd1\xd0\xb3\x1a\x37\x8e\x91\x89\x4e\xe2\x6e\x3a\x04",
+       "\x88\xc2\x3b\xe0\x40\xbe\x64\xd2\x3a\xee\x8d\x7e\xe9\x62\x22\x8a\x6f\x07\x83\x1b\x0e\x05\xfb\xe2\xf2\x5f\x07\x72\x9f\x00\xc2\xc6\x17\xeb\x69\x75\xf5\x7b\x3f\x17\xdd\x54\x0e\x8e\xbc\xa6\x54\xa9",
+       186 },
+      { GCRY_MD_SHA3_384,
+       "\x8b\x8d\x68\xbb\x8a\x75\x73\x2f\xe2\x72\x81\x5a\x68\xa1\xc9\xc5\xaa\x31\xb4\x1d\xed\xc8\x49\x3e\x76\x52\x5d\x1d\x01\x3d\x33\xce\xbd\x9e\x21\xa5\xbb\x95\xdb\x26\x16\x97\x6a\x8c\x07\xfc\xf4\x11\xf5\xf6\xbc\x6f\x7e\x0b\x57\xac\xa7\x8c\xc2\x79\x0a\x6f\x9b\x89\x88\x58\xac\x9c\x79\xb1\x65\xff\x24\xe6\x66\x77\x53\x1e\x39\xf5\x72\xbe\x5d\x81\xeb\x32\x64\x52\x41\x81\x11\x5f\x32\x78\x02\x57\xbf\xb9\xae\xec\x6a\xf1\x2a\xf2\x8e\x58\x7c\xac\x06\x8a\x1a\x29\x53\xb5\x9a\xd6\x80\xf4\xc2\x45\xb2\xe3\xec\x36\xf5\x99\x40\xd3\x7e\x1d\x3d\xb3\x8e\x13\xed\xb2\x9b\x5c\x0f\x40\x4f\x6f\xf8\x7f\x80\xfc\x8b\xe7\xa2\x25\xff\x22\xfb\xb9\xc8\xb6\xb1\xd7\x33\x0c\x57\x84\x0d\x24\xbc\x75\xb0\x6b\x80\xd3\x0d\xad\x68\x06\x54\x4d\x51\x0a\xf6\xc4\x78\x5e\x82\x3a\xc3\xe0\xb8",
+       "\x6c\x42\xde\xe6\x1c\xd9\x7c\x50\xf5\x34\x0c\xf4\xdc\x4f\x7e\x31\x9f\xb5\xfa\xc7\xa2\x6b\x41\xde\xe6\x6d\x78\x98\x04\xbd\x1f\xef\x1e\xf2\x91\x16\x43\xc9\xc1\xe2\xc0\x48\x5c\x97\x9b\x36\xd9\x27",
+       187 },
+      { GCRY_MD_SHA3_384,
+       "\x6b\x01\x87\x10\x44\x6f\x36\x8e\x74\x21\xf1\xbc\x0c\xcf\x56\x2d\x9c\x18\x43\x84\x6b\xc8\xd9\x8d\x1c\x9b\xf7\xd9\xd6\xfc\xb4\x8b\xfc\x3b\xf8\x3b\x36\xd4\x4c\x4f\xa9\x34\x30\xaf\x75\xcd\x19\x0b\xde\x36\xa7\xf9\x2f\x86\x7f\x58\xa8\x03\x90\x0d\xf8\x01\x81\x50\x38\x4d\x85\xd8\x21\x32\xf1\x23\x00\x6a\xc2\xae\xba\x58\xe0\x2a\x03\x7f\xe6\xaf\xbd\x65\xec\xa7\xc4\x49\x77\xdd\x3d\xc7\x4f\x48\xb6\xe7\xa1\xbf\xd5\xcc\x4d\xcf\x24\xe4\xd5\x2e\x92\xbd\x44\x55\x84\x8e\x49\x28\xb0\xea\xc8\xb7\x47\x6f\xe3\xcc\x03\xe8\x62\xaa\x4d\xff\x44\x70\xdb\xfe\xd6\xde\x48\xe4\x10\xf2\x50\x96\x48\x7e\xcf\xc3\x2a\x27\x27\x7f\x3f\x50\x23\xb2\x72\x5a\xde\x46\x1b\x13\x55\x88\x95\x54\xa8\x83\x6c\x9c\xf5\x3b\xd7\x67\xf5\x73\x7d\x55\x18\x4e\xea\x1a\xb3\xf5\x3e\xdd\x09\x76\xc4\x85",
+       "\x72\x01\x50\xfd\x5a\x1c\xf9\x4a\x42\xf9\x22\xef\xcb\xb7\x23\xff\x94\x8f\x74\xca\x6d\x0a\x3f\x39\x9a\xc5\x4d\xa8\xb3\xbc\x07\xf3\x9e\x6e\x29\x79\xc1\x6c\x87\x58\x66\xcf\x2f\x58\x4c\xa7\xf2\xdb",
+       188 },
+      { GCRY_MD_SHA3_384,
+       "\xc9\x53\x4a\x24\x71\x4b\xd4\xbe\x37\xc8\x8a\x3d\xa1\x08\x2e\xda\x7c\xab\xd1\x54\xc3\x09\xd7\xbd\x67\x0d\xcc\xd9\x5a\xa5\x35\x59\x44\x63\x05\x8a\x29\xf7\x90\x31\xd6\xec\xaa\x9f\x67\x5d\x12\x11\xe9\x35\x9b\xe8\x26\x69\xa7\x9c\x85\x5e\xa8\xd8\x9d\xd3\x8c\x2c\x76\x1d\xdd\x0e\xc0\xce\x9e\x97\x59\x74\x32\xe9\xa1\xbe\xae\x06\x2c\xdd\x71\xed\xfd\xfd\x46\x41\x19\xbe\x9e\x69\xd1\x8a\x7a\x7f\xd7\xce\x0e\x21\x06\xf0\xc8\xb0\xab\xf4\x71\x5e\x2c\xa4\x8e\xf9\xf4\x54\xdc\x20\x3c\x96\x65\x66\x53\xb7\x27\x08\x35\x13\xf8\xef\xb8\x6e\x49\xc5\x13\xbb\x75\x8b\x3b\x05\x2f\xe2\x1f\x1c\x05\xbb\x33\xc3\x71\x29\xd6\xcc\x81\xf1\xae\xf6\xad\xc4\x5b\x0e\x88\x27\xa8\x30\xfe\x54\x5c\xf5\x7d\x09\x55\x80\x2c\x11\x7d\x23\xcc\xb5\x5e\xa2\x8f\x95\xc0\xd8\xc2\xf9\xc5\xa2\x42\xb3\x3f",
+       "\xfa\x6f\x90\x93\x58\x43\xd4\xf5\x8e\x77\xca\xbe\x4b\xa6\x62\xb4\xfa\xbc\x17\x32\x72\x5f\xaf\x95\x2e\xee\xd7\x0f\xa0\xaa\xd6\xa9\x8f\xe6\x7f\x3b\x67\x36\xa1\xc8\xf7\xc5\xbe\xd4\xd9\xb0\x17\xe0",
+       189 },
+      { GCRY_MD_SHA3_384,
+       "\x07\x90\x6c\x87\x29\x7b\x86\x7a\xbf\x45\x76\xe9\xf3\xcc\x7f\x82\xf2\x2b\x15\x4a\xfc\xbf\x29\x3b\x93\x19\xf1\xb0\x58\x4d\xa6\xa4\x0c\x27\xb3\x2e\x0b\x1b\x7f\x41\x2c\x4f\x1b\x82\x48\x0e\x70\xa9\x23\x5b\x12\xec\x27\x09\x0a\x5a\x33\x17\x5a\x2b\xb2\x8d\x8a\xdc\x47\x5c\xef\xe3\x3f\x78\x03\xf8\xce\x27\x96\x72\x17\x38\x1f\x02\xe6\x7a\x3b\x4f\x84\xa7\x1f\x1c\x52\x28\xe0\xc2\xad\x97\x13\x73\xf6\xf6\x72\x62\x4f\xce\xa8\xd1\xa9\xf8\x51\x70\xfa\xd3\x0f\xa0\xbb\xd2\x50\x35\xc3\xb4\x1a\x61\x75\xd4\x67\x99\x8b\xd1\x21\x5f\x6f\x38\x66\xf5\x38\x47\xf9\xcf\x68\xef\x3e\x2f\xbb\x54\xbc\x99\x4d\xe2\x30\x2b\x82\x9c\x5e\xea\x68\xec\x44\x1f\xcb\xaf\xd7\xd1\x6a\xe4\xfe\x9f\xff\x98\xbf\x00\xe5\xbc\x2a\xd5\x4d\xd9\x1f\xf9\xfd\xa4\xdd\x77\xb6\xc7\x54\xa9\x19\x55\xd1\xfb\xaa\xd0",
+       "\x4e\x28\x32\xfe\xe2\x90\xd1\x91\x7c\x15\xb3\x18\x93\xf6\x57\x8c\x12\x99\x44\x5b\x99\xbc\x48\x70\x8e\x13\x34\x8a\x11\xeb\x2f\x27\xfe\x21\x7a\x63\xf5\x32\x58\x37\x93\xd1\x8c\xde\xcc\xaa\x78\xb9",
+       190 },
+      { GCRY_MD_SHA3_384,
+       "\x58\x8e\x94\xb9\x05\x4a\xbc\x21\x89\xdf\x69\xb8\xba\x34\x34\x1b\x77\xcd\xd5\x28\xe7\x86\x0e\x5d\xef\xca\xa7\x9b\x0c\x9a\x45\x2a\xd4\xb8\x2a\xa3\x06\xbe\x84\x53\x6e\xb7\xce\xdc\xbe\x05\x8d\x7b\x84\xa6\xae\xf8\x26\xb0\x28\xb8\xa0\x27\x1b\x69\xac\x36\x05\xa9\x63\x5e\xa9\xf5\xea\x0a\xa7\x00\xf3\xeb\x78\x35\xbc\x54\x61\x1b\x92\x29\x64\x30\x0c\x95\x3e\xfe\x74\x91\xe3\x67\x7c\x2c\xeb\xe0\x82\x2e\x95\x6c\xd1\x64\x33\xb0\x2c\x68\xc4\xa2\x32\x52\xc3\xf9\xe1\x51\xa4\x16\xb4\x96\x32\x57\xb7\x83\xe0\x38\xf6\xb4\xd5\xc9\xf1\x10\xf8\x71\x65\x2c\x7a\x64\x9a\x7b\xce\xdc\xbc\xcc\x6f\x2d\x07\x25\xbb\x90\x3c\xc1\x96\xba\x76\xc7\x6a\xa9\xf1\x0a\x19\x0b\x1d\x11\x68\x99\x3b\xaa\x9f\xfc\x96\xa1\x65\x52\x16\x77\x34\x58\xbe\xc7\x2b\x0e\x39\xc9\xf2\xc1\x21\x37\x8f\xea\xb4\xe7\x6a",
+       "\x1f\xb9\x7d\x6f\x42\x48\x0e\x9f\x13\xc9\x34\xc4\xa8\x74\x87\x7a\x80\x8f\x1d\x73\x31\x4c\x54\x4d\x85\x70\xc0\x74\x9f\x20\xfa\x35\xf5\x3a\x0c\x0b\xda\x1f\x10\xd1\xa1\x0a\x02\x9a\xbb\xb5\x0b\xc7",
+       191 },
+      { GCRY_MD_SHA3_384,
+       "\x08\x95\x9a\x7e\x4b\xaa\xe8\x74\x92\x88\x13\x36\x40\x71\x19\x4e\x29\x39\x77\x2f\x20\xdb\x7c\x31\x57\x07\x89\x87\xc5\x57\xc2\xa6\xd5\xab\xe6\x8d\x52\x0e\xef\x3d\xc4\x91\x69\x2e\x1e\x21\xbc\xd8\x80\xad\xeb\xf6\x3b\xb4\x21\x3b\x50\x89\x7f\xa0\x05\x25\x6e\xd4\x1b\x56\x90\xf7\x8f\x52\x85\x5c\x8d\x91\x68\xa4\xb6\x66\xfc\xe2\xda\x2b\x45\x6d\x7a\x7e\x7c\x17\xab\x5f\x2f\xb1\xee\x90\xb7\x9e\x69\x87\x12\xe9\x63\x71\x59\x83\xfd\x07\x64\x1a\xe4\xb4\xe9\xdc\x73\x20\x3f\xac\x1a\xe1\x1f\xa1\xf8\xc7\x94\x1f\xcc\x82\xea\xb2\x47\xad\xdb\x56\xe2\x63\x84\x47\xe9\xd6\x09\xe6\x10\xb6\x0c\xe0\x86\x65\x6a\xae\xbf\x1d\xa3\xc8\xa2\x31\xd7\xd9\x4e\x2f\xd0\xaf\xe4\x6b\x39\x1f\xf1\x4a\x72\xea\xeb\x3f\x44\xad\x4d\xf8\x58\x66\xde\xf4\x3d\x47\x81\xa0\xb3\x57\x8b\xc9\x96\xc8\x79\x70\xb1\x32",
+       "\x86\xb3\xc8\x1a\xa3\x98\xc8\x81\x9a\xfc\x4f\x28\x2d\xfb\xce\x24\xf4\x19\x2b\x25\x30\xc2\x67\xa7\x83\x73\xd2\x53\xc3\x5c\x1d\xcc\x4f\x40\x83\x55\x29\x56\x3f\xd4\x2a\x33\xfd\x2c\xbd\x68\x05\x15",
+       192 },
+      { GCRY_MD_SHA3_384,
+       "\xcb\x2a\x23\x4f\x45\xe2\xec\xd5\x86\x38\x95\xa4\x51\xd3\x89\xa3\x69\xaa\xb9\x9c\xfe\xf0\xd5\xc9\xff\xca\x1e\x6e\x63\xf7\x63\xb5\xc1\x4f\xb9\xb4\x78\x31\x3c\x8e\x8c\x0e\xfe\xb3\xac\x95\x00\xcf\x5f\xd9\x37\x91\xb7\x89\xe6\x7e\xac\x12\xfd\x03\x8e\x25\x47\xcc\x8e\x0f\xc9\xdb\x59\x1f\x33\xa1\xe4\x90\x7c\x64\xa9\x22\xdd\xa2\x3e\xc9\x82\x73\x10\xb3\x06\x09\x85\x54\xa4\xa7\x8f\x05\x02\x62\xdb\x5b\x54\x5b\x15\x9e\x1f\xf1\xdc\xa6\xeb\x73\x4b\x87\x23\x43\xb8\x42\xc5\x7e\xaf\xcf\xda\x84\x05\xee\xdb\xb4\x8e\xf3\x2e\x99\x69\x6d\x13\x59\x79\x23\x5c\x3a\x05\x36\x4e\x37\x1c\x2d\x76\xf1\x90\x2f\x1d\x83\x14\x6d\xf9\x49\x5c\x0a\x6c\x57\xd7\xbf\x9e\xe7\x7e\x80\xf9\x78\x7a\xee\x27\xbe\x1f\xe1\x26\xcd\xc9\xef\x89\x3a\x4a\x7d\xcb\xbc\x36\x7e\x40\xfe\x4e\x1e\xe9\x0b\x42\xea\x25\xaf\x01",
+       "\xa6\xbf\x54\x8a\xb1\x9f\xf6\x0d\x6a\x87\x29\xfa\x62\xfd\xc9\xb5\x92\x37\x84\x37\x39\xaf\xff\x87\x72\x33\xed\x37\x4b\xcf\x70\xa0\x17\x12\x69\x74\xc2\xd1\xa3\x22\x2d\x8d\x90\x6b\xe8\x50\xa2\x5d",
+       193 },
+      { GCRY_MD_SHA3_384,
+       "\xd1\x6b\xea\xdf\x02\xab\x1d\x4d\xc6\xf8\x8b\x8c\x45\x54\xc5\x1e\x86\x6d\xf8\x30\xb8\x9c\x06\xe7\x86\xa5\xf8\x75\x7e\x89\x09\x31\x0a\xf5\x1c\x84\x0e\xfe\x8d\x20\xb3\x53\x31\xf4\x35\x5d\x80\xf7\x32\x95\x97\x46\x53\xdd\xd6\x20\xcd\xde\x47\x30\xfb\x6c\x8d\x0d\x2d\xcb\x2b\x45\xd9\x2d\x4f\xbd\xb5\x67\xc0\xa3\xe8\x6b\xd1\xa8\xa7\x95\xaf\x26\xfb\xf2\x9f\xc6\xc6\x59\x41\xcd\xdb\x09\x0f\xf7\xcd\x23\x0a\xc5\x26\x8a\xb4\x60\x6f\xcc\xba\x9e\xde\xd0\xa2\xb5\xd0\x14\xee\x0c\x34\xf0\xb2\x88\x1a\xc0\x36\xe2\x4e\x15\x1b\xe8\x9e\xeb\x6c\xd9\xa7\xa7\x90\xaf\xcc\xff\x23\x4d\x7c\xb1\x1b\x99\xeb\xf5\x8c\xd0\xc5\x89\xf2\x0b\xda\xc4\xf9\xf0\xe2\x8f\x75\xe3\xe0\x4e\x5b\x3d\xeb\xce\x60\x7a\x49\x6d\x84\x8d\x67\xfa\x7b\x49\x13\x2c\x71\xb8\x78\xfd\x55\x57\xe0\x82\xa1\x8e\xca\x1f\xbd\xa9\x4d\x4b",
+       "\xba\x7d\x3b\x6a\xf5\x96\x6c\x8c\x27\x23\xb1\x31\x88\x20\x50\x5d\x04\x0d\xa8\x10\x12\x6a\xbc\x3e\x65\x08\x8d\xc4\x21\xe4\x6d\x3e\x54\xdd\x31\x77\x7c\x53\x9a\xe0\x83\xb7\xb8\xa4\xe2\x30\x38\x36",
+       194 },
+      { GCRY_MD_SHA3_384,
+       "\x8f\x65\xf6\xbc\x59\xa8\x57\x05\x01\x6e\x2b\xae\x7f\xe5\x79\x80\xde\x31\x27\xe5\xab\x27\x5f\x57\x3d\x33\x4f\x73\xf8\x60\x31\x06\xec\x35\x53\x01\x66\x08\xef\x2d\xd6\xe6\x9b\x24\xbe\x0b\x71\x13\xbf\x6a\x76\x0b\xa6\xe9\xce\x1c\x48\xf9\xe1\x86\x01\x2c\xf9\x6a\x1d\x48\x49\xd7\x5d\xf5\xbb\x83\x15\x38\x7f\xd7\x8e\x9e\x15\x3e\x76\xf8\xba\x7e\xc6\xc8\x84\x98\x10\xf5\x9f\xb4\xbb\x9b\x00\x43\x18\x21\x0b\x37\xf1\x29\x95\x26\x86\x6f\x44\x05\x9e\x01\x7e\x22\xe9\x6c\xbe\x41\x86\x99\xd0\x14\xc6\xea\x01\xc9\xf0\x03\x8b\x10\x29\x98\x84\xdb\xec\x31\x99\xbb\x05\xad\xc9\x4e\x95\x5a\x15\x33\x21\x9c\x11\x15\xfe\xd0\xe5\xf2\x12\x28\xb0\x71\xf4\x0d\xd5\x7c\x42\x40\xd9\x8d\x37\xb7\x3e\x41\x2f\xe0\xfa\x47\x03\x12\x0d\x7c\x0c\x67\x97\x2e\xd2\x33\xe5\xde\xb3\x00\xa2\x26\x05\x47\x2f\xa3\xa3\xba\x86",
+       "\x48\xca\x59\x12\xc1\x11\xdb\x66\x7a\x77\xbe\x7c\x77\xf8\x41\xe8\xb3\x71\x30\x24\x83\x77\xa1\x9c\xd2\xfa\x3c\xd2\xee\xc4\x8b\x33\x7c\xfe\x07\xc2\x90\xf2\x69\x0a\xd4\x9e\x79\xce\x3a\x9f\x9e\x53",
+       195 },
+      { GCRY_MD_SHA3_384,
+       "\x84\x89\x1e\x52\xe0\xd4\x51\x81\x32\x10\xc3\xfd\x63\x5b\x39\xa0\x3a\x6b\x7a\x73\x17\xb2\x21\xa7\xab\xc2\x70\xdf\xa9\x46\xc4\x26\x69\xaa\xcb\xbb\xdf\x80\x1e\x15\x84\xf3\x30\xe2\x8c\x72\x98\x47\xea\x14\x15\x2b\xd6\x37\xb3\xd0\xf2\xb3\x8b\x4b\xd5\xbf\x9c\x79\x1c\x58\x80\x62\x81\x10\x3a\x3e\xab\xba\xed\xe5\xe7\x11\xe5\x39\xe6\xa8\xb2\xcf\x29\x7c\xf3\x51\xc0\x78\xb4\xfa\x8f\x7f\x35\xcf\x61\xbe\xbf\x88\x14\xbf\x24\x8a\x01\xd4\x1e\x86\xc5\x71\x5e\xa4\x0c\x63\xf7\x37\x53\x79\xa7\xeb\x1d\x78\xf2\x76\x22\xfb\x46\x8a\xb7\x84\xaa\xab\xa4\xe5\x34\xa6\xdf\xd1\xdf\x6f\xa1\x55\x11\x34\x1e\x72\x5e\xd2\xe8\x7f\x98\x73\x7c\xcb\x7b\x6a\x6d\xfa\xe4\x16\x47\x74\x72\xb0\x46\xbf\x18\x11\x18\x7d\x15\x1b\xfa\x9f\x7b\x2b\xf9\xac\xdb\x23\xa3\xbe\x50\x7c\xdf\x14\xcf\xdf\x51\x7d\x2c\xb5\xfb\x9e\x4a\xb6",
+       "\x4b\x38\x49\xb0\x91\x6d\xd4\x45\xb1\x85\x6e\x1b\x90\x8c\x41\x4c\x75\x2d\x28\x0d\xe2\x18\x3d\xd1\xf0\x19\x3e\x73\xfd\x1b\xc0\x21\x98\x59\x95\x02\x39\x1e\x8c\xa4\x8d\x65\xe6\x10\xd6\xed\xcd\x8e",
+       196 },
+      { GCRY_MD_SHA3_384,
+       "\xfd\xd7\xa9\x43\x3a\x3b\x4a\xfa\xbd\x7a\x3a\x5e\x34\x57\xe5\x6d\xeb\xf7\x8e\x84\xb7\xa0\xb0\xca\x0e\x8c\x6d\x53\xbd\x0c\x2d\xae\x31\xb2\x70\x0c\x61\x28\x33\x4f\x43\x98\x1b\xe3\xb2\x13\xb1\xd7\xa1\x18\xd5\x9c\x7e\x6b\x64\x93\xa8\x6f\x86\x6a\x16\x35\xc1\x28\x59\xcf\xb9\xad\x17\x46\x0a\x77\xb4\x52\x2a\x5c\x18\x83\xc3\xd6\xac\xc8\x6e\x61\x62\x66\x7e\xc4\x14\xe9\xa1\x04\xaa\x89\x20\x53\xa2\xb1\xd7\x21\x65\xa8\x55\xba\xcd\x8f\xaf\x80\x34\xa5\xdd\x9b\x71\x6f\x47\xa0\x81\x8c\x09\xbb\x6b\xaf\x22\xaa\x50\x3c\x06\xb4\xca\x26\x1f\x55\x77\x61\x98\x9d\x2a\xfb\xd8\x8b\x6a\x67\x8a\xd1\x28\xaf\x68\x67\x21\x07\xd0\xf1\xfc\x73\xc5\xca\x74\x04\x59\x29\x7b\x32\x92\xb2\x81\xe9\x3b\xce\xb7\x61\xbd\xe7\x22\x1c\x3a\x55\x70\x8e\x5e\xc8\x44\x72\xcd\xdc\xaa\x84\xec\xf2\x37\x23\xcc\x09\x91\x35\x5c\x62\x80",
+       "\x02\xc9\x08\x20\xd5\xfa\x9a\x91\x07\x29\x91\xe8\x7b\xfe\xec\x7f\x18\x31\x5f\x8c\xa1\x90\x8e\xdb\xf1\x98\x86\xc4\xca\x5b\xd5\x4a\xb9\xec\x96\xa6\xab\x7b\x81\x5b\x58\x53\x8f\x08\x88\x67\x03\x0f",
+       197 },
+      { GCRY_MD_SHA3_384,
+       "\x70\xa4\x0b\xfb\xef\x92\x27\x7a\x1a\xad\x72\xf6\xb7\x9d\x01\x77\x19\x7c\x4e\xbd\x43\x26\x68\xcf\xec\x05\xd0\x99\xac\xcb\x65\x10\x62\xb5\xdf\xf1\x56\xc0\xb2\x73\x36\x68\x7a\x94\xb2\x66\x79\xcf\xdd\x9d\xaf\x7a\xd2\x04\x33\x8d\xd9\xc4\xd1\x41\x14\x03\x3a\x5c\x22\x5b\xd1\x1f\x21\x7b\x5f\x47\x32\xda\x16\x7e\xe3\xf9\x39\x26\x2d\x40\x43\xfc\x9c\xba\x92\x30\x3b\x7b\x5e\x96\xae\xa1\x2a\xdd\xa6\x48\x59\xdf\x4b\x86\xe9\xee\x0b\x58\xe3\x90\x91\xe6\xb1\x88\xb4\x08\xac\x94\xe1\x29\x4a\x89\x11\x24\x5e\xe3\x61\xe6\x0e\x60\x1e\xff\x58\xd1\xd3\x76\x39\xf3\x75\x3b\xec\x80\xeb\xb4\xef\xde\x25\x81\x74\x36\x07\x66\x23\xfc\x65\x41\x5f\xe5\x1d\x1b\x02\x80\x36\x6d\x12\xc5\x54\xd8\x67\x43\xf3\xc3\xb6\x57\x2e\x40\x03\x61\xa6\x07\x26\x13\x14\x41\xba\x49\x3a\x83\xfb\xe9\xaf\xda\x90\xf7\xaf\x1a\xe7\x17\x23\x8d",
+       "\x75\x96\x75\x01\xff\x78\x1e\xfc\x3c\x9d\x59\x71\x79\xc8\xcc\xae\xe4\x37\x3d\x9b\xf6\xaa\x6a\x5b\xed\x51\x18\x30\x3e\xdc\x8b\x74\x78\xa4\x7f\x2c\xea\xf0\xa6\xb5\xb7\x22\x4e\x53\xd5\xf1\xcd\xb3",
+       198 },
+      { GCRY_MD_SHA3_384,
+       "\x74\x35\x6e\x44\x9f\x4b\xf8\x64\x4f\x77\xb1\x4f\x4d\x67\xcb\x6b\xd9\xc1\xf5\xae\x35\x76\x21\xd5\xb8\x14\x7e\x56\x2b\x65\xc6\x65\x85\xca\xf2\xe4\x91\xb4\x85\x29\xa0\x1a\x34\xd2\x26\xd4\x36\x95\x91\x53\x81\x53\x80\xd5\x68\x9e\x30\xb3\x53\x57\xcd\xac\x6e\x08\xd3\xf2\xb0\xe8\x8e\x20\x06\x00\xd6\x2b\xd9\xf5\xea\xf4\x88\xdf\x86\xa4\x47\x0e\xa2\x27\x00\x61\x82\xe4\x48\x09\x00\x98\x68\xc4\xc2\x80\xc4\x3d\x7d\x64\xa5\x26\x8f\xa7\x19\x07\x49\x60\x08\x7b\x3a\x6a\xbc\x83\x78\x82\xf8\x82\xc8\x37\x83\x45\x35\x92\x93\x89\xa1\x2b\x2c\x78\x18\x7e\x2e\xa0\x7e\xf8\xb8\xee\xf2\x7d\xc8\x50\x02\xc3\xae\x35\xf1\xa5\x0b\xee\x6a\x1c\x48\xba\x7e\x17\x5f\x33\x16\x67\x0b\x27\x98\x34\x72\xaa\x6a\x61\xee\xd0\xa6\x83\xa3\x9e\xe3\x23\x08\x06\x20\xea\x44\xa9\xf7\x44\x11\xae\x5c\xe9\x90\x30\x52\x8f\x9a\xb4\x9c\x79\xf2",
+       "\x29\x83\x87\xba\x8a\x3e\xb8\x8e\xe3\x6b\x42\x06\xe5\x41\x93\xbc\x58\x57\xf2\xa3\x03\xce\x41\xdf\xf7\xc3\xbd\x53\xef\x7e\xe3\xd3\x4a\xe7\xe0\xc7\x14\x31\x1a\x7b\xd8\xd2\x55\x02\xca\xb4\x14\xb7",
+       199 },
+      { GCRY_MD_SHA3_384,
+       "\x8c\x37\x98\xe5\x1b\xc6\x84\x82\xd7\x33\x7d\x3a\xbb\x75\xdc\x9f\xfe\x86\x07\x14\xa9\xad\x73\x55\x1e\x12\x00\x59\x86\x0d\xde\x24\xab\x87\x32\x72\x22\xb6\x4c\xf7\x74\x41\x5a\x70\xf7\x24\xcd\xf2\x70\xde\x3f\xe4\x7d\xda\x07\xb6\x1c\x9e\xf2\xa3\x55\x1f\x45\xa5\x58\x48\x60\x24\x8f\xab\xde\x67\x6e\x1c\xd7\x5f\x63\x55\xaa\x3e\xae\xab\xe3\xb5\x1d\xc8\x13\xd9\xfb\x2e\xaa\x4f\x0f\x1d\x9f\x83\x4d\x7c\xad\x9c\x7c\x69\x5a\xe8\x4b\x32\x93\x85\xbc\x0b\xef\x89\x5b\x9f\x1e\xdf\x44\xa0\x3d\x4b\x41\x0c\xc2\x3a\x79\xa6\xb6\x2e\x4f\x34\x6a\x5e\x8d\xd8\x51\xc2\x85\x79\x95\xdd\xbf\x5b\x2d\x71\x7a\xeb\x84\x73\x10\xe1\xf6\xa4\x6a\xc3\xd2\x6a\x7f\x9b\x44\x98\x5a\xf6\x56\xd2\xb7\xc9\x40\x6e\x8a\x9e\x8f\x47\xdc\xb4\xef\x6b\x83\xca\xac\xf9\xae\xfb\x61\x18\xbf\xcf\xf7\xe4\x4b\xef\x69\x37\xeb\xdd\xc8\x91\x86\x83\x9b\x77",
+       "\x27\xce\xf6\x5d\x1a\xec\xb7\x05\x1b\xad\x55\xda\x0d\x60\x1b\xc9\xd7\xa1\x6d\x93\x8a\x57\x15\x37\x4a\x43\x10\x9d\xd4\x1b\x5c\x27\xd2\x6c\x91\xcb\x44\xe4\xb4\x70\x02\xd9\xb9\x0a\xba\x05\x84\xd1",
+       200 },
+      { GCRY_MD_SHA3_384,
+       "\xfa\x56\xbf\x73\x0c\x4f\x83\x95\x87\x51\x89\xc1\x0c\x4f\xb2\x51\x60\x57\x57\xa8\xfe\xcc\x31\xf9\x73\x7e\x3c\x25\x03\xb0\x26\x08\xe6\x73\x1e\x85\xd7\xa3\x83\x93\xc6\x7d\xe5\x16\xb8\x53\x04\x82\x4b\xfb\x13\x5e\x33\xbf\x22\xb3\xa2\x3b\x91\x3b\xf6\xac\xd2\xb7\xab\x85\x19\x8b\x81\x87\xb2\xbc\xd4\x54\xd5\xe3\x31\x8c\xac\xb3\x2f\xd6\x26\x1c\x31\xae\x7f\x6c\x54\xef\x6a\x7a\x2a\x4c\x9f\x3e\xcb\x81\xce\x35\x55\xd4\xf0\xad\x46\x6d\xd4\xc1\x08\xa9\x03\x99\xd7\x00\x41\x99\x7c\x3b\x25\x34\x5a\x96\x53\xf3\xc9\xa6\x71\x1a\xb1\xb9\x1d\x6a\x9d\x22\x16\x44\x2d\xa2\xc9\x73\xcb\xd6\x85\xee\x76\x43\xbf\xd7\x73\x27\xa2\xf7\xae\x9c\xb2\x83\x62\x0a\x08\x71\x6d\xfb\x46\x2e\x5c\x1d\x65\x43\x2c\xa9\xd5\x6a\x90\xe8\x11\x44\x3c\xd1\xec\xb8\xf0\xde\x17\x9c\x9c\xb4\x8b\xa4\xf6\xfe\xc3\x60\xc6\x6f\x25\x2f\x6e\x64\xed\xc9\x6b",
+       "\x4a\xc9\xbd\xfd\x9f\x71\x7d\x01\x59\x89\x08\xba\x45\x76\x27\xd3\xaf\x7c\x81\x23\xf7\x11\x0d\xd7\xfd\xb4\x0e\x91\xee\x6c\xac\x20\x1a\x8b\x72\x8a\x38\x4e\x66\x38\x90\x84\x7d\xfd\x4d\xe7\xfa\x76",
+       201 },
+      { GCRY_MD_SHA3_384,
+       "\xb6\x13\x4f\x9c\x3e\x91\xdd\x80\x00\x74\x0d\x00\x9d\xd8\x06\x24\x08\x11\xd5\x1a\xb1\x54\x6a\x97\x4b\xcb\x18\xd3\x44\x64\x2b\xaa\x5c\xd5\x90\x3a\xf8\x4d\x58\xec\x5b\xa1\x73\x01\xd5\xec\x0f\x10\xcc\xd0\x50\x9c\xbb\x3f\xd3\xff\xf9\x17\x2d\x19\x3a\xf0\xf7\x82\x25\x2f\xd1\x33\x8c\x72\x44\xd4\x0e\x0e\x42\x36\x22\x75\xb2\x2d\x01\xc4\xc3\x38\x9f\x19\xdd\x69\xbd\xf9\x58\xeb\xe2\x8e\x31\xa4\xff\xe2\xb5\xf1\x8a\x87\x83\x1c\xfb\x70\x95\xf5\x8a\x87\xc9\xfa\x21\xdb\x72\xba\x26\x93\x79\xb2\xdc\x23\x84\xb3\xda\x95\x3c\x79\x25\x76\x1f\xed\x32\x46\x20\xac\xea\x43\x5e\x52\xb4\x24\xa7\x72\x3f\x6a\x23\x57\x37\x41\x57\xa3\x4c\xd8\x25\x23\x51\xc2\x5a\x1b\x23\x28\x26\xce\xfe\x1b\xd3\xe7\x0f\xfc\x15\xa3\x1e\x7c\x05\x98\x21\x9d\x7f\x00\x43\x62\x94\xd1\x18\x91\xb8\x24\x97\xbc\x78\xaa\x53\x63\x89\x2a\x24\x95\xdf\x8c\x1e\xef",
+       "\xf0\x3f\xa0\x3e\x4c\xf9\xc2\x34\x43\xd7\xdb\xdb\xb6\x6d\x9a\xbb\xaf\xef\xb6\x50\x01\x43\xff\x0b\xfb\x5d\x7d\x6c\xa2\xbf\x1d\x7c\xd0\x43\xa7\xba\x7e\xfb\x48\xf1\x5e\xbc\x68\xd1\xf9\x45\x98\xe7",
+       202 },
+      { GCRY_MD_SHA3_384,
+       "\xc9\x41\xcd\xb9\xc2\x8a\xb0\xa7\x91\xf2\xe5\xc8\xe8\xbb\x52\x85\x06\x26\xaa\x89\x20\x5b\xec\x3a\x7e\x22\x68\x23\x13\xd1\x98\xb1\xfa\x33\xfc\x72\x95\x38\x13\x54\x85\x87\x58\xae\x6c\x8e\xc6\xfa\xc3\x24\x5c\x6e\x45\x4d\x16\xfa\x2f\x51\xc4\x16\x6f\xab\x51\xdf\x27\x28\x58\xf2\xd6\x03\x77\x0c\x40\x98\x7f\x64\x44\x2d\x48\x7a\xf4\x9c\xd5\xc3\x99\x1c\xe8\x58\xea\x2a\x60\xda\xb6\xa6\x5a\x34\x41\x49\x65\x93\x39\x73\xac\x24\x57\x08\x9e\x35\x91\x60\xb7\xcd\xed\xc4\x2f\x29\xe1\x0a\x91\x92\x17\x85\xf6\xb7\x22\x4e\xe0\xb3\x49\x39\x3c\xdc\xff\x61\x51\xb5\x0b\x37\x7d\x60\x95\x59\x92\x3d\x09\x84\xcd\xa6\x00\x08\x29\xb9\x16\xab\x68\x96\x69\x3e\xf6\xa2\x19\x9b\x3c\x22\xf7\xdc\x55\x00\xa1\x5b\x82\x58\x42\x0e\x31\x4c\x22\x2b\xc0\x00\xbc\x4e\x54\x13\xe6\xdd\x82\xc9\x93\xf8\x33\x0f\x5c\x6d\x1b\xe4\xbc\x79\xf0\x8a\x1a\x0a\x46",
+       "\x9c\x77\x9d\x98\x1f\x9b\x7e\x49\x1f\xf8\x68\xbe\x22\xb3\x7f\xa9\xdf\x72\xde\x55\x67\x2a\x02\x26\xa8\x21\xb2\x9c\x04\x5d\xf4\xff\x78\x8f\xa7\x27\x1d\x55\x7e\xf6\x02\x5e\xea\x25\x58\x09\xf2\x41",
+       203 },
+      { GCRY_MD_SHA3_384,
+       "\x44\x99\xef\xff\xac\x4b\xce\xa5\x27\x47\xef\xd1\xe4\xf2\x0b\x73\xe4\x87\x58\xbe\x91\x5c\x88\xa1\xff\xe5\x29\x9b\x0b\x00\x58\x37\xa4\x6b\x2f\x20\xa9\xcb\x3c\x6e\x64\xa9\xe3\xc5\x64\xa2\x7c\x0f\x1c\x6a\xd1\x96\x03\x73\x03\x6e\xc5\xbf\xe1\xa8\xfc\x6a\x43\x5c\x21\x85\xed\x0f\x11\x4c\x50\xe8\xb3\xe4\xc7\xed\x96\xb0\x6a\x03\x68\x19\xc9\x46\x3e\x86\x4a\x58\xd6\x28\x6f\x78\x5e\x32\xa8\x04\x44\x3a\x56\xaf\x0b\x4d\xf6\xab\xc5\x7e\xd5\xc2\xb1\x85\xdd\xee\x84\x89\xea\x08\x0d\xee\xee\x66\xaa\x33\xc2\xe6\xda\xb3\x62\x51\xc4\x02\x68\x2b\x68\x24\x82\x1f\x99\x8c\x32\x16\x31\x64\x29\x8e\x1f\xaf\xd3\x1b\xab\xbc\xff\xb5\x94\xc9\x18\x88\xc6\x21\x90\x79\xd9\x07\xfd\xb4\x38\xed\x89\x52\x9d\x6d\x96\x21\x2f\xd5\x5a\xbe\x20\x39\x9d\xbe\xfd\x34\x22\x48\x50\x74\x36\x93\x1c\xde\xad\x49\x6e\xb6\xe4\xa8\x03\x58\xac\xc7\x86\x47\xd0\x43",
+       "\x2c\x0b\xc5\x4a\x67\xb0\x0a\xd7\x03\xfc\x59\x57\x51\x07\x4c\x4e\x44\x7e\xfd\xe0\x0c\xaa\xf8\xc8\xfc\xad\xf5\x76\x8c\x33\x0b\x6c\x7f\x19\x18\xf0\x44\xf5\xc5\xc5\x58\x10\xd0\x78\x53\x4a\x7b\xb3",
+       204 },
+      { GCRY_MD_SHA3_384,
+       "\xee\xcb\xb8\xfd\xfa\x4d\xa6\x21\x70\xfd\x06\x72\x7f\x69\x7d\x81\xf8\x3f\x60\x1f\xf6\x1e\x47\x81\x05\xd3\xcb\x75\x02\xf2\xc8\x9b\xf3\xe8\xf5\x6e\xdd\x46\x9d\x04\x98\x07\xa3\x88\x82\xa7\xee\xfb\xc8\x5f\xc9\xa9\x50\x95\x2e\x9f\xa8\x4b\x8a\xfe\xbd\x3c\xe7\x82\xd4\xda\x59\x80\x02\x82\x7b\x1e\xb9\x88\x82\xea\x1f\x0a\x8f\x7a\xa9\xce\x01\x3a\x6e\x9b\xc4\x62\xfb\x66\xc8\xd4\xa1\x8d\xa2\x14\x01\xe1\xb9\x33\x56\xeb\x12\xf3\x72\x5b\x6d\xb1\x68\x4f\x23\x00\xa9\x8b\x9a\x11\x9e\x5d\x27\xff\x70\x4a\xff\xb6\x18\xe1\x27\x08\xe7\x7e\x6e\x5f\x34\x13\x9a\x5a\x41\x13\x1f\xd1\xd6\x33\x6c\x27\x2a\x8f\xc3\x70\x80\xf0\x41\xc7\x13\x41\xbe\xe6\xab\x55\x0c\xb4\xa2\x0a\x6d\xdb\x6a\x8e\x02\x99\xf2\xb1\x4b\xc7\x30\xc5\x4b\x8b\x1c\x1c\x48\x7b\x49\x4b\xdc\xcf\xd3\xa5\x35\x35\xab\x2f\x23\x15\x90\xbf\x2c\x40\x62\xfd\x2a\xd5\x8f\x90\x6a\x2d\x0d",
+       "\x2d\xb1\x9c\xa5\x57\x72\x3c\xd3\xc1\x7e\x7d\x81\x40\xca\x30\x1a\x5a\x2c\xb7\x7e\x3f\x1f\x59\x5f\x5b\x85\x0a\x78\x94\x3c\x7f\x36\xfc\x37\x05\x6d\xcf\x2b\xad\xb9\x0d\xda\x77\xbf\xa9\x69\xc0\xaa",
+       205 },
+      { GCRY_MD_SHA3_384,
+       "\xe6\x4f\x3e\x4a\xce\x5c\x84\x18\xd6\x5f\xec\x2b\xc5\xd2\xa3\x03\xdd\x45\x80\x34\x73\x6e\x3b\x0d\xf7\x19\x09\x8b\xe7\xa2\x06\xde\xaf\x52\xd6\xba\x82\x31\x6c\xaf\x33\x0e\xf8\x52\x37\x51\x88\xcd\xe2\xb3\x9c\xc9\x4a\xa4\x49\x57\x8a\x7e\x2a\x8e\x3f\x5a\x9d\x68\xe8\x16\xb8\xd1\x68\x89\xfb\xc0\xeb\xf0\x93\x9d\x04\xf6\x30\x33\xae\x9a\xe2\xbd\xab\x73\xb8\x8c\x26\xd6\xbd\x25\xee\x46\x0e\xe1\xef\x58\xfb\x0a\xfa\x92\xcc\x53\x9f\x8c\x76\xd3\xd0\x97\xe7\xa6\xa6\x3e\xbb\x9b\x58\x87\xed\xf3\xcf\x07\x60\x28\xc5\xbb\xd5\xb9\xdb\x32\x11\x37\x1a\xd3\xfe\x12\x1d\x4e\x9b\xf4\x42\x29\xf4\xe1\xec\xf5\xa0\xf9\xf0\xeb\xa4\xd5\xce\xb7\x28\x78\xab\x22\xc3\xf0\xeb\x5a\x62\x53\x23\xac\x66\xf7\x06\x1f\x4a\x81\xfa\xc8\x34\x47\x1e\x0c\x59\x55\x3f\x10\x84\x75\xfe\x29\x0d\x43\xe6\xa0\x55\xae\x3e\xe4\x6f\xb6\x74\x22\xf8\x14\xa6\x8c\x4b\xe3\xe8\xc9",
+       "\x71\xe5\xdd\x07\x55\xcf\x8b\x82\xbc\x79\xae\xd6\xfb\x61\xc9\xe4\xff\x83\x61\xc9\xaf\xc5\xad\x98\x08\x08\xa8\xbc\x48\x0e\x09\xd5\x9b\x23\x40\x74\x47\x28\x51\x08\x07\x14\xe0\x27\x5c\xe7\x2d\xc5",
+       206 },
+      { GCRY_MD_SHA3_384,
+       "\xd2\xcb\x2d\x73\x30\x33\xf9\xe9\x13\x95\x31\x28\x08\x38\x3c\xc4\xf0\xca\x97\x4e\x87\xec\x68\x40\x0d\x52\xe9\x6b\x3f\xa6\x98\x4a\xc5\x8d\x9a\xd0\x93\x8d\xde\x5a\x97\x30\x08\xd8\x18\xc4\x96\x07\xd9\xde\x22\x84\xe7\x61\x8f\x1b\x8a\xed\x83\x72\xfb\xd5\x2e\xd5\x45\x57\xaf\x42\x20\xfa\xc0\x9d\xfa\x84\x43\x01\x16\x99\xb9\x7d\x74\x3f\x8f\x2b\x1a\xef\x35\x37\xeb\xb4\x5d\xcc\x9e\x13\xdf\xb4\x38\x42\x8e\xe1\x90\xa4\xef\xdb\x3c\xae\xb7\xf3\x93\x31\x17\xbf\x63\xab\xdc\x7e\x57\xbe\xb4\x17\x1c\x7e\x1a\xd2\x60\xab\x05\x87\x80\x6c\x4d\x13\x7b\x63\x16\xb5\x0a\xbc\x9c\xce\x0d\xff\x3a\xca\xda\x47\xbb\xb8\x6b\xe7\x77\xe6\x17\xbb\xe5\x78\xff\x45\x19\x84\x4d\xb3\x60\xe0\xa9\x6c\x67\x01\x29\x0e\x76\xbb\x95\xd2\x6f\x0f\x80\x4c\x8a\x4f\x27\x17\xea\xc4\xe7\xde\x9f\x2c\xff\x3b\xbc\x55\xa1\x7e\x77\x6c\x0d\x02\x85\x60\x32\xa6\xcd\x10\xad\x28\x38",
+       "\x51\xf9\x51\xb8\xf1\x01\x3b\xa9\xbc\xed\x90\x47\x8e\x24\x8c\xd8\x9d\x4d\xeb\xc6\xa1\x9c\xeb\x6e\xf8\x1b\xa1\xa5\xd8\xd3\x33\x9d\x42\x6d\x50\xa9\x4c\x7c\xe3\xd1\x43\xc4\x5d\xec\xce\xf9\x49\x65",
+       207 },
+      { GCRY_MD_SHA3_384,
+       "\xf2\x99\x89\x55\x61\x3d\xd4\x14\xcc\x11\x1d\xf5\xce\x30\xa9\x95\xbb\x79\x2e\x26\x0b\x0e\x37\xa5\xb1\xd9\x42\xfe\x90\x17\x1a\x4a\xc2\xf6\x6d\x49\x28\xd7\xad\x37\x7f\x4d\x05\x54\xcb\xf4\xc5\x23\xd2\x1f\x6e\x5f\x37\x9d\x6f\x4b\x02\x8c\xdc\xb9\xb1\x75\x8d\x3b\x39\x66\x32\x42\xff\x3c\xb6\xed\xe6\xa3\x6a\x6f\x05\xdb\x3b\xc4\x1e\x0d\x86\x1b\x38\x4b\x6d\xec\x58\xbb\x09\x6d\x0a\x42\x2f\xd5\x42\xdf\x17\x5e\x1b\xe1\x57\x1f\xb5\x2a\xe6\x6f\x2d\x86\xa2\xf6\x82\x4a\x8c\xfa\xac\xba\xc4\xa7\x49\x2a\xd0\x43\x3e\xeb\x15\x45\x4a\xf8\xf3\x12\xb3\xb2\xa5\x77\x75\x0e\x3e\xfb\xd3\x70\xe8\xa8\xca\xc1\x58\x25\x81\x97\x1f\xba\x3b\xa4\xbd\x0d\x76\xe7\x18\xda\xcf\x84\x33\xd3\x3a\x59\xd2\x87\xf8\xcc\x92\x23\x4e\x7a\x27\x10\x41\xb5\x26\xe3\x89\xef\xb0\xe4\x0b\x6a\x18\xb3\xaa\xf6\x58\xe8\x2e\xd1\xc7\x86\x31\xfd\x23\xb4\xc3\xeb\x27\xc3\xfa\xec\x86\x85",
+       "\x21\x0e\xbc\x15\x56\xe3\x1a\x27\xea\xf6\x0a\x5f\xe3\xe1\x81\x13\x5c\x5e\xa1\x17\xe3\xff\x21\xaf\x2d\x04\xbe\xab\x9a\x24\x3f\xff\xf6\x32\xe3\xd7\x77\x8f\x9a\x6d\x03\x04\xc1\xac\xf3\x65\x9a\x3c",
+       208 },
+      { GCRY_MD_SHA3_384,
+       "\x44\x77\x97\xe2\x89\x9b\x72\xa3\x56\xba\x55\xbf\x4d\xf3\xac\xca\x6c\xdb\x10\x41\xeb\x47\x7b\xd1\x83\x4a\x9f\x9a\xcb\xc3\x40\xa2\x94\xd7\x29\xf2\xf9\x7d\xf3\xa6\x10\xbe\x0f\xf1\x5e\xdb\x9c\x6d\x5d\xb4\x16\x44\xb9\x87\x43\x60\x14\x0f\xc6\x4f\x52\xaa\x03\xf0\x28\x6c\x8a\x64\x06\x70\x06\x7a\x84\xe0\x17\x92\x6a\x70\x43\x8d\xb1\xbb\x36\x1d\xef\xee\x73\x17\x02\x14\x25\xf8\x82\x1d\xef\x26\xd1\xef\xd7\x7f\xc8\x53\xb8\x18\x54\x5d\x05\x5a\xdc\x92\x84\x79\x6e\x58\x3c\x76\xe6\xfe\x74\xc9\xac\x25\x87\xaa\x46\xaa\x8f\x88\x04\xf2\xfe\xb5\x83\x6c\xc4\xb3\xab\xab\xab\x84\x29\xa5\x78\x3e\x17\xd5\x99\x9f\x32\x24\x2e\xb5\x9e\xf3\x0c\xd7\xad\xab\xc1\x6d\x72\xdb\xdb\x09\x76\x23\x04\x7c\x98\x98\x9f\x88\xd1\x4e\xaf\x02\xa7\x21\x2b\xe1\x6e\xc2\xd0\x79\x81\xaa\xa9\x99\x49\xdd\xf8\x9e\xcd\x90\x33\x3a\x77\xbc\x4e\x19\x88\xa8\x2a\xbf\x7c\x7c\xaf\x32\x91",
+       "\xf5\xf6\x59\xf6\x99\x9b\xad\x8c\xdc\x77\xc4\x29\x01\xa8\xd6\x4c\x1f\xa8\x27\xf7\x84\x89\x85\x13\x61\x40\xbf\x5d\x4b\x3b\xbb\x3d\x96\x4d\x2d\x81\x56\xf9\xfd\x02\xb6\xd3\x82\xbc\x84\x10\xa8\x8e",
+       209 },
+      { GCRY_MD_SHA3_384,
+       "\x9f\x2c\x18\xad\xe9\xb3\x80\xc7\x84\xe1\x70\xfb\x76\x3e\x9a\xa2\x05\xf6\x43\x03\x06\x7e\xb1\xbc\xea\x93\xdf\x5d\xac\x4b\xf5\xa2\xe0\x0b\x78\x19\x5f\x80\x8d\xf2\x4f\xc7\x6e\x26\xcb\x7b\xe3\x1d\xc3\x5f\x08\x44\xcd\xed\x15\x67\xbb\xa2\x98\x58\xcf\xfc\x97\xfb\x29\x01\x03\x31\xb0\x1d\x6a\x3f\xb3\x15\x9c\xc1\xb9\x73\xd2\x55\xda\x98\x43\xe3\x4a\x0a\x40\x61\xca\xbd\xb9\xed\x37\xf2\x41\xbf\xab\xb3\xc2\x0d\x32\x74\x3f\x40\x26\xb5\x9a\x4c\xcc\x38\x5a\x23\x01\xf8\x3c\x0b\x0a\x19\x0b\x0f\x2d\x01\xac\xb8\xf0\xd4\x11\x11\xe1\x0f\x2f\x4e\x14\x93\x79\x27\x55\x99\xa5\x2d\xc0\x89\xb3\x5f\xdd\x52\x34\xb0\xcf\xb7\xb6\xd8\xae\xbd\x56\x3c\xa1\xfa\x65\x3c\x5c\x02\x1d\xfd\x6f\x59\x20\xe6\xf1\x8b\xfa\xfd\xbe\xcb\xf0\xab\x00\x28\x13\x33\xed\x50\xb9\xa9\x99\x54\x9c\x1c\x8f\x8c\x63\xd7\x62\x6c\x48\x32\x2e\x97\x91\xd5\xff\x72\x29\x40\x49\xbd\xe9\x1e\x73\xf8",
+       "\xb1\x51\xbf\x98\xc5\x2f\x63\xf2\x94\xa4\xb1\xe9\x90\xc8\x6c\xb7\x3c\x4b\xdd\x47\x6b\x25\xc1\x38\xca\x66\xb2\xba\x08\x44\x75\x40\xb0\xa7\x87\xdf\xdd\xaa\x3d\x38\xaf\x44\xca\x8e\xbb\xed\x74\xd8",
+       210 },
+      { GCRY_MD_SHA3_384,
+       "\xae\x15\x9f\x3f\xa3\x36\x19\x00\x2a\xe6\xbc\xce\x8c\xbb\xdd\x7d\x28\xe5\xed\x9d\x61\x53\x45\x95\xc4\xc9\xf4\x3c\x40\x2a\x9b\xb3\x1f\x3b\x30\x1c\xbf\xd4\xa4\x3c\xe4\xc2\x4c\xd5\xc9\x84\x9c\xc6\x25\x9e\xca\x90\xe2\xa7\x9e\x01\xff\xba\xc0\x7b\xa0\xe1\x47\xfa\x42\x67\x6a\x1d\x66\x85\x70\xe0\x39\x63\x87\xb5\xbc\xd5\x99\xe8\xe6\x6a\xae\xd1\xb8\xa1\x91\xc5\xa4\x75\x47\xf6\x13\x73\x02\x1f\xa6\xde\xad\xcb\x55\x36\x3d\x23\x3c\x24\x44\x0f\x2c\x73\xdb\xb5\x19\xf7\xc9\xfa\x5a\x89\x62\xef\xd5\xf6\x25\x2c\x04\x07\xf1\x90\xdf\xef\xad\x70\x7f\x3c\x70\x07\xd6\x9f\xf3\x6b\x84\x89\xa5\xb6\xb7\xc5\x57\xe7\x9d\xd4\xf5\x0c\x06\x51\x1f\x59\x9f\x56\xc8\x96\xb3\x5c\x91\x7b\x63\xba\x35\xc6\xff\x80\x92\xba\xf7\xd1\x65\x8e\x77\xfc\x95\xd8\xa6\xa4\x3e\xeb\x4c\x01\xf3\x3f\x03\x87\x7f\x92\x77\x4b\xe8\x9c\x11\x14\xdd\x53\x1c\x01\x1e\x53\xa3\x4d\xc2\x48\xa2\xf0\xe6",
+       "\x47\xd7\x4f\xdd\x9a\x19\xa5\x38\x93\x13\x61\x06\x43\xfa\x85\x9f\xf0\xbd\x7b\x58\x3b\x09\x9f\xdd\xb9\xc9\x80\xdc\xc0\x00\xaf\xeb\x63\x9d\xd9\x90\x71\xea\x31\x97\x6d\xa3\x5b\x7b\xc9\x49\xbd\x4e",
+       211 },
+      { GCRY_MD_SHA3_384,
+       "\x3b\x8e\x97\xc5\xff\xc2\xd6\xa4\x0f\xa7\xde\x7f\xce\xfc\x90\xf3\xb1\x2c\x94\x0e\x7a\xb4\x15\x32\x1e\x29\xee\x69\x2d\xfa\xc7\x99\xb0\x09\xc9\x9d\xcd\xdb\x70\x8f\xce\x5a\x17\x8c\x5c\x35\xee\x2b\x86\x17\x14\x3e\xdc\x4c\x40\xb4\xd3\x13\x66\x1f\x49\xab\xdd\x93\xce\xa7\x9d\x11\x75\x18\x80\x54\x96\xfe\x6a\xcf\x29\x2c\x4c\x2a\x1f\x76\xb4\x03\xa9\x7d\x7c\x39\x9d\xaf\x85\xb4\x6a\xd8\x4e\x16\x24\x6c\x67\xd6\x83\x67\x57\xbd\xe3\x36\xc2\x90\xd5\xd4\x01\xe6\xc1\x38\x6a\xb3\x27\x97\xaf\x6b\xb2\x51\xe9\xb2\xd8\xfe\x75\x4c\x47\x48\x2b\x72\xe0\xb3\x94\xea\xb7\x69\x16\x12\x6f\xd6\x8e\xa7\xd6\x5e\xb9\x3d\x59\xf5\xb4\xc5\xac\x40\xf7\xc3\xb3\x7e\x7f\x36\x94\xf2\x94\x24\xc2\x4a\xf8\xc8\xf0\xef\x59\xcd\x9d\xbf\x1d\x28\xe0\xe1\x0f\x79\x9a\x6f\x78\xca\xd1\xd4\x5b\x9d\xb3\xd7\xde\xe4\xa7\x05\x9a\xbe\x99\x18\x27\x14\x98\x3b\x9c\x9d\x44\xd7\xf5\x64\x35\x96\xd4\xf3",
+       "\x9b\x80\x91\x98\xdc\xce\x24\x17\x5e\x33\x09\x83\x31\xd3\xa4\x02\xa8\x21\xae\x93\x26\xe7\x27\x75\xaa\xe3\x4d\x1a\x9b\xb5\x3d\x2b\x57\x86\x39\x05\xcf\xd6\x05\x43\xbb\xc4\x2b\x45\x40\x07\xc3\x15",
+       212 },
+      { GCRY_MD_SHA3_384,
+       "\x34\x34\xec\x31\xb1\x0f\xaf\xdb\xfe\xec\x0d\xd6\xbd\x94\xe8\x0f\x7b\xa9\xdc\xa1\x9e\xf0\x75\xf7\xeb\x01\x75\x12\xaf\x66\xd6\xa4\xbc\xf7\xd1\x6b\xa0\x81\x9a\x18\x92\xa6\x37\x2f\x9b\x35\xbc\xc7\xca\x81\x55\xee\x19\xe8\x42\x8b\xc2\x2d\x21\x48\x56\xed\x5f\xa9\x37\x4c\x3c\x09\xbd\xe1\x69\x60\x2c\xc2\x19\x67\x9f\x65\xa1\x56\x6f\xc7\x31\x6f\x4c\xc3\xb6\x31\xa1\x8f\xb4\x44\x9f\xa6\xaf\xa1\x6a\x3d\xb2\xbc\x42\x12\xef\xf5\x39\xc6\x7c\xf1\x84\x68\x08\x26\x53\x55\x89\xc7\x11\x1d\x73\xbf\xfc\xe4\x31\xb4\xc4\x04\x92\xe7\x63\xd9\x27\x95\x60\xaa\xa3\x8e\xb2\xdc\x14\xa2\x12\xd7\x23\xf9\x94\xa1\xfe\x65\x6f\xf4\xdd\x14\x55\x1c\xe4\xe7\xc6\x21\xb2\xaa\x56\x04\xa1\x00\x01\xb2\x87\x8a\x89\x7a\x28\xa0\x80\x95\xc3\x25\xe1\x0a\x26\xd2\xfb\x1a\x75\xbf\xd6\x4c\x25\x03\x09\xbb\x55\xa4\x4f\x23\xbb\xac\x0d\x55\x16\xa1\xc6\x87\xd3\xb4\x1e\xf2\xfb\xbf\x9c\xc5\x6d\x47\x39",
+       "\x93\xc9\x83\x45\x01\xfc\x72\x85\x08\xa1\x5e\xb9\x20\x5e\x67\x89\x83\xf3\xbd\xb0\xba\x44\x7e\xe7\x39\xae\x50\x82\xdb\x37\xf2\xf2\xd4\x85\x08\x81\x30\xe0\xb1\xcb\xf0\x03\x9d\x18\xbd\xf4\x29\xf7",
+       213 },
+      { GCRY_MD_SHA3_384,
+       "\x7c\x79\x53\xd8\x1c\x8d\x20\x8f\xd1\xc9\x76\x81\xd4\x8f\x49\xdd\x00\x34\x56\xde\x60\x47\x5b\x84\x07\x0e\xf4\x84\x7c\x33\x3b\x74\x57\x5b\x1f\xc8\xd2\xa1\x86\x96\x44\x85\xa3\xb8\x63\x4f\xea\xa3\x59\x5a\xaa\x1a\x2f\x45\x95\xa7\xd6\xb6\x15\x35\x63\xde\xe3\x1b\xba\xc4\x43\xc8\xa3\x3e\xed\x6d\x5d\x95\x6a\x98\x0a\x68\x36\x6c\x25\x27\xb5\x50\xee\x95\x02\x50\xdf\xb6\x91\xea\xcb\xd5\xd5\x6a\xe1\x4b\x97\x06\x68\xbe\x17\x4c\x89\xdf\x2f\xea\x43\xae\x52\xf1\x31\x42\x63\x9c\x88\x4f\xd6\x2a\x36\x83\xc0\xc3\x79\x2f\x0f\x24\xab\x13\x18\xbc\xb2\x7e\x21\xf4\x73\x7f\xab\x62\xc7\x7e\xa3\x8b\xc8\xfd\x1c\xf4\x1f\x7d\xab\x64\xc1\x3f\xeb\xe7\x15\x2b\xf5\xbb\x7a\xb5\xa7\x8f\x53\x46\xd4\x3c\xc7\x41\xcb\x6f\x72\xb7\xb8\x98\x0f\x26\x8b\x68\xbf\x62\xab\xdf\xb1\x57\x7a\x52\x43\x8f\xe1\x4b\x59\x14\x98\xcc\x95\xf0\x71\x22\x84\x60\xc7\xc5\xd5\xce\xb4\xa7\xbd\xe5\x88\xe7\xf2\x1c",
+       "\xc0\xad\x8c\x3e\x7e\xa5\x95\x10\x4d\x4b\xc0\xa0\x8d\xcb\xc8\x50\x42\xed\x50\xdd\x8d\x9b\x01\xab\x47\xc9\xf0\x66\xf9\x1a\xd3\xbf\xfe\xde\x41\x07\xf1\xeb\x1f\x5b\x61\xca\x7d\x40\x91\xd6\x83\x27",
+       214 },
+      { GCRY_MD_SHA3_384,
+       "\x7a\x6a\x4f\x4f\xdc\x59\xa1\xd2\x23\x38\x1a\xe5\xaf\x49\x8d\x74\xb7\x25\x2e\xcf\x59\xe3\x89\xe4\x91\x30\xc7\xea\xee\x62\x6e\x7b\xd9\x89\x7e\xff\xd9\x20\x17\xf4\xcc\xde\x66\xb0\x44\x04\x62\xcd\xed\xfd\x35\x2d\x81\x53\xe6\xa4\xc8\xd7\xa0\x81\x2f\x70\x1c\xc7\x37\xb5\x17\x8c\x25\x56\xf0\x71\x11\x20\x0e\xb6\x27\xdb\xc2\x99\xca\xa7\x92\xdf\xa5\x8f\x35\x93\x52\x99\xfa\x3a\x35\x19\xe9\xb0\x31\x66\xdf\xfa\x15\x91\x03\xff\xa3\x5e\x85\x77\xf7\xc0\xa8\x6c\x6b\x46\xfe\x13\xdb\x8e\x2c\xdd\x9d\xcf\xba\x85\xbd\xdd\xcc\xe0\xa7\xa8\xe1\x55\xf8\x1f\x71\x2d\x8e\x9f\xe6\x46\x15\x3d\x3d\x22\xc8\x11\xbd\x39\xf8\x30\x43\x3b\x22\x13\xdd\x46\x30\x19\x41\xb5\x92\x93\xfd\x0a\x33\xe2\xb6\x3a\xdb\xd9\x52\x39\xbc\x01\x31\x5c\x46\xfd\xb6\x78\x87\x5b\x3c\x81\xe0\x53\xa4\x0f\x58\x1c\xfb\xec\x24\xa1\x40\x4b\x16\x71\xa1\xb8\x8a\x6d\x06\x12\x02\x29\x51\x8f\xb1\x3a\x74\xca\x0a\xc5\xae",
+       "\xaa\x8d\xaa\x02\xab\xcb\xc5\xa4\xb3\x00\x3b\xff\x5c\xbc\x2c\x84\x59\x4c\x5a\x0f\x84\xbd\x44\x9a\x1a\x56\xbe\x59\x56\x6e\x13\xec\x68\x03\x01\x0d\x42\x2a\x4c\x24\x4b\x99\x81\x2f\x45\x37\xc9\x3d",
+       215 },
+      { GCRY_MD_SHA3_384,
+       "\xd9\xfa\xa1\x4c\xeb\xe9\xb7\xde\x55\x1b\x6c\x07\x65\x40\x9a\x33\x93\x85\x62\x01\x3b\x5e\x8e\x0e\x1e\x0a\x64\x18\xdf\x73\x99\xd0\xa6\xa7\x71\xfb\x81\xc3\xca\x9b\xd3\xbb\x8e\x29\x51\xb0\xbc\x79\x25\x25\xa2\x94\xeb\xd1\x08\x36\x88\x80\x6f\xe5\xe7\xf1\xe1\x7f\xd4\xe3\xa4\x1d\x00\xc8\x9e\x8f\xcf\x4a\x36\x3c\xae\xdb\x1a\xcb\x55\x8e\x3d\x56\x2f\x13\x02\xb3\xd8\x3b\xb8\x86\xed\x27\xb7\x60\x33\x79\x81\x31\xda\xb0\x5b\x42\x17\x38\x1e\xaa\xa7\xba\x15\xec\x82\x0b\xb5\xc1\x3b\x51\x6d\xd6\x40\xea\xec\x5a\x27\xd0\x5f\xdf\xca\x0f\x35\xb3\xa5\x31\x21\x46\x80\x6b\x4c\x02\x75\xbc\xd0\xaa\xa3\xb2\x01\x7f\x34\x69\x75\xdb\x56\x6f\x9b\x4d\x13\x7f\x4e\xe1\x06\x44\xc2\xa2\xda\x66\xde\xec\xa5\x34\x2e\x23\x64\x95\xc3\xc6\x28\x05\x28\xbf\xd3\x2e\x90\xaf\x4c\xd9\xbb\x90\x8f\x34\x01\x2b\x52\xb4\xbc\x56\xd4\x8c\xc8\xa6\xb5\x9b\xab\x01\x49\x88\xea\xbd\x12\xe1\xa0\xa1\xc2\xe1\x70\xe7",
+       "\xca\xeb\x4f\x82\x9a\x92\x56\x79\x41\x6f\x7c\xb1\x77\xed\x4c\x99\x72\x1b\x85\x1a\xb5\x9d\x52\x97\x9b\xfe\xc6\xd2\xaa\xa1\xe6\x02\xf4\x31\x0b\x15\x62\x4f\x9d\x7b\xf2\xd3\x51\xdb\x73\xbf\xb5\xea",
+       216 },
+      { GCRY_MD_SHA3_384,
+       "\x2d\x84\x27\x43\x3d\x0c\x61\xf2\xd9\x6c\xfe\x80\xcf\x1e\x93\x22\x65\xa1\x91\x36\x5c\x3b\x61\xaa\xa3\xd6\xdc\xc0\x39\xf6\xba\x2a\xd5\x2a\x6a\x8c\xc3\x0f\xc1\x0f\x70\x5e\x6b\x77\x05\x10\x59\x77\xfa\x49\x6c\x1c\x70\x8a\x27\x7a\x12\x43\x04\xf1\xfc\x40\x91\x1e\x74\x41\xd1\xb5\xe7\x7b\x95\x1a\xad\x7b\x01\xfd\x5d\xb1\xb3\x77\xd1\x65\xb0\x5b\xbf\x89\x80\x42\xe3\x96\x60\xca\xf8\xb2\x79\xfe\x52\x29\xd1\xa8\xdb\x86\xc0\x99\x9e\xd6\x5e\x53\xd0\x1c\xcb\xc4\xb4\x31\x73\xcc\xf9\x92\xb3\xa1\x45\x86\xf6\xba\x42\xf5\xfe\x30\xaf\xa8\xae\x40\xc5\xdf\x29\x96\x6f\x93\x46\xda\x5f\x8b\x35\xf1\x6a\x1d\xe3\xab\x6d\xe0\xf4\x77\xd8\xd8\x66\x09\x18\x06\x0e\x88\xb9\xb9\xe9\xca\x6a\x42\x07\x03\x3b\x87\xa8\x12\xdb\xf5\x54\x4d\x39\xe4\x88\x20\x10\xf8\x2b\x6c\xe0\x05\xf8\xe8\xff\x6f\xe3\xc3\x80\x6b\xc2\xb7\x3c\x2b\x83\xaf\xb7\x04\x34\x56\x29\x30\x4f\x9f\x86\x35\x87\x12\xe9\xfa\xe3\xca\x3e",
+       "\xfc\x1f\xc7\xf1\x9f\x6c\x9d\x0a\xd1\x46\x2b\x24\xc1\x21\xc8\x9b\x01\xb4\xe0\x83\xed\xad\x02\xa8\xdb\xde\xb9\x90\xd9\x8c\xaf\xe0\xaf\xe0\x1e\x2e\xba\x64\x68\x72\xcd\x81\x6b\x52\x03\xee\x8a\x87",
+       217 },
+      { GCRY_MD_SHA3_384,
+       "\x5e\x19\xd9\x78\x87\xfc\xaa\xc0\x38\x7e\x22\xc6\xf8\x03\xc3\x4a\x3d\xac\xd2\x60\x41\x72\x43\x3f\x7a\x8a\x7a\x52\x6c\xa4\xa2\xa1\x27\x1e\xcf\xc5\xd5\xd7\xbe\x5a\xc0\xd8\x5d\x92\x10\x95\x35\x0d\xfc\x65\x99\x7d\x44\x3c\x21\xc8\x09\x4e\x0a\x3f\xef\xd2\x96\x1b\xcb\x94\xae\xd0\x32\x91\xae\x31\x0c\xcd\xa7\x5d\x8a\xce\x4b\xc7\xd8\x9e\x7d\x3e\x5d\x16\x50\xbd\xa5\xd6\x68\xb8\xb5\x0b\xfc\x8e\x60\x8e\x18\x4f\x4d\x3a\x9a\x2b\xad\xc4\xff\x5f\x07\xe0\xc0\xbc\x8a\x9f\x2e\x0b\x2a\x26\xfd\x6d\x8c\x55\x00\x08\xfa\xaa\xb7\x5f\xd7\x1a\xf2\xa4\x24\xbe\xc9\xa7\xcd\x9d\x83\xfa\xd4\xc8\xe9\x31\x91\x15\x65\x6a\x87\x17\xd3\xb5\x23\xa6\x8f\xf8\x00\x42\x58\xb9\x99\x0e\xd3\x62\x30\x84\x61\x80\x4b\xa3\xe3\xa7\xe9\x2d\x8f\x2f\xfa\xe5\xc2\xfb\xa5\x5b\xa5\xa3\xc2\x7c\x0a\x2f\x71\xbd\x71\x1d\x2f\xe1\x79\x9c\x2a\xdb\x31\xb2\x00\x03\x54\x81\xe9\xee\x5c\x4a\xdf\x2a\xb9\xc0\xfa\x50\xb2\x39\x75\xcf",
+       "\x84\x80\x3e\x50\xde\xc9\x01\xff\x93\x0c\x8a\x76\xeb\xc1\xf9\x8e\xc7\x28\x74\xde\xef\x0d\x24\x90\x20\xb1\xdb\xeb\x4e\xa7\xd8\xc7\xda\x47\x61\xed\xe0\x77\x15\x84\x60\xe0\x54\xa7\xf7\x1d\x19\x94",
+       218 },
+      { GCRY_MD_SHA3_384,
+       "\xc8\xe9\x76\xab\x46\x38\x90\x93\x87\xce\x3b\x8d\x4e\x51\x0c\x32\x30\xe5\x69\x0e\x02\xc4\x50\x93\xb1\xd2\x97\x91\x0a\xbc\x48\x1e\x56\xee\xa0\xf2\x96\xf9\x83\x79\xdf\xc9\x08\x0a\xf6\x9e\x73\xb2\x39\x9d\x1c\x14\x3b\xee\x80\xae\x13\x28\x16\x2c\xe1\xba\x7f\x6a\x83\x74\x67\x9b\x20\xaa\xcd\x38\x0e\xb4\xe6\x13\x82\xc9\x99\x98\x70\x4d\x62\x70\x1a\xfa\x91\x4f\x9a\x27\x05\xcd\xb0\x65\x88\x5f\x50\xd0\x86\xc3\xeb\x57\x53\x70\x0c\x38\x71\x18\xbb\x14\x2f\x3e\x6d\xa1\xe9\x88\xdf\xb3\x1a\xc7\x5d\x73\x68\x93\x1e\x45\xd1\x39\x1a\x27\x4b\x22\xf8\x3c\xeb\x07\x2f\x9b\xca\xbc\x0b\x21\x66\x85\xbf\xd7\x89\xf5\x02\x39\x71\x02\x4b\x18\x78\xa2\x05\x44\x25\x22\xf9\xea\x7d\x87\x97\xa4\x10\x2a\x3d\xf4\x17\x03\x76\x82\x51\xfd\x5e\x01\x7c\x85\xd1\x20\x0a\x46\x41\x18\xaa\x35\x65\x4e\x7c\xa3\x9f\x3c\x37\x5b\x8e\xf8\xcb\xe7\x53\x4d\xbc\x64\xbc\x20\xbe\xfb\x41\x7c\xf6\x0e\xc9\x2f\x63\xd9\xee\x73\x97",
+       "\x05\x58\x6b\xcb\x80\x77\xe1\x9f\x3f\x43\x01\x52\x16\xd6\x23\xb1\x43\x9c\x49\xec\xdd\x3c\x53\x25\x55\x53\xe9\x13\x3f\xd1\xa9\x00\x88\x91\x52\x0d\x2e\xeb\xe5\x68\x4c\x54\x60\x28\xca\x2c\xdd\xfe",
+       219 },
+      { GCRY_MD_SHA3_384,
+       "\x71\x45\xfa\x12\x4b\x74\x29\xa1\xfc\x22\x31\x23\x7a\x94\x9b\xa7\x20\x1b\xcc\x18\x22\xd3\x27\x2d\xe0\x05\xb6\x82\x39\x81\x96\xc2\x5f\x7e\x5c\xc2\xf2\x89\xfb\xf4\x44\x15\xf6\x99\xcb\x7f\xe6\x75\x77\x91\xb1\x44\x34\x10\x23\x4a\xe0\x61\xed\xf6\x23\x35\x9e\x2b\x4e\x32\xc1\x9b\xf8\x84\x50\x43\x2d\xd0\x1c\xaa\x5e\xb1\x6a\x1d\xc3\x78\xf3\x91\xca\x5e\x3c\x4e\x5f\x35\x67\x28\xbd\xdd\x49\x75\xdb\x7c\x89\x0d\xa8\xbb\xc8\x4c\xc7\x3f\xf2\x44\x39\x4d\x0d\x48\x95\x49\x78\x76\x5e\x4a\x00\xb5\x93\xf7\x0f\x2c\xa0\x82\x67\x3a\x26\x1e\xd8\x8d\xbc\xef\x11\x27\x72\x8d\x8c\xd8\x9b\xc2\xc5\x97\xe9\x10\x2c\xed\x60\x10\xf6\x5f\xa7\x5a\x14\xeb\xe4\x67\xfa\x57\xce\x3b\xd4\x94\x8b\x68\x67\xd7\x4a\x9d\xf5\xc0\xec\x6f\x53\x0c\xbf\x2e\xe6\x1c\xe6\xf0\x6b\xc8\xf2\x86\x4d\xff\x55\x83\x77\x6b\x31\xdf\x8c\x7f\xfc\xb6\x14\x28\xa5\x6b\xf7\xbd\x37\x18\x8b\x4a\x51\x23\xbb\xf3\x38\x39\x3a\xf4\x6e\xda\x85\xe6",
+       "\xa2\x00\xd8\xef\x3d\x12\x0b\x91\x75\x61\xed\xc8\x42\x0b\xde\x02\x2b\x3a\xce\x79\x29\x25\xc8\xfa\xbf\x25\xad\x9b\x0f\xa6\x76\xd2\x26\x0a\xbd\x80\x98\xf3\x83\xc0\xf9\x30\x43\xd5\xd3\xf5\x6c\x47",
+       220 },
+      { GCRY_MD_SHA3_384,
+       "\x7f\xdf\xad\xcc\x9d\x29\xba\xd2\x3a\xe0\x38\xc6\xc6\x5c\xda\x1a\xef\x75\x72\x21\xb8\x87\x2e\xd3\xd7\x5f\xf8\xdf\x7d\xa0\x62\x7d\x26\x6e\x22\x4e\x81\x2c\x39\xf7\x98\x3e\x45\x58\xbf\xd0\xa1\xf2\xbe\xf3\xfe\xb5\x6b\xa0\x91\x20\xef\x76\x29\x17\xb9\xc0\x93\x86\x79\x48\x54\x7a\xee\x98\x60\x0d\x10\xd8\x7b\x20\x10\x68\x78\xa8\xd2\x2c\x64\x37\x8b\xf6\x34\xf7\xf7\x59\x00\xc0\x39\x86\xb0\x77\xb0\xbf\x8b\x74\x0a\x82\x44\x7b\x61\xb9\x9f\xee\x53\x76\xc5\xeb\x66\x80\xec\x9e\x30\x88\xf0\xbd\xd0\xc5\x68\x83\x41\x3d\x60\xc1\x35\x7d\x3c\x81\x19\x50\xe5\x89\x0e\x76\x00\x10\x3c\x91\x63\x41\xb8\x0c\x74\x3c\x6a\x85\x2b\x7b\x4f\xb6\x0c\x3b\xa2\x1f\x3b\xc1\x5b\x83\x82\x43\x7a\x68\x45\x47\x79\xcf\x3c\xd7\xf9\xf9\x0c\xcc\x8e\xf2\x8d\x0b\x70\x65\x35\xb1\xe4\x10\x8e\xb5\x62\x7b\xb4\x5d\x71\x9c\xb0\x46\x83\x9a\xee\x31\x1c\xa1\xab\xdc\x83\x19\xe0\x50\xd6\x79\x72\xcb\x35\xa6\xb1\x60\x1b\x25\xdb\xf4\x87",
+       "\xa8\x90\x5d\x1e\x9f\x4f\xc9\x6f\x2d\x76\x9d\x31\xc9\xa1\x20\xde\x43\xa0\xb2\x01\x15\xc8\xd1\x7b\xf0\x31\x32\x06\xeb\x9c\xd8\x7a\xe4\x1d\xf2\xd4\x44\xc9\xd7\x5f\x93\x66\x99\x82\x63\xd6\x1c\x07",
+       221 },
+      { GCRY_MD_SHA3_384,
+       "\x98\x86\x38\x21\x9f\xd3\x09\x54\x21\xf8\x26\xf5\x6e\x4f\x09\xe3\x56\x29\x6b\x62\x8c\x3c\xe6\x93\x0c\x9f\x2e\x75\x8f\xd1\xa8\x0c\x82\x73\xf2\xf6\x1e\x4d\xaa\xe6\x5c\x4f\x11\x0d\x3e\x7c\xa0\x96\x5a\xc7\xd2\x4e\x34\xc0\xdc\x4b\xa2\xd6\xff\x0b\xf5\xbb\xe9\x3b\x35\x85\xf3\x54\xd7\x54\x3c\xb5\x42\xa1\xaa\x54\x67\x4d\x37\x50\x77\xf2\xd3\x60\xa8\xf4\xd4\x2f\x3d\xb1\x31\xc3\xb7\xab\x73\x06\x26\x7b\xa1\x07\x65\x98\x64\xa9\x0c\x8c\x90\x94\x60\xa7\x36\x21\xd1\xf5\xd9\xd3\xfd\x95\xbe\xb1\x9b\x23\xdb\x1c\xb6\xc0\xd0\xfb\xa9\x1d\x36\x89\x15\x29\xb8\xbd\x82\x63\xca\xa1\xba\xb5\x6a\x4a\xff\xae\xd4\x49\x62\xdf\x09\x6d\x8d\x5b\x1e\xb8\x45\xef\x31\x18\x8b\x3e\x10\xf1\xaf\x81\x1a\x13\xf1\x56\xbe\xb7\xa2\x88\xaa\xe5\x93\xeb\xd1\x47\x1b\x62\x4a\xa1\xa7\xc6\xad\xf0\x1e\x22\x00\xb3\xd7\x2d\x88\xa3\xae\xd3\x10\x0c\x88\x23\x1e\x41\xef\xc3\x76\x90\x6f\x0b\x58\x0d\xc8\x95\xf0\x80\xfd\xa5\x74\x1d\xb1\xcb",
+       "\x88\x24\x9a\xf8\x4a\x7f\x1e\x49\xd1\x44\x86\x9a\x3d\x4f\xe8\xaa\x6e\x1a\x48\x74\xee\x46\x7b\xc9\x9e\x9c\x33\xe2\x10\x5a\xf2\xd0\x97\x41\x7d\x6b\x78\x53\x79\x25\x39\x2d\xb2\xc5\xcb\x1e\x0b\x92",
+       222 },
+      { GCRY_MD_SHA3_384,
+       "\x5a\xab\x62\x75\x6d\x30\x7a\x66\x9d\x14\x6a\xba\x98\x8d\x90\x74\xc5\xa1\x59\xb3\xde\x85\x15\x1a\x81\x9b\x11\x7c\xa1\xff\x65\x97\xf6\x15\x6e\x80\xfd\xd2\x8c\x9c\x31\x76\x83\x51\x64\xd3\x7d\xa7\xda\x11\xd9\x4e\x09\xad\xd7\x70\xb6\x8a\x6e\x08\x1c\xd2\x2c\xa0\xc0\x04\xbf\xe7\xcd\x28\x3b\xf4\x3a\x58\x8d\xa9\x1f\x50\x9b\x27\xa6\x58\x4c\x47\x4a\x4a\x2f\x3e\xe0\xf1\xf5\x64\x47\x37\x92\x40\xa5\xab\x1f\xb7\x7f\xdc\xa4\x9b\x30\x5f\x07\xba\x86\xb6\x27\x56\xfb\x9e\xfb\x4f\xc2\x25\xc8\x68\x45\xf0\x26\xea\x54\x20\x76\xb9\x1a\x0b\xc2\xcd\xd1\x36\xe1\x22\xc6\x59\xbe\x25\x9d\x98\xe5\x84\x1d\xf4\xc2\xf6\x03\x30\xd4\xd8\xcd\xee\x7b\xf1\xa0\xa2\x44\x52\x4e\xec\xc6\x8f\xf2\xae\xf5\xbf\x00\x69\xc9\xe8\x7a\x11\xc6\xe5\x19\xde\x1a\x40\x62\xa1\x0c\x83\x83\x73\x88\xf7\xef\x58\x59\x8a\x38\x46\xf4\x9d\x49\x96\x82\xb6\x83\xc4\xa0\x62\xb4\x21\x59\x4f\xaf\xbc\x13\x83\xc9\x43\xba\x83\xbd\xef\x51\x5e\xfc\xf1\x0d",
+       "\xc4\x61\x22\xd0\x0b\x61\xe7\x9d\xf0\x25\xa4\xd5\x25\xb8\xa6\x02\xc7\xac\x00\x43\x04\xa9\x93\x87\x2e\x3a\x8a\xa3\x7f\xc0\xe8\xea\xae\x5f\xad\x9a\x22\x0c\x5c\x6a\xfb\xd5\xa4\x78\x36\x80\x01\x3a",
+       223 },
+      { GCRY_MD_SHA3_384,
+       "\x47\xb8\x21\x6a\xa0\xfb\xb5\xd6\x79\x66\xf2\xe8\x2c\x17\xc0\x7a\xa2\xd6\x32\x7e\x96\xfc\xd8\x3e\x3d\xe7\x33\x36\x89\xf3\xee\x79\x99\x4a\x1b\xf4\x50\x82\xc4\xd7\x25\xed\x8d\x41\x20\x5c\xb5\xbc\xdf\x5c\x34\x1f\x77\xfa\xcb\x1d\xa4\x6a\x5b\x9b\x2c\xbc\x49\xea\xdf\x78\x6b\xcd\x88\x1f\x37\x1a\x95\xfa\x17\xdf\x73\xf6\x06\x51\x9a\xea\x0f\xf7\x9d\x5a\x11\x42\x7b\x98\xee\x7f\x13\xa5\xc0\x06\x37\xe2\x85\x41\x34\x69\x10\x59\x83\x91\x21\xfe\xa9\xab\xe2\xcd\x1b\xcb\xbb\xf2\x7c\x74\xca\xf3\x67\x8e\x05\xbf\xb1\xc9\x49\x89\x7e\xa0\x1f\x56\xff\xa4\xda\xfb\xe8\x64\x46\x11\x68\x5c\x61\x7a\x32\x06\xc7\xa7\x03\x6e\x4a\xc8\x16\x79\x9f\x69\x3d\xaf\xe7\xf1\x9f\x30\x3c\xe4\xeb\xa0\x9d\x21\xe0\x36\x10\x20\x1b\xfc\x66\x5b\x72\x40\x0a\x54\x7a\x1e\x00\xfa\x9b\x7a\xd8\xd8\x4f\x84\xb3\x4a\xef\x11\x85\x15\xe7\x4d\xef\x11\xb9\x18\x8b\xd1\xe1\xf9\x7d\x9a\x12\xc3\x01\x32\xec\x28\x06\x33\x9b\xda\xda\xcd\xa2\xfd\x8b\x78",
+       "\xab\xa0\xee\x3c\x16\xd3\xdc\x75\x3f\x6e\x46\x6c\x33\xa9\x98\xa7\x32\x82\xc0\xdb\xea\xf5\x13\x24\x97\x9a\x58\x43\x76\x36\x88\x6e\x55\x21\xb5\x67\xc9\xa6\x2d\x40\x5e\xe5\x58\xff\xeb\xae\x91\xbc",
+       224 },
+      { GCRY_MD_SHA3_384,
+       "\x8c\xff\x1f\x67\xfe\x53\xc0\x98\x89\x6d\x91\x36\x38\x9b\xd8\x88\x18\x16\xcc\xab\x34\x86\x2b\xb6\x7a\x65\x6e\x3d\x98\x89\x6f\x3c\xe6\xff\xd4\xda\x73\x97\x58\x09\xfc\xdf\x96\x66\x76\x0d\x6e\x56\x1c\x55\x23\x8b\x20\x5d\x80\x49\xc1\xce\xde\xef\x37\x4d\x17\x35\xda\xa5\x33\x14\x7b\xfa\x96\x0b\x2c\xce\x4a\x4f\x25\x41\x76\xbb\x4d\x1b\xd1\xe8\x96\x54\x43\x2b\x8d\xbe\x1a\x13\x5c\x42\x11\x5b\x39\x4b\x02\x48\x56\xa2\xa8\x3d\xc8\x5d\x67\x82\xbe\x4b\x44\x42\x39\x56\x7c\xce\xc4\xb1\x84\xd4\x54\x8e\xae\x3f\xf6\xa1\x92\xf3\x43\x29\x2b\xa2\xe3\x2a\x0f\x26\x7f\x31\xcc\x26\x71\x9e\xb8\x52\x45\xd4\x15\xfb\x89\x7a\xc2\xda\x43\x3e\xe9\x1a\x99\x42\x4c\x9d\x7f\x17\x66\xa4\x41\x71\xd1\x65\x10\x01\xc3\x8f\xc7\x92\x94\xac\xcc\x68\xce\xb5\x66\x5d\x36\x21\x84\x54\xd3\xba\x16\x9a\xe0\x58\xa8\x31\x33\x8c\x17\x74\x36\x03\xf8\x1e\xe1\x73\xbf\xc0\x92\x74\x64\xf9\xbd\x72\x8d\xee\x94\xc6\xae\xab\x7a\xae\x6e\xe3\xa6\x27\xe8",
+       "\x28\xb3\x71\x25\xf2\x33\xba\x8d\x52\x7e\x52\x84\xa1\x6e\x6e\xfe\x9a\xe8\x4d\x3e\xbc\x6e\xe4\xc8\x8a\xee\x0a\xb1\x65\xc1\x11\xa3\x2f\xf2\xcd\xcc\x42\x13\xac\x32\x67\xb0\x54\x6d\xc0\xd7\x4c\x84",
+       225 },
+      { GCRY_MD_SHA3_384,
+       "\xea\xcd\x07\x97\x1c\xff\x9b\x99\x39\x90\x3f\x8c\x1d\x8c\xbb\x5d\x4d\xb1\xb5\x48\xa8\x5d\x04\xe0\x37\x51\x4a\x58\x36\x04\xe7\x87\xf3\x29\x92\xbf\x21\x11\xb9\x7a\xc5\xe8\xa9\x38\x23\x35\x52\x73\x13\x21\x52\x2a\xb5\xe8\x58\x35\x61\x26\x0b\x7d\x13\xeb\xee\xf7\x85\xb2\x3a\x41\xfd\x85\x76\xa6\xda\x76\x4a\x8e\xd6\xd8\x22\xd4\x95\x7a\x54\x5d\x52\x44\x75\x6c\x18\xaa\x80\xe1\xaa\xd4\xd1\xf9\xc2\x0d\x25\x9d\xee\x17\x11\xe2\xcc\x8f\xd0\x13\x16\x9f\xb7\xcc\x4c\xe3\x8b\x36\x2f\x8e\x09\x36\xae\x91\x98\xb7\xe8\x38\xdc\xea\x4f\x7a\x5b\x94\x29\xbb\x3f\x6b\xbc\xf2\xdc\x92\x56\x5e\x36\x76\xc1\xc5\xe6\xeb\x3d\xd2\xa0\xf8\x6a\xa2\x3e\xdd\x3d\x08\x91\xf1\x97\x44\x76\x92\x79\x4b\x3d\xfa\x26\x96\x11\xad\x97\xf7\x2b\x79\x56\x02\xb4\xfd\xb1\x98\xf3\xfd\x3e\xb4\x1b\x41\x50\x64\x25\x6e\x34\x5e\x8d\x8c\x51\xc5\x55\xdc\x8a\x21\x90\x4a\x9b\x0f\x1a\xd0\xef\xfa\xb7\x78\x6a\xac\x2d\xa3\xb1\x96\x50\x7e\x9f\x33\xca\x35\x64\x27",
+       "\x25\x89\x88\xe5\x4d\x66\xe0\xc5\x3b\x26\x3b\xa6\x8d\x9e\x3a\xa4\x7d\x27\x8d\xf8\x7c\x51\x21\x9c\xce\x6f\x25\x47\x28\x1e\xa6\x58\x15\x40\xe2\x8c\x1d\x7e\x06\x92\x54\x79\x1f\x0d\x38\x5e\xa6\x94",
+       226 },
+      { GCRY_MD_SHA3_384,
+       "\x23\xac\x4e\x9a\x42\xc6\xef\x45\xc3\x33\x6c\xe6\xdf\xc2\xff\x7d\xe8\x88\x4c\xd2\x3d\xc9\x12\xfe\xf0\xf7\x75\x6c\x09\xd3\x35\xc1\x89\xf3\xad\x3a\x23\x69\x7a\xbd\xa8\x51\xa8\x18\x81\xa0\xc8\xcc\xaf\xc9\x80\xab\x2c\x70\x25\x64\xc2\xbe\x15\xfe\x4c\x4b\x9f\x10\xdf\xb2\x24\x8d\x0d\x0c\xb2\xe2\x88\x7f\xd4\x59\x8a\x1d\x4a\xcd\xa8\x97\x94\x4a\x2f\xfc\x58\x0f\xf9\x27\x19\xc9\x5c\xf2\xaa\x42\xdc\x58\x46\x74\xcb\x5a\x9b\xc5\x76\x5b\x9d\x6d\xdf\x57\x89\x79\x1d\x15\xf8\xdd\x92\x5a\xa1\x2b\xff\xaf\xbc\xe6\x08\x27\xb4\x90\xbb\x7d\xf3\xdd\xa6\xf2\xa1\x43\xc8\xbf\x96\xab\xc9\x03\xd8\x3d\x59\xa7\x91\xe2\xd6\x28\x14\xa8\x9b\x80\x80\xa2\x80\x60\x56\x8c\xf2\x4a\x80\xae\x61\x17\x9f\xe8\x4e\x0f\xfa\xd0\x03\x88\x17\x8c\xb6\xa6\x17\xd3\x7e\xfd\x54\xcc\x01\x97\x0a\x4a\x41\xd1\xa8\xd3\xdd\xce\x46\xed\xbb\xa4\xab\x7c\x90\xad\x56\x53\x98\xd3\x76\xf4\x31\x18\x9c\xe8\xc1\xc3\x3e\x13\x2f\xea\xe6\xa8\xcd\x17\xa6\x1c\x63\x00\x12",
+       "\xf6\xa9\x39\x9b\x48\x2a\x3a\x5e\xa6\xfe\x79\xa2\xdb\x7b\xae\x7e\x58\x8c\x9b\x7d\xa0\x3d\xd8\x5c\x12\x01\x12\xfd\xbc\x23\x43\x50\x52\x9a\x1f\x37\xab\xbe\xbe\xb7\x70\x29\x9e\x14\x1e\xea\x7b\xa3",
+       227 },
+      { GCRY_MD_SHA3_384,
+       "\x01\x72\xdf\x73\x22\x82\xc9\xd4\x88\x66\x9c\x35\x8e\x34\x92\x26\x0c\xbe\x91\xc9\x5c\xfb\xc1\xe3\xfe\xa6\xc4\xb0\xec\x12\x9b\x45\xf2\x42\xac\xe0\x9f\x15\x2f\xc6\x23\x4e\x1b\xee\x8a\xab\x8c\xd5\x6e\x8b\x48\x6e\x1d\xcb\xa9\xc0\x54\x07\xc2\xf9\x5d\xa8\xd8\xf1\xc0\xaf\x78\xee\x2e\xd8\x2a\x3a\x79\xec\x0c\xb0\x70\x93\x96\xee\x62\xaa\xdb\x84\xf8\xa4\xee\x8a\x7c\xcc\xa3\xc1\xee\x84\xe3\x02\xa0\x9e\xa8\x02\x20\x4a\xfe\xcf\x04\x09\x7e\x67\xd0\xf8\xe8\xa9\xd2\x65\x11\x26\xc0\xa5\x98\xa3\x70\x81\xe4\x2d\x16\x8b\x0a\xe8\xa7\x19\x51\xc5\x24\x25\x9e\x4e\x20\x54\xe5\x35\xb7\x79\x67\x9b\xda\xde\x56\x6f\xe5\x57\x00\x85\x86\x18\xe6\x26\xb4\xa0\xfa\xf8\x95\xbc\xce\x90\x11\x50\x4a\x49\xe0\x5f\xd5\x61\x27\xea\xe3\xd1\xf8\x91\x7a\xfb\x54\x8e\xca\xda\xbd\xa1\x02\x01\x11\xfe\xc9\x31\x4c\x41\x34\x98\xa3\x60\xb0\x86\x40\x54\x9a\x22\xcb\x23\xc7\x31\xac\xe7\x43\x25\x2a\x82\x27\xa0\xd2\x68\x9d\x4c\x60\x01\x60\x66\x78\xdf\xb9\x21",
+       "\xc0\xf9\x57\xe5\x2e\x40\xf9\xb8\xea\x94\x5d\x40\x77\x92\x86\xf7\x25\x7a\xd4\x63\xa9\x34\xb0\x49\xdf\x40\xc3\x1d\x35\x47\xae\xf4\x1a\xea\x2d\xd9\x81\xfd\x25\x79\x32\x72\x29\xb5\x4e\xe0\x4e\x66",
+       228 },
+      { GCRY_MD_SHA3_384,
+       "\x38\x75\xb9\x24\x0c\xf3\xe0\xa8\xb5\x9c\x65\x85\x40\xf2\x6a\x70\x1c\xf1\x88\x49\x6e\x2c\x21\x74\x78\x8b\x12\x6f\xd2\x94\x02\xd6\xa7\x54\x53\xba\x06\x35\x28\x4d\x08\x83\x5f\x40\x05\x1a\x2a\x96\x83\xdc\x92\xaf\xb9\x38\x37\x19\x19\x12\x31\x17\x03\x79\xba\x6f\x4a\xdc\x81\x6f\xec\xbb\x0f\x9c\x44\x6b\x78\x5b\xf5\x20\x79\x68\x41\xe5\x88\x78\xb7\x3c\x58\xd3\xeb\xb0\x97\xce\x47\x61\xfd\xea\xbe\x15\xde\x2f\x31\x9d\xfb\xaf\x17\x42\xcd\xeb\x38\x95\x59\xc7\x88\x13\x1a\x67\x93\xe1\x93\x85\x66\x61\x37\x6c\x81\xce\x95\x68\xda\x19\xaa\x69\x25\xb4\x7f\xfd\x77\xa4\x3c\x7a\x0e\x75\x8c\x37\xd6\x92\x54\x90\x9f\xf0\xfb\xd4\x15\xef\x8e\xb9\x37\xbc\xd4\x9f\x91\x46\x8b\x49\x97\x4c\x07\xdc\x81\x9a\xbd\x67\x39\x5d\xb0\xe0\x58\x74\xff\x83\xdd\xda\xb8\x95\x34\x4a\xbd\x0e\x71\x11\xb2\xdf\x9e\x58\xd7\x6d\x85\xad\x98\x10\x6b\x36\x29\x58\x26\xbe\x04\xd4\x35\x61\x55\x95\x60\x5e\x4b\x4b\xb8\x24\xb3\x3c\x4a\xfe\xb5\xe7\xbb\x0d\x19\xf9\x09",
+       "\x77\x9e\xec\xf3\x93\x11\x31\x80\x51\xbf\x73\xc4\x41\xfb\x79\x97\x08\x91\x20\x49\xe2\x8d\xf3\xfa\xdd\xe4\x49\xe4\xcd\x82\x0c\xc4\xca\x1b\xd0\xf8\x51\x39\x27\xd9\xa6\x4f\x5d\x34\xfa\xab\xa0\x39",
+       229 },
+      { GCRY_MD_SHA3_384,
+       "\x74\x7c\xc1\xa5\x9f\xef\xba\x94\xa9\xc7\x5b\xa8\x66\xc3\x0d\xc5\xc1\xcb\x0c\x0f\x8e\x93\x61\xd9\x84\x84\x95\x6d\xd5\xd1\xa4\x0f\x61\x84\xaf\xbe\x3d\xac\x9f\x76\x02\x8d\x1c\xae\xcc\xfb\xf6\x91\x99\xc6\xce\x2b\x4c\x09\x2a\x3f\x4d\x2a\x56\xfe\x5a\x33\xa0\x07\x57\xf4\xd7\xde\xe5\xdf\xb0\x52\x43\x11\xa9\x7a\xe0\x66\x8a\x47\x97\x1b\x95\x76\x6e\x2f\x6d\xd4\x8c\x3f\x57\x84\x1f\x91\xf0\x4a\x00\xad\x5e\xa7\x0f\x2d\x47\x9a\x26\x20\xdc\x5c\xd7\x8e\xaa\xb3\xa3\xb0\x11\x71\x9b\x7e\x78\xd1\x9d\xdf\x70\xd9\x42\x37\x98\xaf\x77\x51\x7e\xbc\x55\x39\x2f\xcd\x01\xfc\x60\x0d\x8d\x46\x6b\x9e\x7a\x7a\x85\xbf\x33\xf9\xcc\x54\x19\xe9\xbd\x87\x4d\xdf\xd6\x09\x81\x15\x0d\xda\xf8\xd7\xfe\xba\xa4\x37\x4f\x08\x72\xa5\x62\x8d\x31\x80\x00\x31\x1e\x2f\x56\x55\x36\x5a\xd4\xd4\x07\xc2\x0e\x5c\x04\xdf\x17\xa2\x22\xe7\xde\xec\x79\xc5\xab\x11\x16\xd8\x57\x2f\x91\xcd\x06\xe1\xcc\xc7\xce\xd5\x37\x36\xfc\x86\x7f\xd4\x9e\xce\xbe\x6b\xf8\x08\x2e\x8a",
+       "\x3d\x64\x95\xeb\x3d\xa4\xe8\x1d\x34\x70\xa0\x50\xf4\x16\xe2\xc8\xab\xf6\x57\xa2\x6d\x4f\xd6\x4a\xf3\x57\x35\xb5\x78\x2b\x61\x1f\xb7\x98\xa7\x2f\xe7\xa6\x1c\xe7\x9d\x04\x96\xf6\x96\x54\xcc\x80",
+       230 },
+      { GCRY_MD_SHA3_384,
+       "\x57\xaf\x97\x1f\xcc\xae\xc9\x74\x35\xdc\x2e\xc9\xef\x04\x29\xbc\xed\xc6\xb6\x47\x72\x9e\xa1\x68\x85\x8a\x6e\x49\xac\x10\x71\xe7\x06\xf4\xa5\xa6\x45\xca\x14\xe8\xc7\x74\x6d\x65\x51\x16\x20\x68\x2c\x90\x6c\x8b\x86\xec\x90\x1f\x3d\xde\xd4\x16\x7b\x3f\x00\xb0\x6c\xbf\xac\x6a\xee\x37\x28\x05\x1b\x3e\x5f\xf1\x0b\x4f\x9e\xd8\xbd\x0b\x8d\xa9\x43\x03\xc8\x33\x75\x5b\x3c\xa3\xae\xdd\xf0\xb5\x4b\xc8\xd6\x63\x21\x38\xb5\xd2\x5b\xab\x03\xd1\x7b\x34\x58\xa9\xd7\x82\x10\x80\x06\xf5\xbb\x7d\xe7\x5b\x5c\x0b\xa8\x54\xb4\x23\xd8\xbb\x80\x1e\x70\x1e\x99\xdc\x4f\xea\xad\x59\xbc\x1c\x71\x12\x45\x3b\x04\xd3\x3e\xa3\x63\x56\x39\xfb\x80\x2c\x73\xc2\xb7\x1d\x58\xa5\x6b\xbd\x67\x1b\x18\xfe\x34\xed\x2e\x3d\xca\x38\x82\x7d\x63\xfd\xb1\xd4\xfb\x32\x85\x40\x50\x04\xb2\xb3\xe2\x60\x81\xa8\xff\x08\xcd\x6d\x2b\x08\xf8\xe7\xb7\xe9\x0a\x2a\xb1\xed\x7a\x41\xb1\xd0\x12\x85\x22\xc2\xf8\xbf\xf5\x6a\x7f\xe6\x79\x69\x42\x2c\xe8\x39\xa9\xd4\x60\x8f\x03",
+       "\xf8\x18\x8e\xaf\xd0\xe2\xf9\xc7\xf4\x4e\x70\xb3\x8d\xb1\xfe\x3e\x12\xb1\x46\x97\x39\xca\x6a\x13\xed\x5a\x86\x61\x67\x3a\x31\x82\x96\xff\xaf\x8d\x37\xf6\xfc\xec\x22\xa2\xd0\x0e\xee\x2a\xbe\xba",
+       231 },
+      { GCRY_MD_SHA3_384,
+       "\x04\xe1\x6d\xed\xc1\x22\x79\x02\xba\xaf\x33\x2d\x3d\x08\x92\x36\x01\xbd\xd6\x4f\x57\x3f\xaa\x1b\xb7\x20\x19\x18\xcf\xe1\x6b\x1e\x10\x15\x1d\xae\x87\x5d\xa0\xc0\xd6\x3c\x59\xc3\xdd\x05\x0c\x4c\x6a\x87\x40\x11\xb0\x18\x42\x1a\xfc\x46\x23\xab\x03\x81\x83\x1b\x2d\xa2\xa8\xba\x42\xc9\x6e\x4f\x70\x86\x4a\xc4\x4e\x10\x6f\x94\x31\x10\x51\xe7\x4c\x77\xc1\x29\x1b\xf5\xdb\x95\x39\xe6\x95\x67\xbf\x6a\x11\xcf\x69\x32\xbb\xba\xd3\x3f\x89\x46\xbf\x58\x14\xc0\x66\xd8\x51\x63\x3d\x1a\x51\x35\x10\x03\x9b\x34\x99\x39\xbf\xd4\x2b\x85\x8c\x21\x82\x7c\x8f\xf0\x5f\x1d\x09\xb1\xb0\x76\x5d\xc7\x8a\x13\x5b\x5c\xa4\xdf\xba\x08\x01\xbc\xad\xdf\xa1\x75\x62\x3c\x8b\x64\x7e\xac\xfb\x44\x44\xb8\x5a\x44\xf7\x38\x90\x60\x7d\x06\xd5\x07\xa4\xf8\x39\x36\x58\x78\x86\x69\xf6\xef\x4d\xeb\x58\xd0\x8c\x50\xca\x07\x56\xd5\xe2\xf4\x9d\x1a\x7a\xd7\x3e\x0f\x0b\x3d\x3b\x5f\x09\x0a\xcf\x62\x2b\x18\x78\xc5\x91\x33\xe4\xa8\x48\xe0\x51\x53\x59\x2e\xa8\x1c\x6f\xbf",
+       "\x7d\x83\xc3\xf2\x26\x5c\x90\xfe\xf4\xbc\x6b\xd0\xd1\x7a\x21\x8f\x0e\x19\x64\x89\xcb\x2d\x84\x55\xbb\xee\x80\xab\x98\x9f\xfe\xa4\x6d\xe7\x53\x34\x6e\xdb\xd5\xc8\x84\x48\xfe\xdb\x0d\x4a\xad\x4d",
+       232 },
+      { GCRY_MD_SHA3_384,
+       "\x7c\x81\x5c\x38\x4e\xee\x0f\x28\x8e\xce\x27\xcc\xed\x52\xa0\x16\x03\x12\x7b\x07\x9c\x00\x73\x78\xbc\x5d\x1e\x6c\x5e\x9e\x6d\x1c\x73\x57\x23\xac\xbb\xd5\x80\x1a\xc4\x98\x54\xb2\xb5\x69\xd4\x47\x2d\x33\xf4\x0b\xbb\x88\x82\x95\x62\x45\xc3\x66\xdc\x35\x82\xd7\x16\x96\xa9\x7a\x4e\x19\x55\x7e\x41\xe5\x4d\xee\x48\x2a\x14\x22\x90\x05\xf9\x3a\xfd\x2c\x4a\x7d\x86\x14\xd1\x0a\x97\xa9\xdf\xa0\x7f\x7c\xd9\x46\xfa\x45\x26\x30\x63\xdd\xd2\x9d\xb8\xf9\xe3\x4d\xb6\x0d\xaa\x32\x68\x4f\x00\x72\xea\x2a\x94\x26\xec\xeb\xfa\x52\x39\xfb\x67\xf2\x9c\x18\xcb\xaa\x2a\xf6\xed\x4b\xf4\x28\x39\x36\x82\x3a\xc1\x79\x01\x64\xfe\xc5\x45\x7a\x9c\xba\x7c\x76\x7c\xa5\x93\x92\xd9\x4c\xab\x74\x48\xf5\x0e\xb3\x4e\x9a\x93\xa8\x00\x27\x47\x1c\xe5\x97\x36\xf0\x99\xc8\x86\xde\xa1\xab\x4c\xba\x4d\x89\xf5\xfc\x7a\xe2\xf2\x1c\xcd\x27\xf6\x11\xec\xa4\x62\x6b\x2d\x08\xdc\x22\x38\x2e\x92\xc1\xef\xb2\xf6\xaf\xdc\x8f\xdc\x3d\x21\x72\x60\x4f\x50\x35\xc4\x6b\x81\x97\xd3",
+       "\xfc\xc5\xfc\xfe\xf5\xba\x87\x4a\x31\x7b\x73\xc9\xb1\xb4\xcf\x68\x77\x37\x3d\x41\xf0\xb8\x08\x0a\x5d\x4f\x02\x1e\x0d\x67\xf3\xb9\xf8\xcc\xaa\xcf\xd4\x24\x4f\xc1\x0b\xa5\x8b\x3a\x47\x0d\xb4\x8b",
+       233 },
+      { GCRY_MD_SHA3_384,
+       "\xe2\x9d\x50\x51\x58\xdb\xdd\x93\x7d\x9e\x3d\x21\x45\x65\x8e\xe6\xf5\x99\x2a\x2f\xc7\x90\xf4\xf6\x08\xd9\xcd\xb4\x4a\x09\x1d\x5b\x94\xb8\x8e\x81\xfa\xc4\xfd\xf5\xc4\x94\x42\xf1\x3b\x91\x1c\x55\x88\x64\x69\x62\x95\x51\x18\x9e\xaf\xf6\x24\x88\xf1\xa4\x79\xb7\xdb\x11\xa1\x56\x0e\x19\x8d\xdc\xcc\xcf\x50\x15\x90\x93\x42\x5f\xf7\xf1\xcb\x8d\x1d\x12\x46\xd0\x97\x87\x64\x08\x7d\x6b\xac\x25\x70\x26\xb0\x90\xef\xae\x8c\xec\x5f\x22\xb6\xf2\x1c\x59\xac\xe1\xac\x73\x86\xf5\xb8\x83\x7c\xa6\xa1\x2b\x6f\xbf\x55\x34\xdd\x05\x60\xef\x05\xca\x78\x10\x4d\x3b\x94\x3d\xdb\x22\x0f\xea\xec\x89\xaa\x5e\x69\x2a\x00\xf8\x22\xa2\xab\x9a\x2f\xe6\x03\x50\xd7\x5e\x7b\xe1\x6f\xf2\x52\x6d\xc6\x43\x87\x25\x02\xd0\x1f\x42\xf1\x88\xab\xed\x0a\x6e\x9a\x6f\x5f\xd0\xd1\xce\x7d\x57\x55\xc9\xff\xa6\x6b\x0a\xf0\xb2\x0b\xd8\x06\xf0\x8e\x06\x15\x66\x90\xd8\x1a\xc8\x11\x77\x8c\xa3\xda\xc2\xc2\x49\xb9\x60\x02\x01\x7f\xce\x93\xe5\x07\xe3\xb9\x53\xac\xf9\x99\x64\xb8\x47",
+       "\x9b\x33\x6b\x4c\x2b\x53\x0f\x65\xc0\x1a\xf3\xf0\xa4\x6c\xf1\xb6\x26\xd5\xdb\xf1\xb2\xe5\x0f\x79\x0b\x9f\x34\xcc\xa3\x67\x31\x5f\xdf\xbf\x7d\x96\x19\xcd\xa4\xda\x22\xe3\x9f\x93\x15\x30\x38\x16",
+       234 },
+      { GCRY_MD_SHA3_384,
+       "\xd8\x55\x88\x69\x6f\x57\x6e\x65\xec\xa0\x15\x5f\x39\x5f\x0c\xfa\xcd\x83\xf3\x6a\x99\x11\x1e\xd5\x76\x8d\xf2\xd1\x16\xd2\x12\x1e\x32\x35\x7b\xa4\xf5\x4e\xde\x92\x7f\x18\x9f\x29\x7d\x3a\x97\xfa\xd4\xe9\xa0\xf5\xb4\x1d\x8d\x89\xdd\x7f\xe2\x01\x56\x79\x9c\x2b\x7b\x6b\xf9\xc9\x57\xba\x0d\x67\x63\xf5\xc3\xbc\x51\x29\x74\x7b\xbb\x53\x65\x2b\x49\x29\x0c\xff\x1c\x87\xe2\xcd\xf2\xc4\xb9\x5d\x8a\xae\xe0\x9b\xc8\xfb\xfa\x68\x83\xe6\x2d\x23\x78\x85\x81\x04\x91\xbf\xc1\x01\xf1\xd8\xc6\x36\xe3\xd0\xed\xe8\x38\xad\x05\xc2\x07\xa3\xdf\x4f\xad\x76\x45\x29\x79\xeb\x99\xf2\x9a\xfa\xec\xed\xd1\xc6\x3b\x8d\x36\xcf\x37\x84\x54\xa1\xbb\x67\xa7\x41\xc7\x7a\xc6\xb6\xb3\xf9\x5f\x4f\x02\xb6\x4d\xab\xc1\x54\x38\x61\x3e\xa4\x97\x50\xdf\x42\xee\x90\x10\x1f\x11\x5a\xa9\xab\xb9\xff\x64\x32\x4d\xde\x9d\xab\xbb\x01\x05\x4e\x1b\xd6\xb4\xbc\xdc\x79\x30\xa4\x4c\x23\x00\xd8\x7c\xa7\x8c\x06\x92\x4d\x03\x23\xad\x78\x87\xe4\x6c\x90\xe8\xc4\xd1\x00\xac\xd9\xee\xd2\x1e",
+       "\xca\xc4\x42\x22\x7f\x10\xc4\x93\x5d\x42\xc2\x91\x40\x43\x16\x78\x90\xc3\xee\x1f\x45\x56\xd3\x8d\x20\x76\x7e\x84\x02\xae\xc4\xd7\x01\x11\xf2\x03\x42\x76\xe9\x0f\x28\x10\x2d\xe6\x34\xe2\x6a\xfd",
+       235 },
+      { GCRY_MD_SHA3_384,
+       "\x3a\x12\xf8\x50\x8b\x40\xc3\x2c\x74\x49\x2b\x66\x32\x33\x75\xdc\xfe\x49\x18\x4c\x78\xf7\x31\x79\xf3\x31\x4b\x79\xe6\x33\x76\xb8\xac\x68\x3f\x5a\x51\xf1\x53\x4b\xd7\x29\xb0\x2b\x04\xd0\x02\xf5\x5c\xbd\x8e\x8f\xc9\xb5\xec\x1e\xa6\xbb\xe6\xa0\xd0\xe7\x43\x15\x18\xe6\xba\x45\xd1\x24\x03\x5f\x9d\x3d\xce\x0a\x8b\xb7\xbf\x14\x30\xa9\xf6\x57\xe0\xb4\xea\x9f\x20\xeb\x20\xc7\x86\xa5\x81\x81\xa1\xe2\x0a\x96\xf1\x62\x8f\x87\x28\xa1\x3b\xdf\x7a\x4b\x4b\x32\xfc\x8a\xa7\x05\x4c\xc4\x88\x1a\xe7\xfa\x19\xaf\xa6\x5c\x6c\x3e\xe1\xb3\xad\xe3\x19\x2a\xf4\x20\x54\xa8\xa9\x11\xb8\xec\x18\x26\x86\x5d\x46\xd9\x3f\x1e\x7c\x5e\x2b\x78\x13\xc9\x2a\x50\x6e\x53\x88\x6f\x3d\x47\x01\xbb\x93\xd2\xa6\x81\xad\x10\x9c\x84\x59\x04\xbb\x86\x1a\xf8\xaf\x06\x46\xb6\xe3\x99\xb3\x8b\x61\x40\x51\xd3\x4f\x68\x42\x56\x3a\x0f\x37\xec\x00\xcb\x3d\x86\x5f\xc5\xd7\x46\xc4\x98\x7d\xe2\xa6\x50\x71\x10\x08\x83\xa2\xa9\xc7\xa2\xbf\xe1\xe2\xdd\x60\x3d\x9e\xa2\x4d\xc7\xc5\xfd\x06\xbe",
+       "\x05\xe3\xfb\x83\xee\x8d\x60\x98\x74\xd5\x93\x52\x83\x70\x2f\x29\xe5\xe8\x96\xbb\x09\x0c\x48\x03\x34\x89\x29\x59\x89\xc4\x5d\xd2\xc0\x6f\x5b\xd5\x58\xb6\xbc\x78\x6a\xb1\x25\x1f\x75\x66\x4b\x06",
+       236 },
+      { GCRY_MD_SHA3_384,
+       "\x18\x61\xed\xce\x46\xfa\x5a\xd1\x7e\x1f\xf1\xde\xae\x08\x4d\xec\x58\x0f\x97\xd0\xa6\x78\x85\xdf\xe8\x34\xb9\xdf\xac\x1a\xe0\x76\x74\x2c\xe9\xe2\x67\x51\x2c\xa5\x1f\x6d\xf5\xa4\x55\xaf\x0c\x5f\xd6\xab\xf9\x4a\xce\xa1\x03\xa3\x37\x0c\x35\x44\x85\xa7\x84\x6f\xb8\x4f\x3a\xc7\xc2\x90\x4b\x5b\x2f\xbf\x22\x70\x02\xce\x51\x21\x33\xbb\x7e\x1c\x4e\x50\x05\x7b\xfd\x1e\x44\xdb\x33\xc7\xcd\xb9\x69\xa9\x9e\x28\x4b\x18\x4f\x50\xa1\x4b\x06\x8a\x1f\xc5\x00\x9d\x9b\x29\x8d\xbe\x92\x23\x95\x72\xa7\x62\x7a\xac\x02\xab\xe8\xf3\xe3\xb4\x73\x41\x7f\x36\xd4\xd2\x50\x5d\x16\xb7\x57\x7f\x45\x26\xc9\xd9\x4a\x27\x0a\x2d\xfe\x45\x0d\x06\xda\x8f\x6f\xa9\x56\x87\x9a\x0a\x55\xcf\xe9\x9e\x74\x2e\xa5\x55\xea\x47\x7b\xa3\xe9\xb4\x4c\xcd\x50\x8c\x37\x54\x23\x61\x1a\xf9\x2e\x55\x34\x5d\xc2\x15\x77\x9b\x2d\x51\x19\xeb\xa4\x9c\x71\xd4\x9b\x9f\xe3\xf1\x56\x9f\xa2\x4e\x5c\xa3\xe3\x32\xd0\x42\x42\x2a\x8b\x81\x58\xd3\xec\x66\xa8\x00\x12\x97\x6f\x31\xff\xdf\x30\x5f\x0c\x9c\x5e",
+       "\x6e\x46\x3c\x7f\xb5\xcf\x43\x6b\x14\x44\x92\x1a\xfe\x76\xd2\xfa\x4e\x7a\x23\xed\xfc\x9d\x49\x6a\xf1\xdc\x7e\x78\xa0\x17\x3d\x79\x7e\xff\x80\xf2\xbb\x32\xcf\xd3\x4d\xaf\x56\x33\xc4\xe6\xbc\xd6",
+       237 },
+      { GCRY_MD_SHA3_384,
+       "\x08\xd0\xff\xde\x3a\x6e\x4e\xf6\x56\x08\xea\x67\x2e\x48\x30\xc1\x29\x43\xd7\x18\x7c\xcf\xf0\x8f\x49\x41\xcf\xc1\x3e\x54\x5f\x3b\x9c\x7a\xd5\xee\xbb\xe2\xb0\x16\x42\xb4\x86\xca\xf8\x55\xc2\xc7\x3f\x58\xc1\xe4\xe3\x39\x1d\xa8\xe2\xd6\x3d\x96\xe1\x5f\xd8\x49\x53\xae\x5c\x23\x19\x11\xb0\x0a\xd6\x05\x0c\xd7\xaa\xfd\xaa\xc9\xb0\xf6\x63\xae\x6a\xab\x45\x51\x9d\x0f\x53\x91\xa5\x41\x70\x7d\x47\x90\x34\xe7\x3a\x6a\xd8\x05\xae\x35\x98\x09\x6a\xf0\x78\xf1\x39\x33\x01\x49\x3d\x66\x3d\xd7\x1f\x83\x86\x9c\xa2\x7b\xa5\x08\xb7\xe9\x1e\x81\xe1\x28\xc1\x71\x6d\xc3\xac\xfe\x30\x84\xb2\x20\x1e\x04\xcf\x80\x06\x61\x7e\xec\xf1\xb6\x40\x47\x4a\x5d\x45\xcf\xde\x9f\x4d\x3e\xf9\x2d\x6d\x05\x5b\x90\x98\x92\x19\x4d\x8a\x82\x18\xdb\x6d\x82\x03\xa8\x42\x61\xd2\x00\xd7\x14\x73\xd7\x48\x8f\x34\x27\x41\x6b\x68\x96\xc1\x37\xd4\x55\xf2\x31\x07\x1c\xac\xbc\x86\xe0\x41\x5a\xb8\x8a\xec\x84\x1d\x96\xb7\xb8\xaf\x41\xe0\x5b\xb4\x61\xa4\x06\x45\xbf\x17\x66\x01\xf1\xe7\x60\xde\x5f",
+       "\x90\x45\x7e\x3d\x33\xfc\xe1\x03\x42\x00\x56\xa1\xc7\x12\x44\x1e\x04\x85\x6b\x17\xcf\x37\xa4\xe1\x33\x84\x1e\x6d\x9a\x94\x4b\x5e\xbe\xf9\x8c\xb1\xc1\xcc\xd5\x75\x63\x2c\xd3\xb5\xc1\x77\x66\x9e",
+       238 },
+      { GCRY_MD_SHA3_384,
+       "\xd7\x82\xab\xb7\x2a\x5b\xe3\x39\x27\x57\xbe\x02\xd3\xe4\x5b\xe6\xe2\x09\x9d\x6f\x00\x0d\x04\x2c\x8a\x54\x3f\x50\xed\x6e\xbc\x05\x5a\x7f\x13\x3b\x0d\xd8\xe9\xbc\x34\x85\x36\xed\xca\xae\x2e\x12\xec\x18\xe8\x83\x7d\xf7\xa1\xb3\xc8\x7e\xc4\x6d\x50\xc2\x41\xde\xe8\x20\xfd\x58\x61\x97\x55\x2d\xc2\x0b\xee\xa5\x0f\x44\x5a\x07\xa3\x8f\x17\x68\xa3\x9e\x2b\x2f\xf0\x5d\xdd\xed\xf7\x51\xf1\xde\xf6\x12\xd2\xe4\xd8\x10\xda\xa3\xa0\xcc\x90\x45\x16\xf9\xa4\x3a\xf6\x60\x31\x53\x85\x17\x8a\x52\x9e\x51\xf8\xaa\xe1\x41\x80\x8c\x8b\xc5\xd7\xb6\x0c\xac\x26\xbb\x98\x4a\xc1\x89\x0d\x04\x36\xef\x78\x04\x26\xc5\x47\xe9\x4a\x7b\x08\xf0\x1a\xcb\xfc\x4a\x38\x25\xea\xe0\x4f\x52\x0a\x90\x16\xf2\xfb\x8b\xf5\x16\x5e\xd1\x27\x36\xfc\x71\xe3\x6a\x49\xa7\x36\x14\x73\x9e\xaa\x3e\xc8\x34\x06\x9b\x1b\x40\xf1\x35\x0c\x2b\x3a\xb8\x85\xc0\x2c\x64\x0b\x9f\x76\x86\xed\x5f\x99\x52\x7e\x41\xcf\xcd\x79\x6f\xe4\xc2\x56\xc9\x17\x31\x86\xc2\x26\x16\x9f\xf2\x57\x95\x4e\xbd\xa8\x1c\x0e\x5f\x99",
+       "\xe5\xfc\x73\xc7\x00\x28\xd1\xb8\x2a\x9a\xa9\x76\xd3\x4f\x5f\xc7\x29\x16\x83\x90\x27\x03\x8e\x79\xdf\x2e\x29\x14\x9e\x86\x1f\x09\xa4\x1a\x82\x03\xce\x92\x22\x03\xf7\x10\x96\x4b\x4f\x5b\xec\x2e",
+       239 },
+      { GCRY_MD_SHA3_384,
+       "\x5f\xce\x81\x09\xa3\x58\x57\x0e\x40\x98\x3e\x11\x84\xe5\x41\x83\x3b\xb9\x09\x1e\x28\x0f\x25\x8c\xfb\x14\x43\x87\xb0\x5d\x19\x0e\x43\x1c\xb1\x9b\xaa\x67\x27\x3b\xa0\xc5\x8a\xbe\x91\x30\x8e\x18\x44\xdc\xd0\xb3\x67\x8b\xaa\x42\xf3\x35\xf2\xfa\x05\x26\x7a\x02\x40\xb3\xc7\x18\xa5\x94\x2b\x3b\x3e\x3b\xfa\x98\xa5\x5c\x25\xa1\x46\x6e\x8d\x7a\x60\x37\x22\xcb\x2b\xbf\x03\xaf\xa5\x4c\xd7\x69\xa9\x9f\x31\x07\x35\xee\x5a\x05\xda\xe2\xc2\x2d\x39\x7b\xd9\x56\x35\xf5\x8c\x48\xa6\x7f\x90\xe1\xb7\x3a\xaf\xcd\x3f\x82\x11\x7f\x01\x66\x65\x78\x38\x69\x10\x05\xb1\x8d\xa6\xf3\x41\xd6\xe9\x0f\xc1\xcd\xb3\x52\xb3\x0f\xae\x45\xd3\x48\x29\x4e\x50\x1b\x63\x25\x2d\xe1\x47\x40\xf2\xb8\x5a\xe5\x29\x9d\xde\xc3\x17\x2d\xe8\xb6\xd0\xba\x21\x9a\x20\xa2\x3b\xb5\xe1\x0f\xf4\x34\xd3\x9d\xb3\xf5\x83\x30\x5e\x9f\x5c\x03\x9d\x98\x56\x9e\x37\x7b\x75\xa7\x0a\xb8\x37\xd1\xdf\x26\x9b\x8a\x4b\x56\x6f\x40\xbb\x91\xb5\x77\x45\x5f\xd3\xc3\x56\xc9\x14\xfa\x06\xb9\xa7\xce\x24\xc7\x31\x7a\x17\x2d",
+       "\xb0\xa1\xbb\xa9\x12\xda\xa6\xd8\x0e\xdc\x65\x19\xb5\x01\xb6\x29\x45\x63\x94\xd7\xbd\xa2\x4d\x46\xaf\xc9\xfc\x1d\x93\xa0\xb5\x96\x2f\xa4\xf9\x52\x14\x27\x32\x90\xd3\x2b\x3e\xae\xff\x6f\x9d\xfe",
+       240 },
+      { GCRY_MD_SHA3_384,
+       "\x61\x72\xf1\x97\x1a\x6e\x1e\x4e\x61\x70\xaf\xba\xd9\x5d\x5f\xec\x99\xbf\x69\xb2\x4b\x67\x4b\xc1\x7d\xd7\x80\x11\x61\x5e\x50\x2d\xe6\xf5\x6b\x86\xb1\xa7\x1d\x3f\x43\x48\x08\x72\x18\xac\x7b\x7d\x09\x30\x29\x93\xbe\x27\x2e\x4a\x59\x19\x68\xae\xf1\x8a\x12\x62\xd6\x65\x61\x0d\x10\x70\xee\x91\xcc\x8d\xa3\x6e\x1f\x84\x1a\x69\xa7\xa6\x82\xc5\x80\xe8\x36\x94\x1d\x21\xd9\x09\xa3\xaf\xc1\xf0\xb9\x63\xe1\xca\x5a\xb1\x93\xe1\x24\xa1\xa5\x3d\xf1\xc5\x87\x47\x0e\x58\x81\xfb\x54\xda\xe1\xb0\xd8\x40\xf0\xc8\xf9\xd1\xb0\x4c\x64\x5b\xa1\x04\x1c\x7d\x8d\xbf\x22\x03\x0a\x62\x3a\xa1\x56\x38\xb3\xd9\x9a\x2c\x40\x0f\xf7\x6f\x32\x52\x07\x9a\xf8\x8d\x2b\x37\xf3\x5e\xe6\x6c\x1a\xd7\x80\x1a\x28\xd3\xd3\x88\xac\x45\x0b\x97\xd5\xf0\xf7\x9e\x45\x41\x75\x53\x56\xb3\xb1\xa5\x69\x6b\x02\x3f\x39\xab\x7a\xb5\xf2\x8d\xf4\x20\x29\x36\xbc\x97\x39\x3b\x93\xbc\x91\x5c\xb1\x59\xea\x1b\xd7\xa0\xa4\x14\xcb\x4b\x7a\x1a\xc3\xaf\x68\xf5\x0d\x79\xf0\xc9\xc7\x31\x4e\x75\x0f\x7d\x02\xfa\xa5\x8b\xfa",
+       "\xfc\xe4\x63\x78\x98\xba\x0c\xbd\x9d\x7b\x63\x6f\xeb\xdd\xc0\x2a\x43\x59\x01\xcb\xbe\xf8\xbf\x76\xd3\xe8\x66\xd9\x7d\x55\x35\x4b\x71\xfc\x12\xe6\x7a\x09\xe7\x93\xd7\x49\x31\x6d\x71\x4f\xe0\x8c",
+       241 },
+      { GCRY_MD_SHA3_384,
+       "\x56\x68\xec\xd9\x9d\xfb\xe2\x15\xc4\x11\x83\x98\xac\x9c\x9e\xaf\x1a\x14\x33\xfa\xb4\xcc\xdd\x39\x68\x06\x47\x52\xb6\x25\xea\x94\x47\x31\xf7\x5d\x48\xa2\x7d\x04\x7d\x67\x54\x7f\x14\xdd\x0f\xfa\xa5\x5f\xa5\xe2\x9f\x7a\xf0\xd1\x61\xd8\x5e\xaf\xc4\xf2\x02\x9b\x71\x7c\x91\x8e\xab\x9d\x30\x45\x43\x29\x0b\xdb\xa7\x15\x8b\x68\x02\x0c\x0b\xa4\xe0\x79\xbc\x95\xb5\xbc\x0f\xc0\x44\xa9\x92\xb9\x4b\x4c\xcd\x3b\xd6\x6d\x0e\xab\xb5\xdb\xba\xb9\x04\xd6\x2e\x00\x75\x2c\x4e\x3b\x00\x91\xd7\x73\xbc\xf4\xc1\x4b\x43\x77\xda\x3e\xff\xf8\x24\xb1\xcb\x2f\xa0\x1b\x32\xd1\xe4\x6c\x90\x9e\x62\x6e\xd2\xda\xe9\x20\xf4\xc7\xdb\xeb\x63\x5b\xc7\x54\xfa\xcb\xd8\xd4\x9b\xeb\xa3\xf2\x3c\x1c\x41\xcc\xbf\xcd\x0e\xe0\xc1\x14\xe6\x97\x37\xf5\x59\x7c\x0b\xf1\xd8\x59\xf0\xc7\x67\xe1\x80\x02\xae\x8e\x39\xc2\x62\x61\xff\xde\x29\x20\xd3\xd0\xba\xf0\xe9\x06\x13\x86\x96\xcf\xe5\xb7\xe3\x2b\x60\x0f\x45\xdf\x3a\xaa\x39\x93\x2f\x3a\x7d\xf9\x5b\x60\xfa\x87\x12\xa2\x27\x1f\xca\xf3\x91\x1c\xe7\xb5\x11\xb1",
+       "\x2b\x54\x71\xfa\xe3\x80\x58\x52\xf4\xcf\x39\x54\x1f\x8a\x0a\x37\x74\x81\x8f\x79\xfe\x50\x47\x6e\x22\x5d\x89\xb6\x2e\x43\xbe\x32\x55\xe9\x6d\x19\xcb\xc3\x34\xae\xf0\x41\x92\x84\x0f\x07\x5c\x7d",
+       242 },
+      { GCRY_MD_SHA3_384,
+       "\x03\xd6\x25\x48\x83\x54\xdf\x30\xe3\xf8\x75\xa6\x8e\xdf\xcf\x34\x0e\x83\x66\xa8\xe1\xab\x67\xf9\xd5\xc5\x48\x6a\x96\x82\x9d\xfa\xc0\x57\x82\x89\x08\x2b\x2a\x62\x11\x7e\x1c\xf4\x18\xb4\x3b\x90\xe0\xad\xc8\x81\xfc\x6a\xe8\x10\x5c\x88\x8e\x9e\xcd\x21\xae\xa1\xc9\xae\x1a\x40\x38\xdf\xd1\x73\x78\xfe\xd7\x1d\x02\xae\x49\x20\x87\xd7\xcd\xcd\x98\xf7\x46\x85\x52\x27\x96\x7c\xb1\xab\x47\x14\x26\x1e\xe3\xbe\xad\x3f\x4d\xb1\x18\x32\x9d\x3e\xbe\xf4\xbc\x48\xa8\x75\xc1\x9b\xa7\x63\x96\x6d\xa0\xeb\xea\x80\x0e\x01\xb2\xf5\x0b\x00\xe9\xdd\x4c\xac\xa6\xdc\xb3\x14\xd0\x01\x84\xef\x71\xea\x23\x91\xd7\x60\xc9\x50\x71\x0d\xb4\xa7\x0f\x92\x12\xff\xc5\x48\x61\xf9\xdc\x75\x2c\xe1\x88\x67\xb8\xad\x0c\x48\xdf\x84\x66\xef\x72\x31\xe7\xac\x56\x7f\x0e\xb5\x50\x99\xe6\x22\xeb\xb8\x6c\xb2\x37\x52\x01\x90\xa6\x1c\x66\xad\x34\xf1\xf4\xe2\x89\xcb\x32\x82\xae\x3e\xaa\xc6\x15\x2e\xd2\x4d\x2c\x92\xba\xe5\xa7\x65\x82\x52\xa5\x3c\x49\xb7\xb0\x2d\xfe\x54\xfd\xb2\xe9\x00\x74\xb6\xcf\x31\x0a\xc6\x61",
+       "\xd4\xd3\xb4\x98\x78\xae\xc7\x2e\x2e\x7f\xaf\xb6\x87\xda\x7e\xfe\x24\x2c\xb6\x0a\xdf\x5c\x65\xc5\x77\xc4\x44\xcf\xc9\x5a\x2a\x2e\xc6\x70\x00\x0c\x8a\x78\x89\x8a\x07\x40\x0e\x35\x02\xd7\x3f\x27",
+       243 },
+      { GCRY_MD_SHA3_384,
+       "\x2e\xdc\x28\x2f\xfb\x90\xb9\x71\x18\xdd\x03\xaa\xa0\x3b\x14\x5f\x36\x39\x05\xe3\xcb\xd2\xd5\x0e\xcd\x69\x2b\x37\xbf\x00\x01\x85\xc6\x51\xd3\xe9\x72\x6c\x69\x0d\x37\x73\xec\x1e\x48\x51\x0e\x42\xb1\x77\x42\xb0\xb0\x37\x7e\x7d\xe6\xb8\xf5\x5e\x00\xa8\xa4\xdb\x47\x40\xce\xe6\xdb\x08\x30\x52\x9d\xd1\x96\x17\x50\x1d\xc1\xe9\x35\x9a\xa3\xbc\xf1\x47\xe0\xa7\x6b\x3a\xb7\x0c\x49\x84\xc1\x3e\x33\x9e\x68\x06\xbb\x35\xe6\x83\xaf\x85\x27\x09\x36\x70\x85\x9f\x3d\x8a\x0f\xc7\xd4\x93\xbc\xba\x6b\xb1\x2b\x5f\x65\xe7\x1e\x70\x5c\xa5\xd6\xc9\x48\xd6\x6e\xd3\xd7\x30\xb2\x6d\xb3\x95\xb3\x44\x77\x37\xc2\x6f\xad\x08\x9a\xa0\xad\x0e\x30\x6c\xb2\x8b\xf0\xac\xf1\x06\xf8\x9a\xf3\x74\x5f\x0e\xc7\x2d\x53\x49\x68\xcc\xa5\x43\xcd\x2c\xa5\x0c\x94\xb1\x45\x67\x43\x25\x4e\x35\x8c\x13\x17\xc0\x7a\x07\xbf\x2b\x0e\xca\x43\x8a\x70\x93\x67\xfa\xfc\x89\xa5\x72\x39\x02\x8f\xc5\xfe\xcf\xd5\x3b\x8e\xf9\x58\xef\x10\xee\x06\x08\xb7\xf5\xcb\x99\x23\xad\x97\x05\x8e\xc0\x67\x70\x0c\xc7\x46\xc1\x27\xa6\x1e\xe3",
+       "\xfe\x1c\x21\x43\xf2\x95\x78\x19\xdf\x9c\x9d\xd0\x5d\x00\x4b\xe0\xe5\x57\xee\xd8\xc5\xa2\xb7\xce\x45\x7d\x58\x56\x13\x2b\x1c\x43\xee\xce\xc3\x6a\xd7\x04\xa9\x30\xa8\x54\x85\xa3\x4c\x38\x60\xfe",
+       244 },
+      { GCRY_MD_SHA3_384,
+       "\x90\xb2\x8a\x6a\xa1\xfe\x53\x39\x15\xbc\xb8\xe8\x1e\xd6\xca\xcd\xc1\x09\x62\xb7\xff\x82\x47\x4f\x84\x5e\xeb\x86\x97\x76\x00\xcf\x70\xb0\x7b\xa8\xe3\x79\x61\x41\xee\x34\x0e\x3f\xce\x84\x2a\x38\xa5\x0a\xfb\xe9\x03\x01\xa3\xbd\xcc\x59\x1f\x2e\x7d\x9d\xe5\x3e\x49\x55\x25\x56\x0b\x90\x8c\x89\x24\x39\x99\x0a\x2c\xa2\x67\x9c\x55\x39\xff\xdf\x63\x67\x77\xad\x9c\x1c\xde\xf8\x09\xcd\xa9\xe8\xdc\xdb\x45\x1a\xbb\x9e\x9c\x17\xef\xa4\x37\x9a\xbd\x24\xb1\x82\xbd\x98\x1c\xaf\xc7\x92\x64\x0a\x18\x3b\x61\x69\x43\x01\xd0\x4c\x5b\x3e\xaa\xd6\x94\xa6\xbd\x4c\xc0\x6e\xf5\xda\x8f\xa2\x3b\x4f\xa2\xa6\x45\x59\xc5\xa6\x83\x97\x93\x00\x79\xd2\x50\xc5\x1b\xcf\x00\xe2\xb1\x6a\x6c\x49\x17\x14\x33\xb0\xaa\xdf\xd8\x02\x31\x27\x65\x60\xb8\x04\x58\xdd\x77\x08\x9b\x7a\x1b\xbc\xc9\xe7\xe4\xb9\xf8\x81\xea\xcd\x6c\x92\xc4\x31\x83\x48\xa1\x3f\x49\x14\xeb\x27\x11\x5a\x1c\xfc\x5d\x16\xd7\xfd\x94\x95\x4c\x35\x32\xef\xac\xa2\xca\xb0\x25\x10\x3b\x2d\x02\xc6\xfd\x71\xda\x3a\x77\xf4\x17\xd7\x93\x26\x85\x88\x8a",
+       "\x4d\x1f\x62\x66\x88\xe6\x89\x9b\x5f\xcc\xd4\x7f\xaa\xb4\x5e\x96\xc6\x1e\x16\x98\x69\xca\xbe\xf4\x02\x83\xb2\x41\x8d\xfb\x28\x88\xfb\x80\xcc\x9f\x2c\x52\x64\x97\xc5\x0c\x52\x44\x78\x4f\x19\x5c",
+       245 },
+      { GCRY_MD_SHA3_384,
+       "\x29\x69\x44\x7d\x17\x54\x90\xf2\xaa\x9b\xb0\x55\x01\x4d\xbe\xf2\xe6\x85\x4c\x95\xf8\xd6\x09\x50\xbf\xe8\xc0\xbe\x8d\xe2\x54\xc2\x6b\x2d\x31\xb9\xe4\xde\x9c\x68\xc9\xad\xf4\x9e\x4e\xe9\xb1\xc2\x85\x09\x67\xf2\x9f\x5d\x08\x73\x84\x83\xb4\x17\xbb\x96\xb2\xa5\x6f\x0c\x8a\xca\x63\x2b\x55\x20\x59\xc5\x9a\xac\x3f\x61\xf7\xb4\x5c\x96\x6b\x75\xf1\xd9\x93\x1f\xf4\xe5\x96\x40\x63\x78\xce\xe9\x1a\xaa\x72\x6a\x3a\x84\xc3\x3f\x37\xe9\xcd\xbe\x62\x6b\x57\x45\xa0\xb0\x60\x64\xa8\xa8\xd5\x6e\x53\xaa\xf1\x02\xd2\x3d\xd9\xdf\x0a\x3f\xdf\x7a\x63\x85\x09\xa6\x76\x1a\x33\xfa\x42\xfa\x8d\xdb\xd8\xe1\x61\x59\xc9\x30\x08\xb5\x37\x65\x01\x9c\x3f\x0e\x9f\x10\xb1\x44\xce\x2a\xc5\x7f\x5d\x72\x97\xf9\xc9\x94\x9e\x4f\xf6\x8b\x70\xd3\x39\xf8\x75\x01\xce\x85\x50\xb7\x72\xf3\x2c\x6d\xa8\xad\x2c\xe2\x10\x0a\x89\x5d\x8b\x08\xfa\x1e\xea\xd7\xc3\x76\xb4\x07\x70\x97\x03\xc5\x10\xb5\x0f\x87\xe7\x3e\x43\xf8\xe7\x34\x8f\x87\xc3\x83\x2a\x54\x7e\xf2\xbb\xe5\x79\x9a\xbe\xdc\xf5\xe1\xf3\x72\xea\x80\x92\x33\xf0\x06",
+       "\xa0\x63\xd7\x78\xb0\xa2\xa1\x1d\x3a\x9c\xba\x42\x5e\xe5\x93\x8f\xca\xa6\xe2\xbf\x1f\x30\xa6\x65\xfa\x81\x16\x01\x44\x4d\x57\x49\xaf\xa1\x87\x66\xdb\x5f\x04\x26\xc5\xb8\x39\x22\x38\xb7\x86\x2e",
+       246 },
+      { GCRY_MD_SHA3_384,
+       "\x72\x16\x45\x63\x3a\x44\xa2\xc7\x8b\x19\x02\x4e\xae\xcf\x58\x57\x5a\xb2\x3c\x27\x19\x08\x33\xc2\x68\x75\xdc\x0f\x0d\x50\xb4\x6a\xea\x9c\x34\x3d\x82\xea\x7d\x5b\x3e\x50\xec\x70\x05\x45\xc6\x15\xda\xea\xea\x64\x72\x6a\x0f\x05\x60\x75\x76\xdc\xd3\x96\xd8\x12\xb0\x3f\xb6\x55\x1c\x64\x10\x87\x85\x6d\x05\x0b\x10\xe6\xa4\xd5\x57\x7b\x82\xa9\x8a\xfb\x89\xce\xe8\x59\x4c\x9d\xc1\x9e\x79\xfe\xff\x03\x82\xfc\xfd\x12\x7f\x1b\x80\x3a\x4b\x99\x46\xf4\xac\x9a\x43\x78\xe1\xe6\xe0\x41\xb1\x38\x9a\x53\xe3\x45\x0c\xd3\x2d\x9d\x29\x41\xb0\xcb\xab\xdb\x50\xda\x8e\xa2\x51\x31\x45\x16\x4c\x3a\xb6\xbc\xbd\x25\x1c\x44\x8d\x2d\x4b\x08\x7a\xc5\x7a\x59\xc2\x28\x5d\x56\x4f\x16\xda\x4e\xd5\xe6\x07\xed\x97\x95\x92\x14\x6f\xfb\x0e\xf3\xf3\xdb\x30\x8f\xb3\x42\xdf\x5e\xb5\x92\x4a\x48\x25\x6f\xc7\x63\x14\x1a\x27\x88\x14\xc8\x2d\x6d\x63\x48\x57\x75\x45\x87\x0a\xe3\xa8\x3c\x72\x30\xac\x02\xa1\x54\x0f\xe1\x79\x8f\x7e\xf0\x9e\x33\x5a\x86\x5a\x2a\xe0\x94\x9b\x21\xe4\xf7\x48\xfb\x8a\x51\xf4\x47\x50\xe2\x13\xa8\xfb",
+       "\x47\x0e\xe6\xd3\x51\x57\x84\x68\x90\xa0\x1b\x38\x09\xeb\x92\x3c\xc4\x5d\xff\xf2\xfc\xa2\x82\x6f\x45\x83\x25\x46\x6c\x98\x3b\x1c\x64\xbe\xa3\x8b\xca\xec\xa9\x21\xc9\x0d\xd0\x04\x32\xec\xcf\x89",
+       247 },
+      { GCRY_MD_SHA3_384,
+       "\x6b\x86\x0d\x39\x72\x5a\x14\xb4\x98\xbb\x71\x45\x74\xb4\xd3\x7c\xa7\x87\x40\x47\x68\xf6\x4c\x64\x8b\x17\x51\xb3\x53\xac\x92\xba\xc2\xc3\xa2\x8e\xa9\x09\xfd\xf0\x42\x33\x36\x40\x1a\x02\xe6\x3e\xc2\x43\x25\x30\x0d\x82\x3b\x68\x64\xbb\x70\x1f\x9d\x7c\x7a\x1f\x8e\xc9\xd0\xae\x35\x84\xaa\x6d\xd6\x2e\xa1\x99\x7c\xd8\x31\xb4\xba\xbd\x9a\x4d\xa5\x09\x32\xd4\xef\xda\x74\x5c\x61\xe4\x13\x08\x90\xe1\x56\xae\xe6\x11\x37\x16\xda\xf9\x57\x64\x22\x2a\x91\x18\x7d\xb2\xef\xfe\xa4\x9d\x5d\x05\x96\x10\x2d\x61\x9b\xd2\x6a\x61\x6b\xbf\xda\x83\x35\x50\x5f\xbb\x0d\x90\xb4\xc1\x80\xd1\xa2\x33\x5b\x91\x53\x8e\x16\x68\xf9\xf9\x64\x27\x90\xb4\xe5\x5f\x9c\xab\x0f\xe2\xbd\xd2\x93\x5d\x00\x1e\xe6\x41\x9a\xba\xb5\x45\x78\x80\xd0\xdb\xff\x20\xed\x87\x58\xf4\xc2\x0f\xe7\x59\xef\xb3\x31\x41\xcf\x0e\x89\x25\x87\xfe\x81\x87\xe5\xfb\xc5\x77\x86\xb7\xe8\xb0\x89\x61\x2c\x93\x6d\xfc\x03\xd2\x7e\xfb\xbe\x7c\x86\x73\xf1\x60\x6b\xd5\x1d\x5f\xf3\x86\xf4\xa7\xab\x68\xed\xf5\x9f\x38\x5e\xb1\x29\x1f\x11\x7b\xfe\x71\x73\x99",
+       "\xa8\xf0\xa3\xc8\x9c\xf7\xe5\x6a\xcc\x18\xac\xe1\x63\x8b\xcf\x13\x30\x94\xfd\x9f\x75\xf0\x56\x77\xc3\xcd\x0e\xd3\x61\x4a\x59\x3c\xbc\xeb\x09\xc7\x8c\x86\xe3\x50\xfd\x07\xff\x44\x29\xa6\xa1\x65",
+       248 },
+      { GCRY_MD_SHA3_384,
+       "\x6a\x01\x83\x0a\xf3\x88\x9a\x25\x18\x32\x44\xde\xcb\x50\x8b\xd0\x12\x53\xd5\xb5\x08\xab\x49\x0d\x31\x24\xaf\xbf\x42\x62\x6b\x2e\x70\x89\x4e\x9b\x56\x2b\x28\x8d\x0a\x24\x50\xcf\xac\xf1\x4a\x0d\xda\xe5\xc0\x47\x16\xe5\xa0\x08\x2c\x33\x98\x1f\x60\x37\xd2\x3d\x5e\x04\x5e\xe1\xef\x22\x83\xfb\x8b\x63\x78\xa9\x14\xc5\xd9\x44\x16\x27\xa7\x22\xc2\x82\xff\x45\x2e\x25\xa7\xea\x60\x8d\x69\xce\xe4\x39\x3a\x07\x25\xd1\x79\x63\xd0\x34\x26\x84\xf2\x55\x49\x6d\x8a\x18\xc2\x96\x11\x45\x31\x51\x30\x54\x93\x11\xfc\x07\xf0\x31\x2f\xb7\x8e\x60\x77\x33\x4f\x87\xea\xa8\x73\xbe\xe8\xaa\x95\x69\x89\x96\xeb\x21\x37\x5e\xb2\xb4\xef\x53\xc1\x44\x01\x20\x7d\xeb\x45\x68\x39\x8e\x5d\xd9\xa7\xcf\x97\xe8\xc9\x66\x3e\x23\x33\x4b\x46\x91\x2f\x83\x44\xc1\x9e\xfc\xf8\xc2\xba\x6f\x04\x32\x5f\x1a\x27\xe0\x62\xb6\x2a\x58\xd0\x76\x6f\xc6\xdb\x4d\x2c\x6a\x19\x28\x60\x4b\x01\x75\xd8\x72\xd1\x6b\x79\x08\xeb\xc0\x41\x76\x11\x87\xcc\x78\x55\x26\xc2\xa3\x87\x3f\xea\xc3\xa6\x42\xbb\x39\xf5\x35\x15\x50\xaf\x97\x70\xc3\x28\xaf\x7b",
+       "\xc8\xa9\xa2\x44\x64\xf2\x1b\x13\x3e\xbe\x20\xba\x42\x1a\x81\xee\x34\xdc\xea\xcd\x5f\x04\xdc\xfb\x66\xd2\x19\xf7\xf4\x14\x56\x33\x69\x2c\x57\x2b\x63\x00\x78\x34\xa4\x06\xec\xfb\x93\x8a\x14\xf6",
+       249 },
+      { GCRY_MD_SHA3_384,
+       "\xb3\xc5\xe7\x4b\x69\x93\x3c\x25\x33\x10\x6c\x56\x3b\x4c\xa2\x02\x38\xf2\xb6\xe6\x75\xe8\x68\x1e\x34\xa3\x89\x89\x47\x85\xbd\xad\xe5\x96\x52\xd4\xa7\x3d\x80\xa5\xc8\x5b\xd4\x54\xfd\x1e\x9f\xfd\xad\x1c\x38\x15\xf5\x03\x8e\x9e\xf4\x32\xaa\xc5\xc3\xc4\xfe\x84\x0c\xc3\x70\xcf\x86\x58\x0a\x60\x11\x77\x8b\xbe\xda\xf5\x11\xa5\x1b\x56\xd1\xa2\xeb\x68\x39\x4a\xa2\x99\xe2\x6d\xa9\xad\xa6\xa2\xf3\x9b\x9f\xaf\xf7\xfb\xa4\x57\x68\x9b\x9c\x1a\x57\x7b\x2a\x1e\x50\x5f\xdf\x75\xc7\xa0\xa6\x4b\x1d\xf8\x1b\x3a\x35\x60\x01\xbf\x0d\xf4\xe0\x2a\x1f\xc5\x9f\x65\x1c\x9d\x58\x5e\xc6\x22\x4b\xb2\x79\xc6\xbe\xba\x29\x66\xe8\x88\x2d\x68\x37\x60\x81\xb9\x87\x46\x8e\x7a\xed\x1e\xf9\x0e\xbd\x09\x0a\xe8\x25\x79\x5c\xdc\xa1\xb4\xf0\x9a\x97\x9c\x8d\xfc\x21\xa4\x8d\x8a\x53\xcd\xbb\x26\xc4\xdb\x54\x7f\xc0\x6e\xfe\x2f\x98\x50\xed\xd2\x68\x5a\x46\x61\xcb\x49\x11\xf1\x65\xd4\xb6\x3e\xf2\x5b\x87\xd0\xa9\x6d\x3d\xff\x6a\xb0\x75\x89\x99\xaa\xd2\x14\xd0\x7b\xd4\xf1\x33\xa6\x73\x4f\xde\x44\x5f\xe4\x74\x71\x1b\x69\xa9\x8f\x7e\x2b",
+       "\x91\xba\xda\x31\xb5\x7a\x4b\xf3\xd2\xeb\x19\xa3\x4f\xf9\x21\xdb\x10\xbd\x64\x06\x19\x14\x86\xd2\x5d\x5c\xa4\xde\x5e\x00\xb5\xe2\x81\x5d\xae\x74\x10\x64\xe5\xb8\x77\xac\x57\x51\x1b\x94\x9f\x91",
+       250 },
+      { GCRY_MD_SHA3_384,
+       "\x83\xaf\x34\x27\x9c\xcb\x54\x30\xfe\xbe\xc0\x7a\x81\x95\x0d\x30\xf4\xb6\x6f\x48\x48\x26\xaf\xee\x74\x56\xf0\x07\x1a\x51\xe1\xbb\xc5\x55\x70\xb5\xcc\x7e\xc6\xf9\x30\x9c\x17\xbf\x5b\xef\xdd\x7c\x6b\xa6\xe9\x68\xcf\x21\x8a\x2b\x34\xbd\x5c\xf9\x27\xab\x84\x6e\x38\xa4\x0b\xbd\x81\x75\x9e\x9e\x33\x38\x10\x16\xa7\x55\xf6\x99\xdf\x35\xd6\x60\x00\x7b\x5e\xad\xf2\x92\xfe\xef\xb7\x35\x20\x7e\xbf\x70\xb5\xbd\x17\x83\x4f\x7b\xfa\x0e\x16\xcb\x21\x9a\xd4\xaf\x52\x4a\xb1\xea\x37\x33\x4a\xa6\x64\x35\xe5\xd3\x97\xfc\x0a\x06\x5c\x41\x1e\xbb\xce\x32\xc2\x40\xb9\x04\x76\xd3\x07\xce\x80\x2e\xc8\x2c\x1c\x49\xbc\x1b\xec\x48\xc0\x67\x5e\xc2\xa6\xc6\xf3\xed\x3e\x5b\x74\x1d\x13\x43\x70\x95\x70\x7c\x56\x5e\x10\xd8\xa2\x0b\x8c\x20\x46\x8f\xf9\x51\x4f\xcf\x31\xb4\x24\x9c\xd8\x2d\xce\xe5\x8c\x0a\x2a\xf5\x38\xb2\x91\xa8\x7e\x33\x90\xd7\x37\x19\x1a\x07\x48\x4a\x5d\x3f\x3f\xb8\xc8\xf1\x5c\xe0\x56\xe5\xe5\xf8\xfe\xbe\x5e\x1f\xb5\x9d\x67\x40\x98\x0a\xa0\x6c\xa8\xa0\xc2\x0f\x57\x12\xb4\xcd\xe5\xd0\x32\xe9\x2a\xb8\x9f\x0a\xe1",
+       "\xf3\x10\xe8\x09\x51\xc7\xbb\x63\x95\xca\x16\x8a\xae\x7e\xc4\x2d\xef\xf6\xc4\xcd\x3f\x5b\xe9\xc8\xb4\x9b\x85\xb4\x05\xf7\x31\x91\x1a\xe8\x26\x7f\xfe\xbd\x54\x3d\xbd\xf4\x09\xec\x20\xa8\x58\xd2",
+       251 },
+      { GCRY_MD_SHA3_384,
+       "\xa7\xed\x84\x74\x9c\xcc\x56\xbb\x1d\xfb\xa5\x71\x19\xd2\x79\xd4\x12\xb8\xa9\x86\x88\x6d\x81\x0f\x06\x7a\xf3\x49\xe8\x74\x9e\x9e\xa7\x46\xa6\x0b\x03\x74\x26\x36\xc4\x64\xfc\x1e\xe2\x33\xac\xc5\x2c\x19\x83\x91\x46\x92\xb6\x43\x09\xed\xfd\xf2\x9f\x1a\xb9\x12\xec\x3e\x8d\xa0\x74\xd3\xf1\xd2\x31\x51\x1f\x57\x56\xf0\xb6\xee\xad\x3e\x89\xa6\xa8\x8f\xe3\x30\xa1\x0f\xac\xe2\x67\xbf\xfb\xfc\x3e\x30\x90\xc7\xfd\x9a\x85\x05\x61\xf3\x63\xad\x75\xea\x88\x1e\x72\x44\xf8\x0f\xf5\x58\x02\xd5\xef\x7a\x1a\x4e\x7b\x89\xfc\xfa\x80\xf1\x6d\xf5\x4d\x1b\x05\x6e\xe6\x37\xe6\x96\x4b\x9e\x0f\xfd\x15\xb6\x19\x6b\xdd\x7d\xb2\x70\xc5\x6b\x47\x25\x14\x85\x34\x8e\x49\x81\x3b\x4e\xb9\xed\x12\x2a\x01\xb3\xea\x45\xad\x5e\x1a\x92\x9d\xf6\x1d\x5c\x0f\x3e\x77\xe1\xfd\xc3\x56\xb6\x38\x83\xa6\x0e\x9c\xbb\x9f\xc3\xe0\x0c\x2f\x32\xdb\xd4\x69\x65\x98\x83\xf6\x90\xc6\x77\x2e\x33\x5f\x61\x7b\xc3\x3f\x16\x1d\x6f\x69\x84\x25\x2e\xe1\x2e\x62\xb6\x00\x0a\xc5\x23\x1e\x0c\x9b\xc6\x5b\xe2\x23\xd8\xdf\xd9\x4c\x50\x04\xa1\x01\xaf\x9f\xd6\xc0\xfb",
+       "\xcf\xd0\x5e\x08\x09\x94\xfc\x6d\x7a\xef\x2d\x8c\x6e\x44\xd8\xa5\xe9\x0f\x5a\x23\x16\x76\xe0\xfa\xe0\xd2\xb8\xce\x16\x2c\xa9\xd0\x67\x12\x58\x0c\x99\x99\x7a\x77\x09\xa0\x61\x80\xdd\x42\xfb\x91",
+       252 },
+      { GCRY_MD_SHA3_384,
+       "\xa6\xfe\x30\xdc\xfc\xda\x1a\x32\x9e\x82\xab\x50\xe3\x2b\x5f\x50\xeb\x25\xc8\x73\xc5\xd2\x30\x58\x60\xa8\x35\xae\xce\xe6\x26\x4a\xa3\x6a\x47\x42\x99\x22\xc4\xb8\xb3\xaf\xd0\x0d\xa1\x60\x35\x83\x0e\xdb\x89\x78\x31\xc4\xe7\xb0\x0f\x2c\x23\xfc\x0b\x15\xfd\xc3\x0d\x85\xfb\x70\xc3\x0c\x43\x1c\x63\x8e\x1a\x25\xb5\x1c\xaf\x1d\x7e\x8b\x05\x0b\x7f\x89\xbf\xb3\x0f\x59\xf0\xf2\x0f\xec\xff\x3d\x63\x9a\xbc\x42\x55\xb3\x86\x8f\xc4\x5d\xd8\x1e\x47\xeb\x12\xab\x40\xf2\xaa\xc7\x35\xdf\x5d\x1d\xc1\xad\x99\x7c\xef\xc4\xd8\x36\xb8\x54\xce\xe9\xac\x02\x90\x00\x36\xf3\x86\x7f\xe0\xd8\x4a\xff\xf3\x7b\xde\x33\x08\xc2\x20\x6c\x62\xc4\x74\x33\x75\x09\x41\x08\x87\x7c\x73\xb8\x7b\x25\x46\xfe\x05\xea\x13\x7b\xed\xfc\x06\xa2\x79\x62\x74\x09\x9a\x0d\x55\x4d\xa8\xf7\xd7\x22\x3a\x48\xcb\xf3\x1b\x7d\xec\xaa\x1e\xbc\x8b\x14\x57\x63\xe3\x67\x31\x68\xc1\xb1\xb7\x15\xc1\xcd\x99\xec\xd3\xdd\xb2\x38\xb0\x60\x49\x88\x5e\xca\xd9\x34\x7c\x24\x36\xdf\xf3\x2c\x77\x1f\x34\xa3\x85\x87\xa4\x4a\x82\xc5\xd3\xd1\x37\xa0\x3c\xaa\x27\xe6\x6c\x8f\xf6",
+       "\x8f\xa2\x6d\xd5\xa5\x4b\xf9\x4a\x03\x7a\x16\x5e\xc5\xce\x3e\xd8\x61\x47\xa0\x8d\xcf\xe3\xb4\x88\x18\xb0\xc0\xbe\xee\xfa\x33\xb1\x45\x32\x3b\x59\x8f\x76\x1d\xe2\xb6\x39\xd0\x51\x27\xf1\xcf\x3e",
+       253 },
+      { GCRY_MD_SHA3_384,
+       "\x83\x16\x7f\xf5\x37\x04\xc3\xaa\x19\xe9\xfb\x33\x03\x53\x97\x59\xc4\x6d\xd4\x09\x1a\x52\xdd\xae\x9a\xd8\x64\x08\xb6\x93\x35\x98\x9e\x61\x41\x4b\xc2\x0a\xb4\xd0\x12\x20\xe3\x52\x41\xef\xf5\xc9\x52\x2b\x07\x9f\xba\x59\x76\x74\xc8\xd7\x16\xfe\x44\x1e\x56\x61\x10\xb6\x21\x15\x31\xce\xcc\xf8\xfd\x06\xbc\x8e\x51\x1d\x00\x78\x5e\x57\x78\x8e\xd9\xa1\xc5\xc7\x35\x24\xf0\x18\x30\xd2\xe1\x14\x8c\x92\xd0\xed\xc9\x71\x13\xe3\xb7\xb5\xcd\x30\x49\x62\x7a\xbd\xb8\xb3\x9d\xd4\xd6\x89\x0e\x0e\xe9\x19\x93\xf9\x2b\x03\x35\x4a\x88\xf5\x22\x51\xc5\x46\xe6\x44\x34\xd9\xc3\xd7\x45\x44\xf2\x3f\xb9\x3e\x5a\x2d\x2f\x1f\xb1\x55\x45\xb4\xe1\x36\x7c\x97\x33\x5b\x02\x91\x94\x4c\x8b\x73\x0a\xd3\xd4\x78\x92\x73\xfa\x44\xfb\x98\xd7\x8a\x36\xc3\xc3\x76\x4a\xbe\xea\xc7\xc5\x69\xc1\xe4\x3a\x35\x2e\x5b\x77\x0c\x35\x04\xf8\x70\x90\xde\xe0\x75\xa1\xc4\xc8\x5c\x0c\x39\xcf\x42\x1b\xdc\xc6\x15\xf9\xef\xf6\xcb\x4f\xe6\x46\x80\x04\xae\xce\x5f\x30\xe1\xec\xc6\xdb\x22\xad\x99\x39\xbb\x2b\x0c\xcc\x96\x52\x1d\xfb\xf4\xae\x00\x8b\x5b\x46\xbc\x00\x6e",
+       "\x28\x3f\xd6\x1d\x1e\x50\x57\x2e\xf4\x03\xbf\x9c\x55\x4d\x76\xd6\x94\xa5\x4f\x90\x2c\x49\x79\x5d\x1c\xf5\x06\xf0\xee\x26\x3e\x7b\xa9\x94\xf7\x2b\xdc\x47\x32\x53\x1f\xa7\x19\x42\x57\xf2\xdf\xda",
+       254 },
+      { GCRY_MD_SHA3_384,
+       "\x3a\x3a\x81\x9c\x48\xef\xde\x2a\xd9\x14\xfb\xf0\x0e\x18\xab\x6b\xc4\xf1\x45\x13\xab\x27\xd0\xc1\x78\xa1\x88\xb6\x14\x31\xe7\xf5\x62\x3c\xb6\x6b\x23\x34\x67\x75\xd3\x86\xb5\x0e\x98\x2c\x49\x3a\xdb\xbf\xc5\x4b\x9a\x3c\xd3\x83\x38\x23\x36\xa1\xa0\xb2\x15\x0a\x15\x35\x8f\x33\x6d\x03\xae\x18\xf6\x66\xc7\x57\x3d\x55\xc4\xfd\x18\x1c\x29\xe6\xcc\xfd\xe6\x3e\xa3\x5f\x0a\xdf\x58\x85\xcf\xc0\xa3\xd8\x4a\x2b\x2e\x4d\xd2\x44\x96\xdb\x78\x9e\x66\x31\x70\xce\xf7\x47\x98\xaa\x1b\xbc\xd4\x57\x4e\xa0\xbb\xa4\x04\x89\xd7\x64\xb2\xf8\x3a\xad\xc6\x6b\x14\x8b\x4a\x0c\xd9\x52\x46\xc1\x27\xd5\x87\x1c\x4f\x11\x41\x86\x90\xa5\xdd\xf0\x12\x46\xa0\xc8\x0a\x43\xc7\x00\x88\xb6\x18\x36\x39\xdc\xfd\xa4\x12\x5b\xd1\x13\xa8\xf4\x9e\xe2\x3e\xd3\x06\xfa\xac\x57\x6c\x3f\xb0\xc1\xe2\x56\x67\x1d\x81\x7f\xc2\x53\x4a\x52\xf5\xb4\x39\xf7\x2e\x42\x4d\xe3\x76\xf4\xc5\x65\xcc\xa8\x23\x07\xdd\x9e\xf7\x6d\xa5\xb7\xc4\xeb\x7e\x08\x51\x72\xe3\x28\x80\x7c\x02\xd0\x11\xff\xbf\x33\x78\x53\x78\xd7\x9d\xc2\x66\xf6\xa5\xbe\x6b\xb0\xe4\xa9\x2e\xce\xeb\xae\xb1",
+       "\x12\x8d\xc6\x11\x76\x2b\xe9\xb1\x35\xb3\x73\x94\x84\xcf\xaa\xdc\xa7\x48\x1d\x68\x51\x4f\x3d\xfd\x6f\x5d\x78\xbb\x18\x63\xae\x68\x13\x08\x35\xcd\xc7\x06\x1a\x7e\xd9\x64\xb3\x2f\x1d\xb7\x5e\xe1",
+       255 },
diff --git a/tests/sha3-512.h b/tests/sha3-512.h
new file mode 100644 (file)
index 0000000..b91e7b2
--- /dev/null
@@ -0,0 +1,1025 @@
+/* Generated from https://raw.githubusercontent.com/gvanas/KeccakCodePackage/master/TestVectors/ShortMsgKAT_SHA3-512.txt */
+      { GCRY_MD_SHA3_512,
+       "",
+       "\xa6\x9f\x73\xcc\xa2\x3a\x9a\xc5\xc8\xb5\x67\xdc\x18\x5a\x75\x6e\x97\xc9\x82\x16\x4f\xe2\x58\x59\xe0\xd1\xdc\xc1\x47\x5c\x80\xa6\x15\xb2\x12\x3a\xf1\xf5\xf9\x4c\x11\xe3\xe9\x40\x2c\x3a\xc5\x58\xf5\x00\x19\x9d\x95\xb6\xd3\xe3\x01\x75\x85\x86\x28\x1d\xcd\x26",
+       0 },
+      { GCRY_MD_SHA3_512,
+       "\xcc",
+       "\x39\x39\xfc\xc8\xb5\x7b\x63\x61\x25\x42\xda\x31\xa8\x34\xe5\xdc\xc3\x6e\x2e\xe0\xf6\x52\xac\x72\xe0\x26\x24\xfa\x2e\x5a\xde\xec\xc7\xdd\x6b\xb3\x58\x02\x24\xb4\xd6\x13\x87\x06\xfc\x6e\x80\x59\x7b\x52\x80\x51\x23\x0b\x00\x62\x1c\xc2\xb2\x29\x99\xea\xa2\x05",
+       1 },
+      { GCRY_MD_SHA3_512,
+       "\x41\xfb",
+       "\xaa\x09\x28\x65\xa4\x06\x94\xd9\x17\x54\xdb\xc7\x67\xb5\x20\x2c\x54\x6e\x22\x68\x77\x14\x7a\x95\xcb\x8b\x4c\x8f\x87\x09\xfe\x8c\xd6\x90\x52\x56\xb0\x89\xda\x37\x89\x6e\xa5\xca\x19\xd2\xcd\x9a\xb9\x4c\x71\x92\xfc\x39\xf7\xcd\x4d\x59\x89\x75\xa3\x01\x3c\x69",
+       2 },
+      { GCRY_MD_SHA3_512,
+       "\x1f\x87\x7c",
+       "\xcb\x20\xdc\xf5\x49\x55\xf8\x09\x11\x11\x68\x8b\xec\xce\xf4\x8c\x1a\x2f\x0d\x06\x08\xc3\xa5\x75\x16\x37\x51\xf0\x02\xdb\x30\xf4\x0f\x2f\x67\x18\x34\xb2\x2d\x20\x85\x91\xcf\xaf\x1f\x5e\xcf\xe4\x3c\x49\x86\x3a\x53\xb3\x22\x5b\xdf\xd7\xc6\x59\x1b\xa7\x65\x8b",
+       3 },
+      { GCRY_MD_SHA3_512,
+       "\xc1\xec\xfd\xfc",
+       "\xd4\xb4\xbd\xfe\xf5\x6b\x82\x1d\x36\xf4\xf7\x0a\xb0\xd2\x31\xb8\xd0\xc9\x13\x46\x38\xfd\x54\xc4\x63\x09\xd1\x4f\xad\xa9\x2a\x28\x40\x18\x6e\xed\x54\x15\xad\x7c\xf3\x96\x9b\xdf\xbf\x2d\xaf\x8c\xca\x76\xab\xfe\x54\x9b\xe6\x57\x8c\x6f\x41\x43\x61\x7a\x4f\x1a",
+       4 },
+      { GCRY_MD_SHA3_512,
+       "\x21\xf1\x34\xac\x57",
+       "\x58\x42\x19\xa8\x4e\x87\x96\x07\x6b\xf1\x17\x8b\x14\xb9\xd1\xe2\xf9\x6a\x4b\x4e\xf1\x1f\x10\xcc\x51\x6f\xbe\x1a\x29\x63\x9d\x6b\xa7\x4f\xb9\x28\x15\xf9\xe3\xc5\x19\x2e\xd4\xdc\xa2\x0a\xea\x5b\x10\x9d\x52\x23\x7c\x99\x56\x40\x1f\xd4\x4b\x22\x1f\x82\xab\x37",
+       5 },
+      { GCRY_MD_SHA3_512,
+       "\xc6\xf5\x0b\xb7\x4e\x29",
+       "\x43\x45\xb9\x2a\x2a\xb7\xea\xdb\x6a\x24\xee\x1d\x17\x5a\xc2\x58\xcc\xf2\xf6\x94\xac\x09\xec\x9d\x47\x39\x9e\x4d\x96\xf6\x1f\x30\xb3\x22\xc5\x43\x8c\x51\xba\xcd\x0d\x59\x7d\x00\x47\x1a\x41\xed\x8e\x9c\x9f\x14\x6b\xbc\x80\x7e\x6b\xc3\x85\xf8\x50\xfb\xab\xfe",
+       6 },
+      { GCRY_MD_SHA3_512,
+       "\x11\x97\x13\xcc\x83\xee\xef",
+       "\x50\x08\x1c\x93\xbf\x73\xec\xc5\x4a\x5f\xfe\x43\xfc\x14\xf8\xba\xee\xdb\xe7\xda\x03\x02\xac\x98\x4c\x9e\x66\x83\x89\x88\x6b\xd0\x64\xba\xb2\x6d\xdc\xb6\x16\xeb\x4e\x0e\x72\x60\x42\xb1\x9f\x3f\xd5\x0b\xdd\x0d\x2c\x5b\x34\x89\x2e\x00\xe6\xf3\x99\xde\x25\x4f",
+       7 },
+      { GCRY_MD_SHA3_512,
+       "\x4a\x4f\x20\x24\x84\x51\x25\x26",
+       "\x15\x0d\x78\x7d\x6e\xb4\x96\x70\xc2\xa4\xcc\xd1\x7e\x6c\xce\x7a\x04\xc1\xfe\x30\xfc\xe0\x3d\x1e\xf2\x50\x17\x52\xd9\x2a\xe0\x4c\xb3\x45\xfd\x42\xe5\x10\x38\xc8\x3b\x2b\x4f\x8f\xd4\x38\xd1\xb4\xb5\x5c\xc5\x88\xc6\xb9\x13\x13\x2f\x1a\x65\x8f\xb1\x22\xcb\x52",
+       8 },
+      { GCRY_MD_SHA3_512,
+       "\x1f\x66\xab\x41\x85\xed\x9b\x63\x75",
+       "\xa1\x3c\x95\x1c\x6c\x51\xf2\x36\xa0\x19\x7a\x29\xa8\x99\x4b\x1c\x72\x94\xe1\x7b\xa5\x18\xed\x10\x29\xd6\xf5\x4a\xd7\x39\xd8\x76\x59\x20\x28\x1b\xbb\x85\x4d\x16\xfb\xb6\x0e\x03\x85\xaf\xd6\xe6\xe4\x33\xe6\x3a\xaa\x77\xe7\x3b\x8b\xee\x7f\xde\x56\x9d\x68\x75",
+       9 },
+      { GCRY_MD_SHA3_512,
+       "\xee\xd7\x42\x22\x27\x61\x3b\x6f\x53\xc9",
+       "\x5a\x56\x6f\xb1\x81\xbe\x53\xa4\x10\x92\x75\x53\x7d\x80\xe5\xfd\x0f\x31\x4d\x68\x88\x45\x29\xca\x66\xb8\xb0\xe9\xf2\x40\xa6\x73\xb6\x4b\x28\xff\xfe\x4c\x1e\xc4\xa5\xce\xf0\xf4\x30\x22\x9c\x57\x57\xeb\xd1\x72\xb4\xb0\xb6\x8a\x81\xd8\xc5\x8a\x9e\x96\xe1\x64",
+       10 },
+      { GCRY_MD_SHA3_512,
+       "\xea\xee\xd5\xcd\xff\xd8\x9d\xec\xe4\x55\xf1",
+       "\x7c\x77\xe3\x0e\xce\x98\xef\x88\x96\x44\x58\x68\x3c\x5e\x02\x87\xb5\x89\x6e\x16\x6c\xcc\xa7\x1d\x2b\xfd\x8d\x8b\xbc\x6d\x6f\xe5\x89\xa0\x22\x5e\xb1\xd6\xaa\x7b\x22\x0f\x14\x10\xc9\xa9\xec\x06\x72\xcc\xdd\xaa\x17\x32\xc3\xe2\x87\x7f\xb5\xd2\x32\xc2\xa4\x28",
+       11 },
+      { GCRY_MD_SHA3_512,
+       "\x5b\xe4\x3c\x90\xf2\x29\x02\xe4\xfe\x8e\xd2\xd3",
+       "\xf5\xdf\x59\x52\x92\x4e\x93\x33\x30\xbd\x5b\xd7\x62\x7a\x62\xc3\x67\x2f\x24\xa4\x99\x1d\xad\xaf\x78\x81\x6e\x02\x37\x69\xc9\x1d\x19\x10\x53\x7f\x9c\x19\xfc\xde\x60\xfa\x6d\xe9\x27\x98\x2d\xd5\xf5\x97\x0f\x74\xe3\x0f\x2b\x04\x0f\x67\x34\x8a\x33\x94\xc4\x8c",
+       12 },
+      { GCRY_MD_SHA3_512,
+       "\xa7\x46\x27\x32\x28\x12\x2f\x38\x1c\x3b\x46\xe4\xf1",
+       "\x80\xa1\x31\x7e\xc5\x34\xed\x48\xd8\xa8\x13\xe0\xbc\xa0\xce\xe0\x4f\x70\x5a\x2f\x86\x35\x23\x06\xa9\x32\xed\xc5\x48\xb9\xa8\xf1\xcf\x79\xf9\x50\x27\xf4\x3b\xda\xda\x82\x13\x44\x9c\x54\xf6\x8f\x4d\xd8\x00\xb1\x5c\x4a\xba\xd8\x7a\xd7\xa3\xb3\x71\xa7\xc9\x18",
+       13 },
+      { GCRY_MD_SHA3_512,
+       "\x3c\x58\x71\xcd\x61\x9c\x69\xa6\x3b\x54\x0e\xb5\xa6\x25",
+       "\x54\xc2\x74\xc3\xdd\xf2\x6d\x82\x4f\x5f\xdf\xcb\x34\x9a\x60\x08\x90\x05\x7e\xb2\xe2\x02\x22\x45\xcb\xb8\xbd\xc0\xd2\x24\x0c\xfa\x83\x48\xf0\x21\x91\xfa\xbc\x0e\x10\xf9\x28\x71\x85\x21\x1c\x9f\x56\x91\x32\xee\x6d\xde\x4c\x39\x66\x68\xb4\xbb\x50\xae\xfc\x3f",
+       14 },
+      { GCRY_MD_SHA3_512,
+       "\xfa\x22\x87\x4b\xcc\x06\x88\x79\xe8\xef\x11\xa6\x9f\x07\x22",
+       "\x00\x76\x72\x36\xa7\x35\x25\x51\xb2\x83\xa8\xec\xf4\xc7\x92\x74\xf8\xc4\xce\xa5\x53\xab\x43\xfc\x71\xcf\x22\xfb\x2f\x68\x65\xad\x02\xc8\x8b\xf0\x09\x2f\x21\x30\x57\x34\x0c\x85\xa5\x31\x8f\x62\xf4\x99\x1c\x00\xc6\x3c\xb0\x55\x8c\xbc\xf1\x3d\x6d\x84\xe7\x3d",
+       15 },
+      { GCRY_MD_SHA3_512,
+       "\x52\xa6\x08\xab\x21\xcc\xdd\x8a\x44\x57\xa5\x7e\xde\x78\x21\x76",
+       "\x00\x16\x18\x37\x2e\x75\x14\x7a\xf9\x0c\x0c\xf1\x6c\x3b\xbd\xaa\x06\x9d\xdb\xc6\x24\x83\xb3\x92\xd0\x28\xde\xd4\x9f\x75\x08\x4a\x5d\xfc\xc5\x3a\xec\xd9\xf5\x7d\xdb\xb7\x3d\xaa\x04\x1f\xd7\x10\x89\xd8\xfb\x5e\xdf\x6c\xfa\xf6\xf1\xe4\xe2\x5a\xd3\xde\x26\x6c",
+       16 },
+      { GCRY_MD_SHA3_512,
+       "\x82\xe1\x92\xe4\x04\x3d\xdc\xd1\x2e\xcf\x52\x96\x9d\x0f\x80\x7e\xed",
+       "\x96\x44\xe3\xc9\x0b\x67\xe2\x21\x24\xe9\x6d\xfe\xdc\xe5\x3d\x33\xc4\x60\xf1\x32\x86\x8f\x09\x75\xd1\x8b\x22\xcf\xd5\x9f\x63\x7d\xd8\x5a\xa4\x05\xe3\x98\x08\xa4\x55\x70\xa4\x98\xc0\xb8\xf2\xcb\xa5\x9f\x8e\x14\x37\xea\xef\x89\xf2\x0b\x88\x29\x8a\xdf\xa2\xde",
+       17 },
+      { GCRY_MD_SHA3_512,
+       "\x75\x68\x3d\xcb\x55\x61\x40\xc5\x22\x54\x3b\xb6\xe9\x09\x8b\x21\xa2\x1e",
+       "\x47\x39\x99\x43\x90\x72\x8f\x4a\x93\x8d\xf7\xb3\x20\x1c\xd6\x37\x71\x85\x84\x53\xf0\xff\x1d\xde\x9a\x2b\x9c\x38\xa2\x7a\x0f\x6c\x86\x84\x60\xd0\x0e\xe0\x3d\xdc\xb0\xf0\x63\xf5\xf8\xbb\x7c\xb0\x95\x9b\x7a\x22\x22\x59\xda\x0f\x2c\x57\xfa\x40\x0b\x50\x98\x5b",
+       18 },
+      { GCRY_MD_SHA3_512,
+       "\x06\xe4\xef\xe4\x50\x35\xe6\x1f\xaa\xf4\x28\x7b\x4d\x8d\x1f\x12\xca\x97\xe5",
+       "\xaf\x69\xa4\x65\x27\xc1\x71\x17\xe6\xdf\xf3\x2c\xba\x28\x9e\xdd\xd1\xee\xcd\xa1\x3e\x53\x13\xe4\x66\x78\xeb\x80\x06\xe7\x63\x98\x54\xc3\x97\x0d\xfe\xb4\xd9\x07\xdb\x11\x51\xc1\xc5\xee\x25\xca\x6f\x19\x5b\x09\xca\x5a\x5c\xc9\x7a\x4d\x64\xac\x4c\x75\x57\x8e",
+       19 },
+      { GCRY_MD_SHA3_512,
+       "\xe2\x61\x93\x98\x9d\x06\x56\x8f\xe6\x88\xe7\x55\x40\xae\xa0\x67\x47\xd9\xf8\x51",
+       "\x19\x1c\xef\x1c\x6a\xa0\x09\xb1\xab\xa6\x74\xbe\x2b\x3f\x0d\xa4\x18\xfd\xf9\xe6\xa7\xec\xf2\xbe\x42\xac\x14\xf7\xd6\xe0\x73\x31\x42\x51\x33\xa8\x3b\x4e\x01\x61\xcc\x7d\xeb\xf9\xdc\xd7\xfe\x37\x87\xdc\xb6\x62\x2a\x38\x47\x51\x89\xed\xfe\x1d\xe6\xb0\x53\xd6",
+       20 },
+      { GCRY_MD_SHA3_512,
+       "\xd8\xdc\x8f\xde\xfb\xdc\xe9\xd4\x4e\x4c\xba\xfe\x78\x44\x7b\xae\x3b\x54\x36\x10\x2a",
+       "\xa6\x0d\x75\x87\x42\x4b\x72\x42\xd9\x3b\xcc\xe5\x15\xf1\xc7\x5a\xe2\xbe\x77\x10\xf7\x2e\xd3\xf4\xe5\xea\x8b\xc2\xba\x8d\x64\x09\x9f\xe4\x2b\x88\xa2\x95\xe1\x2f\xda\xfa\xb4\x41\xd7\x72\xc4\xa9\xa7\xd7\x94\xb2\x77\x88\xed\xea\x27\x15\x71\xa0\x43\x05\xf2\x53",
+       21 },
+      { GCRY_MD_SHA3_512,
+       "\x57\x08\x5f\xd7\xe1\x42\x16\xab\x10\x2d\x83\x17\xb0\xcb\x33\x8a\x78\x6d\x5f\xc3\x2d\x8f",
+       "\x09\xfc\xad\x97\xea\x3c\xb6\xb7\xfc\x61\x58\x0d\xe0\x96\x8d\x23\x80\x06\xb7\xe7\x1f\x0b\xd5\x8a\xba\x2a\xa9\xd4\xad\xb8\x55\xd7\x60\x6e\x76\x32\x13\x8c\xcc\x0a\xa0\x65\xca\x0b\x92\x42\x22\x62\xe0\x29\xda\x17\xd7\x3c\xd3\x01\x1f\xf2\x85\x70\x6c\x7f\xc1\xae",
+       22 },
+      { GCRY_MD_SHA3_512,
+       "\xa0\x54\x04\xdf\x5d\xbb\x57\x69\x7e\x2c\x16\xfa\x29\xde\xfa\xc8\xab\x35\x60\xd6\x12\x6f\xa0",
+       "\xf6\x1f\xaa\xb0\x80\xcf\x9a\x5f\x75\x40\x7b\x08\x1a\x03\xde\xf4\xf4\x9a\x60\x1a\x2b\xb8\x32\xe8\xc6\x40\x1b\xe0\xc9\x8b\x3c\xeb\x3f\x75\xc9\x22\xa9\x1b\xd5\x06\x0b\x32\x17\xf7\x37\x40\x4e\xf4\x61\x2b\x9a\x00\x9b\x69\xca\x64\x8b\x1e\x37\xb2\xed\x49\x22\x9d",
+       23 },
+      { GCRY_MD_SHA3_512,
+       "\xae\xcb\xb0\x27\x59\xf7\x43\x3d\x6f\xcb\x06\x96\x3c\x74\x06\x1c\xd8\x3b\x5b\x3f\xfa\x6f\x13\xc6",
+       "\x51\xde\x0a\x62\x2f\xc6\xfc\x70\x2c\x7c\x2d\xb5\xcc\xb0\x5c\xa0\xdd\xf7\x92\x98\x6e\x44\xb4\xd3\x36\xa7\xa5\xda\xf1\x9a\x20\xa3\x71\xd9\xbf\x7d\xde\x82\x2e\xcd\xd0\xa4\xce\x28\xe4\xa0\xb4\x6f\xe5\x1a\x2a\xab\xef\xa7\x86\x58\x07\xef\x3d\x3b\x18\x87\xf1\x4d",
+       24 },
+      { GCRY_MD_SHA3_512,
+       "\xaa\xfd\xc9\x24\x3d\x3d\x4a\x09\x65\x58\xa3\x60\xcc\x27\xc8\xd8\x62\xf0\xbe\x73\xdb\x5e\x88\xaa\x55",
+       "\x62\x86\xc3\xdb\x87\xd3\xb4\x5c\xfd\x4d\xe8\x5a\x7a\xdd\x18\xe0\x7a\xe2\x2f\x1f\x0f\x46\x75\xe1\xd4\xe1\xfc\x77\x63\x37\x34\xd7\x96\x28\x18\xa9\xf3\xb9\x6b\x37\xfe\x77\x4f\xc2\x6d\xea\x78\x74\x85\x31\x7b\x96\x22\x27\x5f\x63\xa7\xdd\x6d\x62\xd6\x50\xd3\x07",
+       25 },
+      { GCRY_MD_SHA3_512,
+       "\x7b\xc8\x48\x67\xf6\xf9\xe9\xfd\xc3\xe1\x04\x6c\xae\x3a\x52\xc7\x7e\xd4\x85\x86\x0e\xe2\x60\xe3\x0b\x15",
+       "\x81\x46\xc4\x3a\x0f\xfe\x48\x18\x72\x14\x2f\x56\xa9\xce\xa4\x43\x32\xed\xc7\x6b\x4e\x99\xc2\xbd\xc3\x9d\x7f\x80\xb2\xa6\xb5\x54\xc7\x59\x8f\x09\x85\x5b\xf7\xab\xc5\xe6\xc0\x48\xbe\x76\xf5\xf3\x69\xeb\xb2\x88\x4e\x6e\x37\xf1\x86\xe8\x71\x9d\xf3\xd5\x23\xe4",
+       26 },
+      { GCRY_MD_SHA3_512,
+       "\xfa\xc5\x23\x57\x5a\x99\xec\x48\x27\x9a\x7a\x45\x9e\x98\xff\x90\x19\x18\xa4\x75\x03\x43\x27\xef\xb5\x58\x43",
+       "\x4b\x86\xfb\xf9\xdf\xb6\x76\x7e\xb6\x60\xaf\x9c\x30\x98\x3e\xd6\x5b\x6f\xd0\x51\x24\x7a\xb5\x47\x67\xdf\xb4\x95\x30\xeb\x3c\x01\x01\x4e\xb2\x6d\xf6\x3e\x53\x6c\xf5\x5e\x0b\xce\x2f\x62\x65\x4f\xb2\xfc\xe3\x83\x9b\x4b\xfd\x30\x15\x70\xb1\xab\x79\x4d\xf6\x7d",
+       27 },
+      { GCRY_MD_SHA3_512,
+       "\x0f\x8b\x2d\x8f\xcf\xd9\xd6\x8c\xff\xc1\x7c\xcf\xb1\x17\x70\x9b\x53\xd2\x64\x62\xa3\xf3\x46\xfb\x7c\x79\xb8\x5e",
+       "\x21\x13\x2f\xc1\x1f\x60\x40\xad\x49\x3d\x62\x70\x27\xc7\x52\xce\x29\x81\x65\x89\xde\x7b\xe7\x85\x62\x91\x4b\x63\xd1\xa9\x21\x98\x03\xdd\xbd\x96\x73\xaa\x74\x9f\x37\xff\x4d\x6e\x1b\x5a\xe2\xa1\x26\x33\xba\x8b\x0c\x99\x94\xe0\x31\xeb\xf6\xc4\x2e\x58\xa7\x93",
+       28 },
+      { GCRY_MD_SHA3_512,
+       "\xa9\x63\xc3\xe8\x95\xff\x5a\x0b\xe4\x82\x44\x00\x51\x8d\x81\x41\x2f\x87\x5f\xa5\x05\x21\xe2\x6e\x85\xea\xc9\x0c\x04",
+       "\x8a\x53\x74\xd9\x2f\xf9\xa5\x8e\x04\x51\xe6\x09\xaa\x5c\x0c\x5c\x17\x2b\xb2\x06\x8c\x80\x56\x2d\x03\x24\xf9\xcb\x6a\x03\x74\x36\x91\x0c\x65\x93\xf9\x50\xc4\x43\x74\xb4\xe5\xbf\x6f\x6d\x3a\x43\x6e\xce\x6d\xaa\xeb\x56\xd1\x47\xd8\xcd\x83\x9c\xca\x35\xea\xc3",
+       29 },
+      { GCRY_MD_SHA3_512,
+       "\x03\xa1\x86\x88\xb1\x0c\xc0\xed\xf8\x3a\xdf\x0a\x84\x80\x8a\x97\x18\x38\x3c\x40\x70\xc6\xc4\xf2\x95\x09\x86\x99\xac\x2c",
+       "\x71\x02\x5d\x08\x9a\x39\xd2\x73\x27\xc4\x6c\x27\xbd\x4e\x75\x65\xdd\xbf\x9c\x28\x6f\x18\x5a\x08\x17\x86\x01\xc3\xba\xb4\x66\x7f\x36\x8a\x3a\x8b\xdd\xac\xf2\x5b\x2b\x0a\xa5\xc9\xe0\xcd\x6c\x87\xdc\x32\xc8\x54\x02\x7a\x89\x54\xb5\xc6\xaf\xd3\xa8\x50\x97\xac",
+       30 },
+      { GCRY_MD_SHA3_512,
+       "\x84\xfb\x51\xb5\x17\xdf\x6c\x5a\xcc\xb5\xd0\x22\xf8\xf2\x8d\xa0\x9b\x10\x23\x2d\x42\x32\x0f\xfc\x32\xdb\xec\xc3\x83\x5b\x29",
+       "\xdc\x29\xeb\x71\x30\x81\x2a\x65\x2a\xf3\xff\x9b\x77\x62\x96\x84\x63\x45\x02\xea\x66\x67\xe7\xe9\xf8\x00\x90\xec\x2a\x9d\x69\x0c\x8c\x9a\x78\x64\x5f\xb0\x4d\x9c\xd2\x69\xe7\x06\xee\x2c\x96\xe7\x42\x07\xfb\xbd\xa5\x59\xdc\x28\x5c\x9b\xc5\x2f\x15\xa2\x56\xca",
+       31 },
+      { GCRY_MD_SHA3_512,
+       "\x9f\x2f\xcc\x7c\x90\xde\x09\x0d\x6b\x87\xcd\x7e\x97\x18\xc1\xea\x6c\xb2\x11\x18\xfc\x2d\x5d\xe9\xf9\x7e\x5d\xb6\xac\x1e\x9c\x10",
+       "\xb0\x87\xc9\x04\x21\xae\xbf\x87\x91\x16\x47\xde\x9d\x46\x5c\xbd\xa1\x66\xb6\x72\xec\x47\xcc\xd4\x05\x4a\x71\x35\xa1\xef\x88\x5e\x79\x03\xb5\x2c\x3f\x2c\x3f\xe7\x22\xb1\xc1\x69\x29\x7a\x91\xb8\x24\x28\x95\x6a\x02\xc6\x31\xa2\x24\x0f\x12\x16\x2c\x7b\xc7\x26",
+       32 },
+      { GCRY_MD_SHA3_512,
+       "\xde\x8f\x1b\x3f\xaa\x4b\x70\x40\xed\x45\x63\xc3\xb8\xe5\x98\x25\x31\x78\xe8\x7e\x4d\x0d\xf7\x5e\x4f\xf2\xf2\xde\xdd\x5a\x0b\xe0\x46",
+       "\xd2\xa9\x5c\x6f\xc0\xf3\x9c\x8f\x7a\x86\xc4\xdd\x62\x61\xa7\x9c\x94\x0f\xcb\x31\x3b\xcf\xba\x9b\xf7\x15\x27\xf5\xbc\x70\xef\x82\x7c\xd9\x7d\xfa\x18\x28\x0e\x5d\xde\xe5\xcc\xbc\x1d\x63\xce\x88\xce\x2b\xcd\xd8\x2d\xab\x61\x0f\x79\x86\x7a\x7c\x20\xb1\x1e\x4f",
+       33 },
+      { GCRY_MD_SHA3_512,
+       "\x62\xf1\x54\xec\x39\x4d\x0b\xc7\x57\xd0\x45\xc7\x98\xc8\xb8\x7a\x00\xe0\x65\x5d\x04\x81\xa7\xd2\xd9\xfb\x58\xd9\x3a\xed\xc6\x76\xb5\xa0",
+       "\xaf\x8c\x0f\xbd\x72\xb3\xf8\x07\xdb\x95\xc9\x23\x1b\xc4\xe9\x31\x53\xdc\x66\x08\xb2\x2f\x47\x07\x31\x6a\xab\x3d\x69\xaf\x0e\x63\x29\x1b\x56\x9f\x11\x8b\x5c\x9e\x69\x3c\x5b\xac\x46\x30\xc4\xa9\x23\xa4\x74\x35\x81\x24\x6a\xd3\x44\x6d\xda\x4f\x90\x76\xfd\xdb",
+       34 },
+      { GCRY_MD_SHA3_512,
+       "\xb2\xdc\xfe\x9f\xf1\x9e\x2b\x23\xce\x7d\xa2\xa4\x20\x7d\x3e\x5e\xc7\xc6\x11\x2a\x8a\x22\xae\xc9\x67\x5a\x88\x63\x78\xe1\x4e\x5b\xfb\xad\x4e",
+       "\xbf\xc7\xd9\x68\xd4\x53\x42\x06\x98\x07\xc5\xf1\xb9\x64\x25\xcf\xff\xe9\x9e\xd1\x36\xd4\x76\x65\xe9\x02\xe0\x26\xc1\x18\x70\x1b\xb7\xc3\xe7\xfd\x69\x17\x85\x11\x5c\xfd\xb2\xef\x23\x5a\x66\xbc\xc1\x38\x4a\x1d\x08\x8b\x8c\xca\x90\xd9\xd5\x60\x91\x35\x49\xde",
+       35 },
+      { GCRY_MD_SHA3_512,
+       "\x47\xf5\x69\x7a\xc8\xc3\x14\x09\xc0\x86\x88\x27\x34\x7a\x61\x3a\x35\x62\x04\x1c\x63\x3c\xf1\xf1\xf8\x68\x65\xa5\x76\xe0\x28\x35\xed\x2c\x24\x92",
+       "\x9a\x34\x85\x40\xab\x66\x9c\xdd\x89\x14\x42\x6f\xbb\xad\x19\x2b\xa0\xdb\x16\x58\x3e\x8d\x4e\x86\x7b\x66\xcc\x78\xc6\x49\x6e\x4d\x83\xdd\xbf\x7b\x97\x2b\x06\x68\xdf\x79\x03\xb0\xfe\x9a\xb8\x2b\x65\x15\x3f\x94\x7c\xf2\xaf\x25\x91\x12\x1c\x9d\x1a\x78\xe5\x15",
+       36 },
+      { GCRY_MD_SHA3_512,
+       "\x51\x2a\x6d\x29\x2e\x67\xec\xb2\xfe\x48\x6b\xfe\x92\x66\x09\x53\xa7\x54\x84\xff\x4c\x4f\x2e\xca\x2b\x0a\xf0\xed\xcd\xd4\x33\x9c\x6b\x2e\xe4\xe5\x42",
+       "\xff\xdb\x64\x9d\x1a\xa7\xff\x26\x9b\x9b\xb0\xae\x61\x92\xf7\xbc\xbc\x06\x61\x25\x28\xdf\x0e\x68\x52\x1d\x5c\x89\x1e\x9b\xba\x12\x92\x71\xa0\x7d\xc5\x63\x93\xbb\x21\x21\x8f\x5e\x2f\xb9\x2c\xff\xf8\x33\x43\x20\x66\xaa\x63\x80\xf3\x55\x7a\x07\x48\xe6\x5b\x33",
+       37 },
+      { GCRY_MD_SHA3_512,
+       "\x97\x3c\xf2\xb4\xdc\xf0\xbf\xa8\x72\xb4\x11\x94\xcb\x05\xbb\x4e\x16\x76\x0a\x18\x40\xd8\x34\x33\x01\x80\x25\x76\x19\x7e\xc1\x9e\x2a\x14\x93\xd8\xf4\xfb",
+       "\x96\x65\x80\x8d\x39\xb4\xbe\xcf\xdd\x9a\xa8\x02\x0a\x0a\x72\xcf\xd4\xf8\x23\xa1\x5d\x67\x0d\x51\x27\x8a\x4a\xe9\x55\x07\xe1\x60\x20\xae\xde\xd6\xe6\xc0\xe2\xda\xb0\xba\xd8\x90\xa9\xe7\x55\x24\x03\xd2\xaa\x8d\x1e\xbc\x0b\x8e\xae\xc9\xa3\xa8\xdb\xb2\xa9\xef",
+       38 },
+      { GCRY_MD_SHA3_512,
+       "\x80\xbe\xeb\xcd\x2e\x3f\x8a\x94\x51\xd4\x49\x99\x61\xc9\x73\x1a\xe6\x67\xcd\xc2\x4e\xa0\x20\xce\x3b\x9a\xa4\xbb\xc0\xa7\xf7\x9e\x30\xa9\x34\x46\x7d\xa4\xb0",
+       "\x7a\xba\x6b\x9f\x8f\x18\xd9\xd7\x2b\x88\x3e\xb9\x88\xa5\xf4\xff\xcc\x02\x17\xa3\xda\x31\x6a\xff\x11\xb3\x89\x76\xe9\x0b\x07\x36\xcb\x00\x0f\x52\x2d\xbf\x2d\xdc\xbb\x61\xba\x4b\xf4\x4c\x35\x6e\xc5\xb4\x6f\xc8\x6a\x51\x33\xf9\x71\xa9\x4f\xe2\xa9\x98\x32\x60",
+       39 },
+      { GCRY_MD_SHA3_512,
+       "\x7a\xba\xa1\x2e\xc2\xa7\x34\x76\x74\xe4\x44\x14\x0a\xe0\xfb\x65\x9d\x08\xe1\xc6\x6d\xec\xd8\xd6\xea\xe9\x25\xfa\x45\x1d\x65\xf3\xc0\x30\x8e\x29\x44\x6b\x8e\xd3",
+       "\x58\x9c\x46\x62\x5a\x6a\xc9\xa2\xc9\xc9\xa8\x84\xf4\x27\xc3\xc0\x32\x88\x7a\xe5\x3a\x69\x93\x2b\x72\xe1\xe3\x79\x6b\xb9\x56\x89\x29\xd1\x63\x39\x5a\x3a\xa8\xb2\xab\x23\xc5\x64\x93\x7c\xd7\x29\x20\x6d\x9b\x62\xcc\x60\x35\x3b\x68\xa6\x9a\x73\x96\x16\xeb\x35",
+       40 },
+      { GCRY_MD_SHA3_512,
+       "\xc8\x8d\xee\x99\x27\x67\x9b\x8a\xf4\x22\xab\xcb\xac\xf2\x83\xb9\x04\xff\x31\xe1\xca\xc5\x8c\x78\x19\x80\x9f\x65\xd5\x80\x7d\x46\x72\x3b\x20\xf6\x7b\xa6\x10\xc2\xb7",
+       "\xf7\xcd\x87\x37\xa1\xab\x36\xb3\x76\x12\xe5\x7d\x1e\x5a\x3d\x4a\x26\x9d\x18\xcf\x2c\xb7\x64\x4a\x12\x54\x0e\x3b\x18\x46\x31\x79\x4e\xc1\xa1\xda\x11\x8a\x10\x9a\xef\x51\x4d\xb3\x59\x0f\xe2\x7b\xe0\x75\x2e\xc0\x82\x6a\xca\xf4\x58\xfb\x0a\x75\x4b\xdc\x51\xf1",
+       41 },
+      { GCRY_MD_SHA3_512,
+       "\x01\xe4\x3f\xe3\x50\xfc\xec\x45\x0e\xc9\xb1\x02\x05\x3e\x6b\x5d\x56\xe0\x98\x96\xe0\xdd\xd9\x07\x4f\xe1\x38\xe6\x03\x82\x10\x27\x0c\x83\x4c\xe6\xea\xdc\x2b\xb8\x6b\xf6",
+       "\xb2\x1b\xde\xde\x48\x4c\xa1\x8f\x67\x20\x58\x66\x7c\xb2\xf2\xdc\x92\x2c\x44\x35\x1e\x95\xc2\xcd\xa7\x5a\xf7\xe4\x55\x77\xbf\x50\xe3\xf2\x03\x13\x9f\x62\x62\x27\x9a\xdf\xc3\x22\x1b\x94\xa0\x72\x64\x1f\x8b\xdb\x55\xdc\xc0\x2f\x21\xd0\x87\x9e\xb5\xe7\x46\x6a",
+       42 },
+      { GCRY_MD_SHA3_512,
+       "\x33\x70\x23\x37\x0a\x48\xb6\x2e\xe4\x35\x46\xf1\x7c\x4e\xf2\xbf\x8d\x7e\xcd\x1d\x49\xf9\x0b\xab\x60\x4b\x83\x9c\x2e\x6e\x5b\xd2\x15\x40\xd2\x9b\xa2\x7a\xb8\xe3\x09\xa4\xb7",
+       "\xdb\x56\x26\x5b\x93\x46\x96\x8a\x39\x0e\x98\x41\xd5\xb7\x87\x8a\x15\x8b\xae\xd9\x46\x06\x8e\x80\x8e\x45\x67\x35\xa6\x7e\x49\x22\x0f\xab\x66\x23\x9d\x5d\x50\x6d\xd7\x5a\x58\xf2\xc5\x6e\x25\xc9\xc1\x05\xa3\x82\x7c\x14\x34\xc6\x72\x55\xcf\xc9\x10\x1a\x5d\x09",
+       43 },
+      { GCRY_MD_SHA3_512,
+       "\x68\x92\x54\x0f\x96\x4c\x8c\x74\xbd\x2d\xb0\x2c\x0a\xd8\x84\x51\x0c\xb3\x8a\xfd\x44\x38\xaf\x31\xfc\x91\x27\x56\xf3\xef\xec\x6b\x32\xb5\x8e\xbc\x38\xfc\x2a\x6b\x91\x35\x96\xa8",
+       "\x4c\x82\x5f\xd9\xa7\x95\xcc\xd2\x0a\x08\x92\xda\x15\x72\xb9\xb1\xf7\x0b\xa0\x5f\xf2\xd2\xda\x3a\x47\x26\xa7\x4f\x9a\xb5\x32\x3c\xcb\xc4\x29\x04\x59\xc1\xbb\x46\xf0\xa1\xe1\xff\xc3\x57\xff\x47\x66\xf4\xf4\x87\x9d\xaa\x91\xd3\x1e\xca\x98\x6a\xa3\x0c\x7b\x00",
+       44 },
+      { GCRY_MD_SHA3_512,
+       "\xf5\x96\x1d\xfd\x2b\x1f\xff\xfd\xa4\xff\xbf\x30\x56\x0c\x16\x5b\xfe\xda\xb8\xce\x0b\xe5\x25\x84\x5d\xeb\x8d\xc6\x10\x04\xb7\xdb\x38\x46\x72\x05\xf5\xdc\xfb\x34\xa2\xac\xfe\x96\xc0",
+       "\x84\x45\xa0\x57\x66\xa3\x0d\xdd\x00\x80\x58\x9f\x8e\x8c\xbf\x7e\xc5\x9f\xb7\xa3\xce\x73\xc0\x20\x97\x91\xb1\x9c\xf7\x12\xcf\x16\x35\xd6\x3c\x83\x56\x82\x22\x72\x30\x9c\x6b\x9f\x01\x63\x70\x88\x87\x8d\xbf\xfb\xed\xb2\x6d\x2a\x56\x61\x85\x22\x5c\x4d\xa5\x6b",
+       45 },
+      { GCRY_MD_SHA3_512,
+       "\xca\x06\x1a\x2e\xb6\xce\xed\x88\x81\xce\x20\x57\x17\x2d\x86\x9d\x73\xa1\x95\x1e\x63\xd5\x72\x61\x38\x4b\x80\xce\xb5\x45\x1e\x77\xb0\x6c\xf0\xf5\xa0\xea\x15\xca\x90\x7e\xe1\xc2\x7e\xba",
+       "\x2d\xc2\x51\x65\xcf\x31\x7e\xd7\xde\x2b\x4f\x2f\xd0\x99\x5d\x77\x85\x97\x8c\xa8\x58\x1e\xa8\x03\x3e\x91\x2f\x2e\x44\xee\x61\x3d\xeb\xfc\x55\x35\xc4\x8d\x63\x83\x8f\x32\x5d\x14\x16\xb9\x18\x0c\x20\xbd\xe8\x26\x14\x50\x4b\x71\x61\xf9\x86\x05\x30\xec\xa7\x0c",
+       46 },
+      { GCRY_MD_SHA3_512,
+       "\x17\x43\xa7\x72\x51\xd6\x92\x42\x75\x0c\x4f\x11\x40\x53\x2c\xd3\xc3\x3f\x9b\x5c\xcd\xf7\x51\x4e\x85\x84\xd4\xa5\xf9\xfb\xd7\x30\xbc\xf8\x4d\x0d\x47\x26\x36\x4b\x9b\xf9\x5a\xb2\x51\xd9\xbb",
+       "\xcb\x61\x10\xa0\x2d\x7c\xa6\x36\x46\x3f\x6e\x35\x02\xcc\xf0\x17\x3b\x00\x04\x82\xc7\xe0\x02\xad\x92\x77\xc1\xd1\x03\x17\xbd\xde\xbc\x3d\xa7\xf9\x1d\x01\x73\xe3\xe2\xf9\x55\x2b\xdf\xde\xa4\xdd\x1a\xfb\xf7\x50\x8b\x09\x6a\xab\x18\x04\x92\x1e\x95\x75\x4e\x78",
+       47 },
+      { GCRY_MD_SHA3_512,
+       "\xd8\xfa\xba\x1f\x51\x94\xc4\xdb\x5f\x17\x6f\xab\xff\xf8\x56\x92\x4e\xf6\x27\xa3\x7c\xd0\x8c\xf5\x56\x08\xbb\xa8\xf1\xe3\x24\xd7\xc7\xf1\x57\x29\x8e\xab\xc4\xdc\xe7\xd8\x9c\xe5\x16\x24\x99\xf9",
+       "\x7e\xf3\xa2\x89\x4c\x6e\xcb\xc4\x20\x1b\x15\x34\x8f\x90\x67\x15\x15\xac\xcb\xa3\xc8\x16\x66\x21\xf8\x64\xa9\x18\x4b\xf0\x8c\x3f\x5a\x89\x5f\x6b\x59\x9d\x3c\xb4\x1f\x20\xa8\xa1\xdf\x25\xae\x84\xf1\xa6\xd7\xc8\xde\x74\xfb\x7c\xef\x48\xf7\xe9\x6f\xde\x8d\x43",
+       48 },
+      { GCRY_MD_SHA3_512,
+       "\xbe\x96\x84\xbe\x70\x34\x08\x60\x37\x3c\x9c\x48\x2b\xa5\x17\xe8\x99\xfc\x81\xba\xaa\x12\xe5\xc6\xd7\x72\x79\x75\xd1\xd4\x1b\xa8\xbe\xf7\x88\xcd\xb5\xcf\x46\x06\xc9\xc1\xc7\xf6\x1a\xed\x59\xf9\x7d",
+       "\x39\xc7\xae\x0f\x80\x12\x9d\x9d\x29\x80\xa6\x24\x6e\x2b\x6f\x10\xa3\x9e\xfa\xfd\x69\x4d\xed\x12\xa6\x08\x95\x09\xd9\x5e\xce\x50\x6d\xc3\x8c\x0a\x9d\xe4\x87\xd9\xd4\x01\xdb\x1f\x15\x19\x34\x04\x91\x10\x69\x53\x3b\xca\xe4\xc4\x8c\x53\xf2\x7b\xee\x3c\xe0\xac",
+       49 },
+      { GCRY_MD_SHA3_512,
+       "\x7e\x15\xd2\xb9\xea\x74\xca\x60\xf6\x6c\x8d\xfa\xb3\x77\xd9\x19\x8b\x7b\x16\xde\xb6\xa1\xba\x0e\xa3\xc7\xee\x20\x42\xf8\x9d\x37\x86\xe7\x79\xcf\x05\x3c\x77\x78\x5a\xa9\xe6\x92\xf8\x21\xf1\x4a\x7f\x51",
+       "\x9b\x8a\x7d\x2f\x85\x19\xad\x6d\xc3\xd2\xbc\x5b\x69\x6b\x35\x4c\x5a\x8b\x47\x96\x40\x2c\xe1\x24\x2c\x52\x63\x8e\xea\x68\x93\xa1\x26\x98\x20\xa6\x42\xbc\x9e\xfe\x56\xcd\x7e\x26\xdc\x46\xe9\x7a\x7f\xc5\x8f\xaf\x3f\x1a\x7a\x25\xf8\x6e\xcd\xc1\xf2\xf1\x7e\x64",
+       50 },
+      { GCRY_MD_SHA3_512,
+       "\x9a\x21\x9b\xe4\x37\x13\xbd\x57\x80\x15\xe9\xfd\xa6\x6c\x0f\x2d\x83\xca\xc5\x63\xb7\x76\xab\x9f\x38\xf3\xe4\xf7\xef\x22\x9c\xb4\x43\x30\x4f\xba\x40\x1e\xfb\x2b\xdb\xd7\xec\xe9\x39\x10\x22\x98\x65\x1c\x86",
+       "\xb5\xce\xef\x23\xf5\x6b\xe8\x07\xb6\x16\xc7\xfd\xa4\x86\x7a\x1d\x12\xd0\xa1\x68\x45\x45\x9f\xc7\x04\xce\x63\x1a\xd3\x27\x9a\xb2\x22\xdc\xa7\xad\xda\xe5\x95\xd2\x89\xcb\xa8\x99\x6d\x46\x65\x5f\xa9\xb6\xbe\x58\x70\x03\x02\xe6\x55\xc5\x1c\x82\x5f\x31\xbb\x2e",
+       51 },
+      { GCRY_MD_SHA3_512,
+       "\xc8\xf2\xb6\x93\xbd\x0d\x75\xef\x99\xca\xeb\xdc\x22\xad\xf4\x08\x8a\x95\xa3\x54\x2f\x63\x72\x03\xe2\x83\xbb\xc3\x26\x87\x80\xe7\x87\xd6\x8d\x28\xcc\x38\x97\x45\x2f\x6a\x22\xaa\x85\x73\xcc\xeb\xf2\x45\x97\x2a",
+       "\x14\x3d\x02\x4f\xa7\x5c\x8d\x46\x27\x35\x89\xb8\xf7\x84\x32\xd4\x9e\xf1\x41\x78\xe4\xaa\xa2\x7d\xc3\x66\xc9\xcb\x78\x7f\x24\xb7\x3f\x41\x97\xa7\x22\xf1\x30\x31\x18\x1a\x6f\xa6\xe4\xf6\x61\x27\x89\x3d\xa7\xb2\x3a\x57\x9b\xb9\x3f\xe7\xd7\x37\xa4\x19\x40\x93",
+       52 },
+      { GCRY_MD_SHA3_512,
+       "\xec\x0f\x99\x71\x10\x16\xc6\xa2\xa0\x7a\xd8\x0d\x16\x42\x75\x06\xce\x6f\x44\x10\x59\xfd\x26\x94\x42\xba\xaa\x28\xc6\xca\x03\x7b\x22\xee\xac\x49\xd5\xd8\x94\xc0\xbf\x66\x21\x9f\x2c\x08\xe9\xd0\xe8\xab\x21\xde\x52",
+       "\x0f\x48\xd0\x08\xdd\x3a\xa6\x30\xe8\x26\x16\x58\xa5\x5b\x56\x5b\x67\x73\x99\x24\x26\xb0\x85\x92\xb4\xc1\xd7\x7a\x58\xb0\x67\xf0\x5e\x25\x97\x4e\x50\x16\x28\xa2\xdb\x63\x2f\x2d\xdd\xd7\x36\x73\x11\x9a\xda\x56\x74\xd0\xce\x92\xc7\xaa\x90\x8b\x9e\x9c\x43\x5e",
+       53 },
+      { GCRY_MD_SHA3_512,
+       "\x0d\xc4\x51\x81\x33\x7c\xa3\x2a\x82\x22\xfe\x7a\x3b\xf4\x2f\xc9\xf8\x97\x44\x25\x9c\xff\x65\x35\x04\xd6\x05\x1f\xe8\x4b\x1a\x7f\xfd\x20\xcb\x47\xd4\x69\x6c\xe2\x12\xa6\x86\xbb\x9b\xe9\xa8\xab\x1c\x69\x7b\x6d\x6a\x33",
+       "\x29\x74\x98\x63\x9f\xc7\xaa\x41\x52\x65\x4e\x46\x8e\x08\xf2\x9a\xff\xd7\x06\x1d\x44\xe3\xf5\x32\xbe\x4b\xac\x16\x9c\x87\x7a\x2e\xa7\xb4\xd7\x0d\x6b\xc0\xf6\x78\xbe\x08\xaa\x06\x42\x58\xef\x57\x11\x13\x10\xd1\x3b\x88\x97\x12\xd0\x65\x30\xb6\x90\x84\x1d\xbe",
+       54 },
+      { GCRY_MD_SHA3_512,
+       "\xde\x28\x6b\xa4\x20\x6e\x8b\x00\x57\x14\xf8\x0f\xb1\xcd\xfa\xeb\xde\x91\xd2\x9f\x84\x60\x3e\x4a\x3e\xbc\x04\x68\x6f\x99\xa4\x6c\x9e\x88\x0b\x96\xc5\x74\x82\x55\x82\xe8\x81\x2a\x26\xe5\xa8\x57\xff\xc6\x57\x9f\x63\x74\x2f",
+       "\x1b\x6d\xa1\x61\x51\xfc\xd1\x83\x83\x37\x26\x83\x48\x01\x19\xa3\x04\x79\x6b\x2a\x5e\x54\xf7\xed\xc6\xc7\xbc\x86\x81\x73\x59\xe7\x3f\x6f\xc5\x58\x7c\x77\xbf\xc7\x1b\x56\xec\x67\x90\x5f\xa7\xf1\x51\x93\xf9\xf1\x3c\xfa\x19\x0b\xc7\xb0\x55\x03\xa5\x78\x2c\x8a",
+       55 },
+      { GCRY_MD_SHA3_512,
+       "\xee\xbc\xc1\x80\x57\x25\x2c\xbf\x3f\x9c\x07\x0f\x1a\x73\x21\x33\x56\xd5\xd4\xbc\x19\xac\x2a\x41\x1e\xc8\xcd\xee\xe7\xa5\x71\xe2\xe2\x0e\xaf\x61\xfd\x0c\x33\xa0\xff\xeb\x29\x7d\xdb\x77\xa9\x7f\x0a\x41\x53\x47\xdb\x66\xbc\xaf",
+       "\xb2\xf4\x09\x35\xe7\xc9\x01\x88\x14\xc4\xe2\x72\x1d\x9b\x5a\xee\xed\x33\x70\x69\x03\x78\xe4\x72\xbd\x29\xf2\x27\x44\x2c\xa4\x94\x2b\x06\x18\x9c\x34\x6f\xda\x49\x81\x23\xec\xe5\x90\x18\xe4\x2c\x8b\x7e\xe3\x81\x91\xf9\x77\x89\xb4\xaa\x93\x22\x3a\x8d\x80\xef",
+       56 },
+      { GCRY_MD_SHA3_512,
+       "\x41\x6b\x5c\xdc\x9f\xe9\x51\xbd\x36\x1b\xd7\xab\xfc\x12\x0a\x50\x54\x75\x8e\xba\x88\xfd\xd6\x8f\xd8\x4e\x39\xd3\xb0\x9a\xc2\x54\x97\xd3\x6b\x43\xcb\xe7\xb8\x5a\x6a\x3c\xeb\xda\x8d\xb4\xe5\x54\x9c\x3e\xe5\x1b\xb6\xfc\xb6\xac\x1e",
+       "\xc8\xd2\x42\xfb\x5f\xf1\xc6\xcd\x11\xa0\x40\xae\xaf\x35\xcc\x09\xe3\x55\xa9\x75\xe0\x4d\xed\x1d\x83\x41\x87\x8b\xed\x5d\xff\x8b\xbb\xd1\xb6\x9f\x4d\x12\x2c\xe5\x33\x09\xac\x08\x75\x3b\x95\xd2\xa5\x77\x21\xdf\xd1\x2e\x70\xa8\xef\x12\xe1\x1e\x16\xde\x0f\xd9",
+       57 },
+      { GCRY_MD_SHA3_512,
+       "\x5c\x5f\xaf\x66\xf3\x2e\x0f\x83\x11\xc3\x2e\x8d\xa8\x28\x4a\x4e\xd6\x08\x91\xa5\xa7\xe5\x0f\xb2\x95\x6b\x3c\xba\xa7\x9f\xc6\x6c\xa3\x76\x46\x0e\x10\x04\x15\x40\x1f\xc2\xb8\x51\x8c\x64\x50\x2f\x18\x7e\xa1\x4b\xfc\x95\x03\x75\x97\x05",
+       "\xd1\xd5\xd5\xdd\x7d\x19\x6b\x87\xbe\x4a\x38\xf2\xd9\xb4\xa6\x9d\xf9\xdf\xe0\xa6\xe8\xce\x71\xb0\x8c\xf2\x2c\x7f\x67\x0e\xcf\x27\x3e\xaf\x39\x5d\x12\xfc\x63\xe1\x74\x1d\xef\x11\x3c\xc7\x10\x49\x70\x19\x4a\x7c\x7c\x80\x7e\x53\x19\xd7\xbb\x70\x2f\x20\xb5\x68",
+       58 },
+      { GCRY_MD_SHA3_512,
+       "\x71\x67\xe1\xe0\x2b\xe1\xa7\xca\x69\xd7\x88\x66\x6f\x82\x3a\xe4\xee\xf3\x92\x71\xf3\xc2\x6a\x5c\xf7\xce\xe0\x5b\xca\x83\x16\x10\x66\xdc\x2e\x21\x7b\x33\x0d\xf8\x21\x10\x37\x99\xdf\x6d\x74\x81\x0e\xed\x36\x3a\xdc\x4a\xb9\x9f\x36\x04\x6a",
+       "\xd8\x12\x47\x0b\x2d\x13\x5b\x6e\x1b\xc0\xc8\x5d\xc0\x65\x2b\xf9\xf6\xc2\xf9\xee\x70\x7a\x2e\x66\x71\x81\xcc\x9f\x68\x9b\xc7\xdf\x9c\xc9\x99\xb0\x87\x16\x86\x8a\xfa\xc7\x82\x44\xb1\x51\xb7\x25\xa0\x27\xd9\x25\x0a\xb7\xa0\x73\xa4\x69\xe7\xf0\x9b\xdb\x0b\x55",
+       59 },
+      { GCRY_MD_SHA3_512,
+       "\x2f\xda\x31\x1d\xbb\xa2\x73\x21\xc5\x32\x95\x10\xfa\xe6\x94\x8f\x03\x21\x0b\x76\xd4\x3e\x74\x48\xd1\x68\x9a\x06\x38\x77\xb6\xd1\x4c\x4f\x6d\x0e\xaa\x96\xc1\x50\x05\x13\x71\xf7\xdd\x8a\x41\x19\xf7\xda\x5c\x48\x3c\xc3\xe6\x72\x3c\x01\xfb\x7d",
+       "\x20\x3e\xf6\xbb\x51\x32\xa9\xd4\x4e\xae\x93\xc7\x20\x2b\x14\x69\xc2\xc2\xb9\x37\x06\xd0\xa3\x1b\x29\x22\x3c\x41\x1a\x39\x55\x0f\x60\xf3\x9b\x95\x56\xfd\x04\x0b\xfb\x5f\x9f\x70\x99\x31\x3b\x88\x74\xc8\xed\x67\x7c\xfc\x5f\x93\xd9\xa2\x94\x1a\x9b\x01\x39\xde",
+       60 },
+      { GCRY_MD_SHA3_512,
+       "\x95\xd1\x47\x4a\x5a\xab\x5d\x24\x22\xac\xa6\xe4\x81\x18\x78\x33\xa6\x21\x2b\xd2\xd0\xf9\x14\x51\xa6\x7d\xd7\x86\xdf\xc9\x1d\xfe\xd5\x1b\x35\xf4\x7e\x1d\xeb\x8a\x8a\xb4\xb9\xcb\x67\xb7\x01\x79\xcc\x26\xf5\x53\xae\x7b\x56\x99\x69\xce\x15\x1b\x8d",
+       "\x23\xbe\xad\x09\x70\x7a\x77\xb2\x95\xfd\x22\xfe\x00\x12\x82\x33\x8c\x2d\x36\x83\x02\xa0\x5f\xb1\x14\xba\x2a\x01\x2c\x4d\xef\xcf\x06\xf3\x88\x7d\x6d\xb7\xa0\xa1\xde\x04\xbc\x39\x9b\xde\x92\xd6\xbe\x71\x90\x4a\x9a\xa7\xb9\x2b\xed\xfa\x02\x03\xf1\xd8\xb0\x6f",
+       61 },
+      { GCRY_MD_SHA3_512,
+       "\xc7\x1b\xd7\x94\x1f\x41\xdf\x04\x4a\x29\x27\xa8\xff\x55\xb4\xb4\x67\xc3\x3d\x08\x9f\x09\x88\xaa\x25\x3d\x29\x4a\xdd\xbd\xb3\x25\x30\xc0\xd4\x20\x8b\x10\xd9\x95\x98\x23\xf0\xc0\xf0\x73\x46\x84\x00\x6d\xf7\x9f\x70\x99\x87\x0f\x6b\xf5\x32\x11\xa8\x8d",
+       "\x93\xa8\xdb\x85\x77\x4b\x32\x10\x90\x80\x1d\xf4\xdc\x3c\xc7\x5e\x94\xaf\x63\xff\x6d\xcf\x50\xbd\x21\x0e\x5b\x65\xfb\x35\xe1\xbe\xae\xde\xd5\x56\x02\xeb\x32\x38\x07\x26\x02\x98\x34\x98\x2d\x77\xb4\x34\xe9\x41\x79\xd0\xa3\xee\x10\x59\x34\x59\x10\xee\x1d\xcc",
+       62 },
+      { GCRY_MD_SHA3_512,
+       "\xf5\x7c\x64\x00\x6d\x9e\xa7\x61\x89\x2e\x14\x5c\x99\xdf\x1b\x24\x64\x08\x83\xda\x79\xd9\xed\x52\x62\x85\x9d\xcd\xa8\xc3\xc3\x2e\x05\xb0\x3d\x98\x4f\x1a\xb4\xa2\x30\x24\x2a\xb6\xb7\x8d\x36\x8d\xc5\xaa\xa1\xe6\xd3\x49\x8d\x53\x37\x1e\x84\xb0\xc1\xd4\xba",
+       "\x3b\x7d\x98\xff\x31\x52\xb2\x02\x4a\xad\x4f\xa0\xb4\x0d\xc6\x42\xe8\x42\xd4\x53\x30\x5e\xce\xf2\x78\x57\x4e\x38\x61\x72\xf3\xc1\x64\xe4\xef\xb9\xc2\x95\x1a\x23\xfc\x73\xd8\x3c\x16\xb4\x90\x0f\xb9\x2a\xeb\x8e\xfe\x06\xb5\x8f\x91\x8b\xc4\xa4\x81\xe4\xc2\x38",
+       63 },
+      { GCRY_MD_SHA3_512,
+       "\xe9\x26\xae\x8b\x0a\xf6\xe5\x31\x76\xdb\xff\xcc\x2a\x6b\x88\xc6\xbd\x76\x5f\x93\x9d\x3d\x17\x8a\x9b\xde\x9e\xf3\xaa\x13\x1c\x61\xe3\x1c\x1e\x42\xcd\xfa\xf4\xb4\xdc\xde\x57\x9a\x37\xe1\x50\xef\xbe\xf5\x55\x5b\x4c\x1c\xb4\x04\x39\xd8\x35\xa7\x24\xe2\xfa\xe7",
+       "\xeb\x50\x67\xbf\x76\x2a\x29\x1c\xf2\x58\xad\x69\xa8\x16\xa0\xb0\x89\xe0\xbd\x44\xf8\xe5\xb7\x4c\xf6\x0b\xce\x64\x73\x4e\x59\x85\x3c\xcb\x8d\x09\x1c\xd2\xe3\x3f\x90\xaa\x06\x3f\xb7\x94\x2c\xf5\x96\x5d\x45\x92\x00\x14\x4c\x1a\x08\x01\xab\xd6\x9a\x9a\x09\x4a",
+       64 },
+      { GCRY_MD_SHA3_512,
+       "\x16\xe8\xb3\xd8\xf9\x88\xe9\xbb\x04\xde\x9c\x96\xf2\x62\x78\x11\xc9\x73\xce\x4a\x52\x96\xb4\x77\x2c\xa3\xee\xfe\xb8\x0a\x65\x2b\xdf\x21\xf5\x0d\xf7\x9f\x32\xdb\x23\xf9\xf7\x3d\x39\x3b\x2d\x57\xd9\xa0\x29\x7f\x7a\x2f\x2e\x79\xcf\xda\x39\xfa\x39\x3d\xf1\xac\x00",
+       "\xb0\xe2\x3d\x60\x0b\xa4\x21\x5f\x79\xd5\x00\x47\xbb\xfe\xd5\x0d\xf7\xd6\xe7\x69\x51\x4d\x79\x6a\xfd\x16\x6d\xee\xca\x88\xbd\x1c\xbe\x0a\xfc\x72\xa4\x1e\x03\x17\xa2\x23\x22\x5b\x4f\x58\x82\xf7\x23\xaf\xcb\xa3\xaf\x7c\x45\x7e\xb5\x25\x94\x6d\xa6\xc5\x3b\xb0",
+       65 },
+      { GCRY_MD_SHA3_512,
+       "\xfc\x42\x4e\xeb\x27\xc1\x8a\x11\xc0\x1f\x39\xc5\x55\xd8\xb7\x8a\x80\x5b\x88\xdb\xa1\xdc\x2a\x42\xed\x5e\x2c\x0e\xc7\x37\xff\x68\xb2\x45\x6d\x80\xeb\x85\xe1\x17\x14\xfa\x3f\x8e\xab\xfb\x90\x6d\x3c\x17\x96\x4c\xb4\xf5\xe7\x6b\x29\xc1\x76\x5d\xb0\x3d\x91\xbe\x37\xfc",
+       "\x83\x02\x10\x62\x11\x7d\xa9\x93\x27\xe5\x21\xd7\xc9\x13\x31\x20\x8b\xf3\xf0\xa9\x72\xa6\xc7\x55\xec\xa4\x67\x60\xc0\x98\x48\x71\xfe\x03\x72\x4a\x51\xfb\x54\x41\xc3\xcd\xd3\xd2\x4f\xa1\xb8\x12\x75\x10\xd6\xa4\x2c\xfe\x18\xb0\x8e\x80\x96\xed\x70\x2e\xf3\x3c",
+       66 },
+      { GCRY_MD_SHA3_512,
+       "\xab\xe3\x47\x2b\x54\xe7\x27\x34\xbd\xba\x7d\x91\x58\x73\x64\x64\x25\x1c\x4f\x21\xb3\x3f\xbb\xc9\x2d\x7f\xac\x9a\x35\xc4\xe3\x32\x2f\xf0\x1d\x23\x80\xcb\xaa\x4e\xf8\xfb\x07\xd2\x1a\x21\x28\xb7\xb9\xf5\xb6\xd9\xf3\x4e\x13\xf3\x9c\x7f\xfc\x2e\x72\xe4\x78\x88\x59\x9b\xa5",
+       "\xbc\xa9\xf0\x6b\x6b\x9a\xb8\xf7\x6c\x4f\x3d\xbe\x67\x7d\x5b\x4b\x31\x03\x42\x36\x44\x48\x4c\x77\xcd\xd8\xc5\xdd\x6c\x1a\x0b\xf7\x17\xc7\x6e\x83\xda\x9b\x2b\x4e\xdf\xe4\xcc\x13\x3c\x1f\xc8\x63\x96\xe8\xc3\xa9\xe4\x2f\xdd\x20\x51\x9f\xca\xa1\x99\x69\x18\x9f",
+       67 },
+      { GCRY_MD_SHA3_512,
+       "\x36\xf9\xf0\xa6\x5f\x2c\xa4\x98\xd7\x39\xb9\x44\xd6\xef\xf3\xda\x5e\xbb\xa5\x7e\x7d\x9c\x41\x59\x8a\x2b\x0e\x43\x80\xf3\xcf\x4b\x47\x9e\xc2\x34\x8d\x01\x5f\xfe\x62\x56\x27\x35\x11\x15\x4a\xfc\xf3\xb4\xb4\xbf\x09\xd6\xc4\x74\x4f\xdd\x0f\x62\xd7\x50\x79\xd4\x40\x70\x6b\x05",
+       "\xdc\xdf\x76\x17\xf7\x9d\xa8\x47\x5b\x3a\x4d\xb1\x30\x6c\x9c\xaf\x87\xf1\xae\x85\xec\x97\x72\x18\x92\xd8\xe2\x0d\x0e\x54\xec\x82\xee\x7a\x0f\x2d\x17\xf2\x1a\x61\xae\xcd\x89\xa6\xc4\xcf\x50\x19\xd7\xb8\x07\x74\x47\xef\xe0\x3d\xef\x52\x08\x01\x0a\x8a\x1e\x84",
+       68 },
+      { GCRY_MD_SHA3_512,
+       "\xab\xc8\x77\x63\xca\xe1\xca\x98\xbd\x8c\x5b\x82\xca\xba\x54\xac\x83\x28\x6f\x87\xe9\x61\x01\x28\xae\x4d\xe6\x8a\xc9\x5d\xf5\xe3\x29\xc3\x60\x71\x7b\xd3\x49\xf2\x6b\x87\x25\x28\x49\x2c\xa7\xc9\x4c\x2c\x1e\x1e\xf5\x6b\x74\xdb\xb6\x5c\x2a\xc3\x51\x98\x1f\xdb\x31\xd0\x6c\x77\xa4",
+       "\x9b\x8c\x71\x42\x18\x0f\x0e\xd8\x53\x59\xb6\xd1\x86\xae\x05\xb7\x7b\x2d\xb7\xc3\xe1\xf0\x66\x39\x2e\x73\x3b\x7e\xef\xfd\x7c\x11\xf7\xa6\xc0\xc5\x70\x27\x3a\x1f\x3f\xea\x1a\x09\x29\xd0\x17\xc7\xa4\xfa\x00\x17\x5b\x5a\xba\x76\x86\x1b\xca\x7e\xe8\x06\x45\x8b",
+       69 },
+      { GCRY_MD_SHA3_512,
+       "\x94\xf7\xca\x8e\x1a\x54\x23\x4c\x6d\x53\xcc\x73\x4b\xb3\xd3\x15\x0c\x8b\xa8\xc5\xf8\x80\xea\xb8\xd2\x5f\xed\x13\x79\x3a\x97\x01\xeb\xe3\x20\x50\x92\x86\xfd\x8e\x42\x2e\x93\x1d\x99\xc9\x8d\xa4\xdf\x7e\x70\xae\x44\x7b\xab\x8c\xff\xd9\x23\x82\xd8\xa7\x77\x60\xa2\x59\xfc\x4f\xbd\x72",
+       "\x3a\xb7\x3a\x0a\x75\xb9\x97\xc0\xee\x83\x29\xc3\x3e\x6e\xf1\x38\x9e\x98\x21\x71\x18\x67\xf7\x75\xaf\x29\x51\x7e\xdf\xfb\xe4\x10\xd0\x37\x14\x3c\x64\x31\xfd\xed\x3d\x8c\xe7\x28\x08\x6c\x35\x12\xe9\x4f\x03\x8b\x92\x43\xb5\x0c\xb8\x20\xdc\x24\x45\x53\x5d\x91",
+       70 },
+      { GCRY_MD_SHA3_512,
+       "\x13\xbd\x28\x11\xf6\xed\x2b\x6f\x04\xff\x38\x95\xac\xee\xd7\xbe\xf8\xdc\xd4\x5e\xb1\x21\x79\x1b\xc1\x94\xa0\xf8\x06\x20\x6b\xff\xc3\xb9\x28\x1c\x2b\x30\x8b\x1a\x72\x9c\xe0\x08\x11\x9d\xd3\x06\x6e\x93\x78\xac\xdc\xc5\x0a\x98\xa8\x2e\x20\x73\x88\x00\xb6\xcd\xdb\xe5\xfe\x96\x94\xad\x6d",
+       "\xde\xf4\xab\x6c\xda\x88\x39\x72\x9a\x03\xe0\x00\x84\x66\x04\xb1\x7f\x03\xc5\xd5\xd7\xec\x23\xc4\x83\x67\x0a\x13\xe1\x15\x73\xc1\xe9\x34\x7a\x63\xec\x69\xa5\xab\xb2\x13\x05\xf9\x38\x2e\xcd\xaa\xab\xc6\x85\x0f\x92\x84\x0e\x86\xf8\x8f\x4d\xab\xfc\xd9\x3c\xc0",
+       71 },
+      { GCRY_MD_SHA3_512,
+       "\x1e\xed\x9c\xba\x17\x9a\x00\x9e\xc2\xec\x55\x08\x77\x3d\xd3\x05\x47\x7c\xa1\x17\xe6\xd5\x69\xe6\x6b\x5f\x64\xc6\xbc\x64\x80\x1c\xe2\x5a\x84\x24\xce\x4a\x26\xd5\x75\xb8\xa6\xfb\x10\xea\xd3\xfd\x19\x92\xed\xdd\xee\xc2\xeb\xe7\x15\x0d\xc9\x8f\x63\xad\xc3\x23\x7e\xf5\x7b\x91\x39\x7a\xa8\xa7",
+       "\xa3\xe1\x68\xb0\xd6\xc1\x43\xee\x9e\x17\xea\xe9\x29\x30\xb9\x7e\x66\x00\x35\x6b\x73\xae\xbb\x5d\x68\x00\x5d\xd1\xd0\x74\x94\x45\x1a\x37\x05\x2f\x7b\x39\xff\x03\x0c\x1a\xe1\xd7\xef\xc4\xe0\xc3\x66\x7e\xb7\xa7\x6c\x62\x7e\xc1\x43\x54\xc4\xf6\xa7\x96\xe2\xc6",
+       72 },
+      { GCRY_MD_SHA3_512,
+       "\xba\x5b\x67\xb5\xec\x3a\x3f\xfa\xe2\xc1\x9d\xd8\x17\x6a\x2e\xf7\x5c\x0c\xd9\x03\x72\x5d\x45\xc9\xcb\x70\x09\xa9\x00\xc0\xb0\xca\x7a\x29\x67\xa9\x5a\xe6\x82\x69\xa6\xdb\xf8\x46\x6c\x7b\x68\x44\xa1\xd6\x08\xac\x66\x1f\x7e\xff\x00\x53\x8e\x32\x3d\xb5\xf2\xc6\x44\xb7\x8b\x2d\x48\xde\x1a\x08\xaa",
+       "\x63\x57\x41\xb3\x7f\x66\xcd\x5c\xe4\xdb\xd1\xf7\x8a\xcc\xd9\x07\xf9\x61\x46\xe7\x70\xb2\x39\x04\x6a\xfb\x91\x81\x91\x0b\x61\x2d\x0e\x65\x84\x1f\xf8\x66\x80\x6e\xed\x83\xc3\xae\x70\x12\xfc\x55\xe4\x2c\x3f\xfc\x9c\x6e\x3d\x03\xce\x28\x70\x44\x2f\x29\x3a\xb4",
+       73 },
+      { GCRY_MD_SHA3_512,
+       "\x0e\xfa\x26\xac\x56\x73\x16\x7d\xca\xca\xb8\x60\x93\x2e\xd6\x12\xf6\x5f\xf4\x9b\x80\xfa\x9a\xe6\x54\x65\xe5\x54\x2c\xb6\x20\x75\xdf\x1c\x5a\xe5\x4f\xba\x4d\xb8\x07\xbe\x25\xb0\x70\x03\x3e\xfa\x22\x3b\xdd\x5b\x1d\x3c\x94\xc6\xe1\x90\x9c\x02\xb6\x20\xd4\xb1\xb3\xa6\xc9\xfe\xd2\x4d\x70\x74\x96\x04",
+       "\xd6\x29\x9a\x21\xcb\x1b\x31\xf0\xa6\xeb\x67\xd8\x2d\x4e\x73\x82\x49\x01\x3b\x75\xc9\xbc\xb4\xa4\xfe\x41\x90\x36\xa6\x04\x3a\x71\x03\xe9\xca\x9b\x7d\x25\x75\x91\x77\xc4\xb6\x40\x01\x37\x70\x93\xcf\x39\xf3\x5c\x9b\x16\x25\xc6\x81\x93\x69\xfa\x37\x5f\xa4\x9d",
+       74 },
+      { GCRY_MD_SHA3_512,
+       "\xbb\xfd\x93\x3d\x1f\xd7\xbf\x59\x4a\xc7\xf4\x35\x27\x7d\xc1\x7d\x8d\x5a\x5b\x8e\x4d\x13\xd9\x6d\x2f\x64\xe7\x71\xab\xbd\x51\xa5\xa8\xae\xa7\x41\xbe\xcc\xbd\xdb\x17\x7b\xce\xa0\x52\x43\xeb\xd0\x03\xcf\xde\xae\x87\x7c\xca\x4d\xa9\x46\x05\xb6\x76\x91\x91\x9d\x8b\x03\x3f\x77\xd3\x84\xca\x01\x59\x3c\x1b",
+       "\x07\xf0\xa1\x84\x73\x4b\xa4\xbb\x72\x1f\x36\xd7\xb1\xb3\x83\xf6\xbf\x99\xcd\x5f\x75\x94\x1e\xcf\x1f\xf2\xb3\x25\xf0\x3a\xf9\x70\xd1\xdb\x1f\x03\x59\x75\x70\x20\x93\xf5\x9a\x76\x10\xbf\x05\x4d\x12\x01\x7e\xcd\x61\x09\x17\x7c\xf0\x61\xab\x14\x96\xf8\x78\x60",
+       75 },
+      { GCRY_MD_SHA3_512,
+       "\x90\x07\x89\x99\xfd\x3c\x35\xb8\xaf\xbf\x40\x66\xcb\xde\x33\x58\x91\x36\x5f\x0f\xc7\x5c\x12\x86\xcd\xd8\x8f\xa5\x1f\xab\x94\xf9\xb8\xde\xf7\xc9\xac\x58\x2a\x5d\xbc\xd9\x58\x17\xaf\xb7\xd1\xb4\x8f\x63\x70\x4e\x19\xc2\xba\xa4\xdf\x34\x7f\x48\xd4\xa6\xd6\x03\x01\x3c\x23\xf1\xe9\x61\x1d\x59\x5e\xba\xc3\x7c",
+       "\x89\x07\x0b\x8b\x1e\x32\x2c\xcf\x9d\x63\x07\xed\xc1\x1f\xc3\x4e\x13\x87\x4c\x49\x77\xda\x9f\x60\x35\xd0\x6f\xaf\x64\x7d\x7f\x7d\x54\xb8\x25\x0b\x54\x17\x44\x29\x8a\xac\xd4\xc5\x4d\x9b\x41\xb4\x08\x5d\xd3\x5c\x49\x1a\x46\x1d\x50\x4b\xdb\x42\xfc\x12\xf0\x3c",
+       76 },
+      { GCRY_MD_SHA3_512,
+       "\x64\x10\x5e\xca\x86\x35\x15\xc2\x0e\x7c\xfb\xaa\x0a\x0b\x88\x09\x04\x61\x64\xf3\x74\xd6\x91\xcd\xbd\x65\x08\xaa\xab\xc1\x81\x9f\x9a\xc8\x4b\x52\xba\xfc\x1b\x0f\xe7\xcd\xdb\xc5\x54\xb6\x08\xc0\x1c\x89\x04\xc6\x69\xd8\xdb\x31\x6a\x09\x53\xa4\xc6\x8e\xce\x32\x4e\xc5\xa4\x9f\xfd\xb5\x9a\x1b\xd6\xa2\x92\xaa\x0e",
+       "\x6c\x3f\xbe\x32\x55\x64\x45\xda\xd4\x30\xcf\x15\xfe\x12\x43\xb6\xab\x44\x34\x9e\xec\x2b\xe1\x13\x2b\x06\x80\xe5\xed\xf0\xb0\x8b\x55\xf1\xab\xe4\x73\x43\x9c\x5e\x07\x50\x13\x29\x96\x19\x5f\xd1\x20\xc2\x67\xb9\x10\x0c\x47\x77\x7b\x33\x91\x32\xec\x34\xcc\x80",
+       77 },
+      { GCRY_MD_SHA3_512,
+       "\xd4\x65\x4b\xe2\x88\xb9\xf3\xb7\x11\xc2\xd0\x20\x15\x97\x8a\x8c\xc5\x74\x71\xd5\x68\x0a\x09\x2a\xa5\x34\xf7\x37\x2c\x71\xce\xaa\xb7\x25\xa3\x83\xc4\xfc\xf4\xd8\xde\xaa\x57\xfc\xa3\xce\x05\x6f\x31\x29\x61\xec\xcf\x9b\x86\xf1\x49\x81\xba\x5b\xed\x6a\xb5\xb4\x49\x8e\x1f\x6c\x82\xc6\xca\xe6\xfc\x14\x84\x5b\x3c\x8a",
+       "\x6a\xe3\xe6\x56\xcf\x94\xdb\x10\xae\x3c\x18\x53\x62\xa6\x62\x5c\xec\x53\xe0\xba\x4d\xc7\xd1\x60\x8a\x3f\x2f\xca\x3c\x4f\x31\xf8\x9f\xe1\xb0\x6f\xe9\xca\x34\x5e\x3f\x5e\x96\x7a\x3e\xbc\xf6\xa1\xa1\x6e\x24\x52\x1d\x5c\x46\x90\xd9\xb6\x42\x48\x3a\xc7\xa8\x96",
+       78 },
+      { GCRY_MD_SHA3_512,
+       "\x12\xd9\x39\x48\x88\x30\x5a\xc9\x6e\x65\xf2\xbf\x0e\x1b\x18\xc2\x9c\x90\xfe\x9d\x71\x4d\xd5\x9f\x65\x1f\x52\xb8\x8b\x30\x08\xc5\x88\x43\x55\x48\x06\x6e\xa2\xfc\x4c\x10\x11\x18\xc9\x1f\x32\x55\x62\x24\xa5\x40\xde\x6e\xfd\xdb\xca\x29\x6e\xf1\xfb\x00\x34\x1f\x5b\x01\xfe\xcf\xc1\x46\xbd\xb2\x51\xb3\xbd\xad\x55\x6c\xd2",
+       "\xad\xa8\xe7\x8c\xe3\xe6\xd4\x47\xba\x2b\x7d\xcf\x98\x71\x8f\xe7\xd4\x3b\x38\xd6\x81\x17\xe5\x77\x9a\x41\xed\xd8\xfa\x72\x19\x8e\x3b\x3c\x1c\x02\x15\x92\x5b\xc9\xd0\x07\xfd\x2c\x35\x5e\xdd\x66\x8a\x0c\x27\xef\x0f\xf8\x9f\x76\xcf\x85\x36\x3d\x4c\x9e\xe0\x01",
+       79 },
+      { GCRY_MD_SHA3_512,
+       "\x87\x1a\x0d\x7a\x5f\x36\xc3\xda\x1d\xfc\xe5\x7a\xcd\x8a\xb8\x48\x7c\x27\x4f\xad\x33\x6b\xc1\x37\xeb\xd6\xff\x46\x58\xb5\x47\xc1\xdc\xfa\xb6\x5f\x03\x7a\xa5\x8f\x35\xef\x16\xaf\xf4\xab\xe7\x7b\xa6\x1f\x65\x82\x6f\x7b\xe6\x81\xb5\xb6\xd5\xa1\xea\x80\x85\xe2\xae\x9c\xd5\xcf\x09\x91\x87\x8a\x31\x1b\x54\x9a\x6d\x6a\xf2\x30",
+       "\x35\x69\xd9\xa0\x8d\xfb\x00\x01\xbe\x71\x39\x40\xc4\x64\xc1\x19\xf5\xa4\xc1\xb9\xff\x97\xd8\x29\x7d\x04\xc7\xb2\xdc\xe2\xd6\x84\xae\xe1\x64\x43\xc3\x2e\x5b\xb2\x35\x5a\xc8\xa3\x36\x24\x9d\x1b\xaa\xea\xb4\xfb\xd0\x4a\xb9\x82\xd6\xb1\x78\xdd\x0a\x5b\x5b\xc8",
+       80 },
+      { GCRY_MD_SHA3_512,
+       "\xe9\x0b\x4f\xfe\xf4\xd4\x57\xbc\x77\x11\xff\x4a\xa7\x22\x31\xca\x25\xaf\x6b\x2e\x20\x6f\x8b\xf8\x59\xd8\x75\x8b\x89\xa7\xcd\x36\x10\x5d\xb2\x53\x8d\x06\xda\x83\xba\xd5\xf6\x63\xba\x11\xa5\xf6\xf6\x1f\x23\x6f\xd5\xf8\xd5\x3c\x5e\x89\xf1\x83\xa3\xce\xc6\x15\xb5\x0c\x7c\x68\x1e\x77\x3d\x10\x9f\xf7\x49\x1b\x5c\xc2\x22\x96\xc5",
+       "\x13\x43\xe3\xcd\x16\x2d\x79\x86\x43\x1b\xab\xe6\x63\x83\xb8\x40\x29\x66\x56\x91\xe3\x6c\xaf\x97\xcd\xac\xa1\x7e\xe9\xe9\x7d\x74\x20\x1d\x2a\x82\x8d\x72\xe9\xfb\xbd\x5e\x07\x83\x1d\x90\xf0\x9e\xaf\x3c\x86\x3b\xd1\x02\xcd\xb1\xed\xeb\xc8\xad\x58\xa5\x3e\xce",
+       81 },
+      { GCRY_MD_SHA3_512,
+       "\xe7\x28\xde\x62\xd7\x58\x56\x50\x0c\x4c\x77\xa4\x28\x61\x2c\xd8\x04\xf3\x0c\x3f\x10\xd3\x6f\xb2\x19\xc5\xca\x0a\xa3\x07\x26\xab\x19\x0e\x5f\x3f\x27\x9e\x07\x33\xd7\x7e\x72\x67\xc1\x7b\xe2\x7d\x21\x65\x0a\x9a\x4d\x1e\x32\xf6\x49\x62\x76\x38\xdb\xad\xa9\x70\x2c\x7c\xa3\x03\x26\x9e\xd1\x40\x14\xb2\xf3\xcf\x8b\x89\x4e\xac\x85\x54",
+       "\xbb\xa0\x1d\xbe\xa9\x66\x0f\x9c\x2a\xd7\x44\x60\xb6\x7a\x82\x44\x07\x01\xeb\x99\x51\x43\xff\xcf\x74\x34\xb5\xd2\xde\x4e\x35\xc8\x2c\xc7\x57\xdf\x77\x6d\x46\x19\x9d\xd8\xe7\x35\x5a\xeb\x1f\x42\xa8\x8f\x6f\x0b\xb5\x0f\xd2\x39\xc7\x38\x98\x15\x6e\x4d\xdb\xbc",
+       82 },
+      { GCRY_MD_SHA3_512,
+       "\x63\x48\xf2\x29\xe7\xb1\xdf\x3b\x77\x0c\x77\x54\x4e\x51\x66\xe0\x81\x85\x0f\xa1\xc6\xc8\x81\x69\xdb\x74\xc7\x6e\x42\xeb\x98\x3f\xac\xb2\x76\xad\x6a\x0d\x1f\xa7\xb5\x0d\x3e\x3b\x6f\xcd\x79\x9e\xc9\x74\x70\x92\x0a\x7a\xbe\xd4\x7d\x28\x8f\xf8\x83\xe2\x4c\xa2\x1c\x7f\x80\x16\xb9\x3b\xb9\xb9\xe0\x78\xbd\xb9\x70\x3d\x2b\x78\x1b\x61\x6e",
+       "\x32\x68\xbc\x24\xe2\x93\x92\xdd\xa1\x67\x7b\x7a\x3c\xe3\x11\x19\x94\x48\x2d\x17\xba\xd1\xc1\x50\xac\x88\x5f\x1d\x29\xc3\x08\x65\x7c\x69\xfd\x4f\x7c\xe5\x96\x7d\x04\xfc\xcb\x92\x0d\xac\xb0\x0d\x0c\xe0\x95\x36\xee\x92\xa6\x66\x4c\xb2\x0e\x69\x2d\x91\xd8\xce",
+       83 },
+      { GCRY_MD_SHA3_512,
+       "\x4b\x12\x7f\xde\x5d\xe7\x33\xa1\x68\x0c\x27\x90\x36\x36\x27\xe6\x3a\xc8\xa3\xf1\xb4\x70\x7d\x98\x2c\xae\xa2\x58\x65\x5d\x9b\xf1\x8f\x89\xaf\xe5\x41\x27\x48\x2b\xa0\x1e\x08\x84\x55\x94\xb6\x71\x30\x6a\x02\x5c\x9a\x5c\x5b\x6f\x93\xb0\xa3\x95\x22\xdc\x87\x74\x37\xbe\x5c\x24\x36\xcb\xf3\x00\xce\x7a\xb6\x74\x79\x34\xfc\xfc\x30\xae\xaa\xf6",
+       "\xec\x13\xe3\x90\xfa\x65\xfd\xc1\x10\x54\xe3\x2c\x9f\x5b\xf5\xe6\xe9\x7f\xbc\x34\xc2\x80\x89\x34\x6f\xf2\x2d\x97\x62\xbe\xbf\x6a\x14\xfa\x7f\x9c\x2e\x66\x43\xd1\xed\x7e\xc6\x92\x5d\x0f\xa2\x09\x8f\x81\x49\x05\x8e\x99\xd0\x2a\xd5\xcb\x61\xb4\xcc\xba\x64\x67",
+       84 },
+      { GCRY_MD_SHA3_512,
+       "\x08\x46\x1f\x00\x6c\xff\x4c\xc6\x4b\x75\x2c\x95\x72\x87\xe5\xa0\xfa\xab\xc0\x5c\x9b\xff\x89\xd2\x3f\xd9\x02\xd3\x24\xc7\x99\x03\xb4\x8f\xcb\x8f\x8f\x4b\x01\xf3\xe4\xdd\xb4\x83\x59\x3d\x25\xf0\x00\x38\x66\x98\xf5\xad\xe7\xfa\xad\xe9\x61\x5f\xdc\x50\xd3\x27\x85\xea\x51\xd4\x98\x94\xe4\x5b\xaa\x3d\xc7\x07\xe2\x24\x68\x8c\x64\x08\xb6\x8b\x11",
+       "\x6f\xd5\xa3\x34\xd4\xb7\xf9\xc7\x2a\x8d\xb1\x29\x2c\xc8\xf1\x9b\xf2\xa0\x0f\x5c\x22\x6c\x16\x36\x24\x80\x24\x72\x3c\xb8\x76\x07\x0a\x96\x57\xf4\x8a\xb3\xb1\xd4\x22\x92\x02\xb7\xbb\xc6\x40\x53\xa4\x8c\x3f\xf6\xb9\x3a\xb1\x1a\x2a\xf3\x23\x77\x21\xc9\xcc\x09",
+       85 },
+      { GCRY_MD_SHA3_512,
+       "\x68\xc8\xf8\x84\x9b\x12\x0e\x6e\x0c\x99\x69\xa5\x86\x6a\xf5\x91\xa8\x29\xb9\x2f\x33\xcd\x9a\x4a\x31\x96\x95\x7a\x14\x8c\x49\x13\x8e\x1e\x2f\x5c\x76\x19\xa6\xd5\xed\xeb\xe9\x95\xac\xd8\x1e\xc8\xbb\x9c\x7b\x9c\xfc\xa6\x78\xd0\x81\xea\x9e\x25\xa7\x5d\x39\xdb\x04\xe1\x8d\x47\x59\x20\xce\x82\x8b\x94\xe7\x22\x41\xf2\x4d\xb7\x25\x46\xb3\x52\xa0\xe4",
+       "\x01\x6c\x80\xcb\xab\xed\x07\xc5\x0f\x2c\x1b\x67\x7c\x43\xe5\x2d\xe8\xd1\x17\x51\xe5\x4e\x59\x6e\x0c\x04\xb3\x83\x7a\x7e\x34\xa9\xff\x5d\x2e\x98\xe7\xc5\x81\x82\x87\x9c\x15\x84\x7d\x18\xdc\xe8\x8e\xa9\x00\x33\x7b\xc4\x48\x11\x2e\x98\xce\x11\x18\x82\x0c\x58",
+       86 },
+      { GCRY_MD_SHA3_512,
+       "\xb8\xd5\x64\x72\x95\x4e\x31\xfb\x54\xe2\x8f\xca\x74\x3f\x84\xd8\xdc\x34\x89\x1c\xb5\x64\xc6\x4b\x08\xf7\xb7\x16\x36\xde\xbd\x64\xca\x1e\xdb\xdb\xa7\xfc\x5c\x3e\x40\x04\x9c\xe9\x82\xbb\xa8\xc7\xe0\x70\x30\x34\xe3\x31\x38\x46\x95\xe9\xde\x76\xb5\x10\x4f\x2f\xbc\x45\x35\xec\xbe\xeb\xc3\x3b\xc2\x7f\x29\xf1\x8f\x6f\x27\xe8\x02\x3b\x0f\xbb\x6f\x56\x3c",
+       "\xa4\xe8\x5f\xf8\x64\x82\xc1\x0c\x6a\xaa\xbc\x79\xa5\x73\xcb\xf8\x9a\x0a\x92\x71\x10\xd7\x55\xf2\x2b\x52\x9b\xd7\xcf\x3f\x6c\xc6\xcb\x98\x61\xe5\x09\x65\x72\x42\xa7\x8b\x0c\x0a\xf7\x8f\xf9\x7a\xbc\xc1\xa8\x38\x82\x70\xd6\xc8\xd3\x02\xd4\x5c\x9b\xa5\x84\x04",
+       87 },
+      { GCRY_MD_SHA3_512,
+       "\x0d\x58\xac\x66\x5f\xa8\x43\x42\xe6\x0c\xef\xee\x31\xb1\xa4\xea\xcd\xb0\x92\xf1\x22\xdf\xc6\x83\x09\x07\x7a\xed\x1f\x3e\x52\x8f\x57\x88\x59\xee\x9e\x4c\xef\xb4\xa7\x28\xe9\x46\x32\x49\x27\xb6\x75\xcd\x4f\x4a\xc8\x4f\x64\xdb\x3d\xac\xfe\x85\x0c\x1d\xd1\x87\x44\xc7\x4c\xec\xcd\x9f\xe4\xdc\x21\x40\x85\x10\x8f\x40\x4e\xab\x6d\x8f\x45\x2b\x54\x42\xa4\x7d",
+       "\xb9\x7a\xfb\x77\xd3\x9f\x89\x04\xae\x8a\x51\x29\xa7\xdd\xc8\xec\x92\x90\xac\x40\x35\x6e\x1b\x53\xdd\x05\x7f\xa7\x58\x4b\xa3\x1a\xfa\xf9\xef\x5b\x65\x70\x97\xfc\x11\x5e\xaa\x33\xe7\xed\xe3\x6d\xd0\x08\x32\xd6\x77\xeb\xd0\x7c\x34\xb0\x71\xe7\x35\x80\xdd\x3a",
+       88 },
+      { GCRY_MD_SHA3_512,
+       "\x17\x55\xe2\xd2\xe5\xd1\xc1\xb0\x15\x64\x56\xb5\x39\x75\x3f\xf4\x16\x65\x1d\x44\x69\x8e\x87\x00\x2d\xcf\x61\xdc\xfa\x2b\x4e\x72\xf2\x64\xd9\xad\x59\x1d\xf1\xfd\xee\x7b\x41\xb2\xeb\x00\x28\x3c\x5a\xeb\xb3\x41\x13\x23\xb6\x72\xea\xa1\x45\xc5\x12\x51\x85\x10\x4f\x20\xf3\x35\x80\x4b\x02\x32\x5b\x6d\xea\x65\x60\x3f\x34\x9f\x4d\x5d\x8b\x78\x2d\xd3\x46\x9c\xcd",
+       "\xab\x2f\xc5\x9a\x43\xa2\x66\x6c\x92\x06\xb9\x31\x74\x79\x28\x5e\x66\x0b\x67\x0c\x6f\x11\x1f\x99\x95\x56\xe8\x15\x1e\x0e\xb8\xd1\x2b\xc8\x2c\x9a\x7e\x7b\x3f\x8d\x6f\x38\x2a\x8d\x96\x77\x5e\xa4\x17\xf7\x54\xff\x55\x2e\x1b\xac\x27\x1f\xbd\x08\x24\x0f\x1b\x86",
+       89 },
+      { GCRY_MD_SHA3_512,
+       "\xb1\x80\xde\x1a\x61\x11\x11\xee\x75\x84\xba\x2c\x4b\x02\x05\x98\xcd\x57\x4a\xc7\x7e\x40\x4e\x85\x3d\x15\xa1\x01\xc6\xf5\xa2\xe5\xc8\x01\xd7\xd8\x5d\xc9\x52\x86\xa1\x80\x4c\x87\x0b\xb9\xf0\x0f\xd4\xdc\xb0\x3a\xa8\x32\x82\x75\x15\x88\x19\xdc\xad\x72\x53\xf3\xe3\xd2\x37\xae\xaa\x79\x79\x26\x8a\x5d\xb1\xc6\xce\x08\xa9\xec\x7c\x25\x79\x78\x3c\x8a\xfc\x1f\x91\xa7",
+       "\x0a\x67\x3a\xf8\x4e\x2d\x23\x17\xb8\x0a\x87\x3b\xfe\x38\xb2\x52\x87\x27\x08\xb3\x8a\xf9\xb9\x56\xe3\x55\x4a\xc2\xdc\xe2\xf7\x7c\x81\x55\x93\xd9\x99\x30\xe7\xaa\x66\x6c\x57\xb5\x97\x30\x71\x2e\x5c\x4a\x9b\x57\x84\x9e\xdd\xd7\x12\xa3\x78\x04\x0e\xb8\x24\xd8",
+       90 },
+      { GCRY_MD_SHA3_512,
+       "\xcf\x35\x83\xcb\xdf\xd4\xcb\xc1\x70\x63\xb1\xe7\xd9\x0b\x02\xf0\xe6\xe2\xee\x05\xf9\x9d\x77\xe2\x4e\x56\x03\x92\x53\x5e\x47\xe0\x50\x77\x15\x7f\x96\x81\x35\x44\xa1\x70\x46\x91\x4f\x9e\xfb\x64\x76\x2a\x23\xcf\x7a\x49\xfe\x52\xa0\xa4\xc0\x1c\x63\x0c\xfe\x87\x27\xb8\x1f\xb9\x9a\x89\xff\x7c\xc1\x1d\xca\x51\x73\x05\x7e\x04\x17\xb8\xfe\x7a\x9e\xfb\xa6\xd9\x5c\x55\x5f",
+       "\x1d\x34\x64\x54\x63\xeb\xbd\x93\x2c\x73\x0e\x59\x3d\x9c\x10\x8a\xa8\x68\x07\xdb\x67\x85\xf0\x5c\x4c\xe8\x0f\x3e\x83\x02\xf8\x7e\xfb\xcc\xb1\xab\x88\x4e\x25\xf1\xdc\xd5\x48\x5d\x38\x55\x02\x99\x5e\x7a\xbe\x2e\xf1\x1b\xd3\x46\x9e\x03\x6d\x7e\xb9\x3b\x4f\x39",
+       91 },
+      { GCRY_MD_SHA3_512,
+       "\x07\x2f\xc0\x23\x40\xef\x99\x11\x5b\xad\x72\xf9\x2c\x01\xe4\xc0\x93\xb9\x59\x9f\x6c\xfc\x45\xcb\x38\x0e\xe6\x86\xcb\x5e\xb0\x19\xe8\x06\xab\x9b\xd5\x5e\x63\x4a\xb1\x0a\xa6\x2a\x95\x10\xcc\x06\x72\xcd\x3e\xdd\xb5\x89\xc7\xdf\x2b\x67\xfc\xd3\x32\x9f\x61\xb1\xa4\x44\x1e\xca\x87\xa3\x3c\x8f\x55\xda\x4f\xbb\xad\x5c\xf2\xb2\x52\x7b\x8e\x98\x3b\xb3\x1a\x2f\xad\xec\x75\x23",
+       "\x3f\x57\xfa\x91\x5a\x78\x2e\x3c\xc6\x98\x15\xba\x21\x9f\x42\xaa\x2c\x22\x2c\xd7\xf3\x09\xf1\x0a\xf8\x43\x38\x4b\x3d\x39\x39\xaa\x0b\x92\xdd\x95\x71\x68\x6c\x79\x61\xe0\x6b\xfe\xe8\x18\x12\x7f\xc5\xb5\xf3\x2c\x67\xf4\xaa\x2a\xf1\x0d\x4f\xa3\x8f\x65\xe9\x0d",
+       92 },
+      { GCRY_MD_SHA3_512,
+       "\x76\xee\xcf\x95\x6a\x52\x64\x9f\x87\x75\x28\x14\x6d\xe3\x3d\xf2\x49\xcd\x80\x0e\x21\x83\x0f\x65\xe9\x0f\x0f\x25\xca\x9d\x65\x40\xfd\xe4\x06\x03\x23\x0e\xca\x67\x60\xf1\x13\x9c\x7f\x26\x8d\xeb\xa2\x06\x06\x31\xee\xa9\x2b\x1f\xff\x05\xf9\x3f\xd5\x57\x2f\xbe\x29\x57\x9e\xcd\x48\xbc\x3a\x8d\x6c\x2e\xb4\xa6\xb2\x6e\x38\xd6\xc5\xfb\xf2\xc0\x80\x44\xae\xea\x47\x0a\x8f\x2f\x26",
+       "\x15\x13\x82\xca\x35\xfb\x20\xb8\x95\xa9\xdc\x07\x4d\x68\x7f\x2f\x33\x5e\xaf\x57\x45\x6d\x35\x7a\x68\x5e\xf7\x52\xda\x59\x17\x4d\x3f\x23\x9a\xa9\xe0\x4f\x14\x21\x38\xd9\x41\x3b\x21\x90\x46\x65\xef\x4d\xf2\xf6\x3e\x66\x3b\x49\x03\x83\x66\x04\x81\xf7\x83\x62",
+       93 },
+      { GCRY_MD_SHA3_512,
+       "\x7a\xdc\x0b\x66\x93\xe6\x1c\x26\x9f\x27\x8e\x69\x44\xa5\xa2\xd8\x30\x09\x81\xe4\x00\x22\xf8\x39\xac\x64\x43\x87\xbf\xac\x90\x86\x65\x00\x85\xc2\xcd\xc5\x85\xfe\xa4\x7b\x9d\x2e\x52\xd6\x5a\x2b\x29\xa7\xdc\x37\x04\x01\xef\x5d\x60\xdd\x0d\x21\xf9\xe2\xb9\x0f\xae\x91\x93\x19\xb1\x4b\x8c\x55\x65\xb0\x42\x3c\xef\xb8\x27\xd5\xf1\x20\x33\x02\xa9\xd0\x15\x23\x49\x8a\x4d\xb1\x03\x74",
+       "\x23\xaa\x4b\x74\xc5\x4e\x8f\x45\x00\x54\xb6\xab\xdb\xc6\xf6\xc3\xe4\x43\x66\xaf\xce\xc0\x99\xb1\x55\x77\x5d\xe0\x40\xbf\x3b\x9c\xdd\x0b\x87\x5f\x9d\x49\x0f\xaa\x69\x4f\x18\xcc\xbf\xfe\xc6\xca\xb7\xde\x57\xa5\x9e\xc6\x32\x72\x40\xac\x59\xd6\x2d\x50\xb2\x1c",
+       94 },
+      { GCRY_MD_SHA3_512,
+       "\xe1\xff\xfa\x98\x26\xcc\xe8\xb8\x6b\xcc\xef\xb8\x79\x4e\x48\xc4\x6c\xdf\x37\x20\x13\xf7\x82\xec\xed\x1e\x37\x82\x69\xb7\xbe\x2b\x7b\xf5\x13\x74\x09\x22\x61\xae\x12\x0e\x82\x2b\xe6\x85\xf2\xe7\xa8\x36\x64\xbc\xfb\xe3\x8f\xe8\x63\x3f\x24\xe6\x33\xff\xe1\x98\x8e\x1b\xc5\xac\xf5\x9a\x58\x70\x79\xa5\x7a\x91\x0b\xda\x60\x06\x0e\x85\xb5\xf5\xb6\xf7\x76\xf0\x52\x96\x39\xd9\xcc\xe4\xbd",
+       "\x36\x05\xce\xc1\x6a\x7a\xa8\xb2\x52\x54\x79\xfc\xc1\x29\x54\x11\xb6\xa9\x52\xdc\xe2\x33\xc9\xac\xc8\x56\xd6\xd1\x7c\x98\x12\xc9\x20\x17\x85\x00\xcd\x00\x28\xb5\x99\x8d\x07\x04\x6c\x6a\x5c\xf3\x98\xee\x1e\xc9\x7d\xf9\x18\x2c\x33\xfc\xa8\x66\x47\x86\x18\x78",
+       95 },
+      { GCRY_MD_SHA3_512,
+       "\x69\xf9\xab\xba\x65\x59\x2e\xe0\x1d\xb4\xdc\xe5\x2d\xba\xb9\x0b\x08\xfc\x04\x19\x36\x02\x79\x2e\xe4\xda\xa2\x63\x03\x3d\x59\x08\x15\x87\xb0\x9b\xbe\x49\xd0\xb4\x9c\x98\x25\xd2\x28\x40\xb2\xff\x5d\x9c\x51\x55\xf9\x75\xf8\xf2\xc2\xe7\xa9\x0c\x75\xd2\xe4\xa8\x04\x0f\xe3\x9f\x63\xbb\xaf\xb4\x03\xd9\xe2\x8c\xc3\xb8\x6e\x04\xe3\x94\xa9\xc9\xe8\x06\x5b\xd3\xc8\x5f\xa9\xf0\xc7\x89\x16\x00",
+       "\xc5\xa5\x26\xd7\x58\x16\xd4\x1b\x53\xbf\x16\x4b\x04\x67\xe0\xb8\x0a\x99\x84\xd1\x83\x0e\xdb\x9d\x49\xf7\xec\x3e\xcf\xef\xb0\x1a\x2c\x82\x4a\x0f\x64\x57\x53\xaa\x46\x3d\x56\x7c\xb2\x78\x2a\xfc\xb2\xb2\xc2\x10\x2e\xa6\x64\xc5\x69\x98\xf7\x90\x62\x63\x6f\xc1",
+       96 },
+      { GCRY_MD_SHA3_512,
+       "\x38\xa1\x0a\x35\x2c\xa5\xae\xdf\xa8\xe1\x9c\x64\x78\x7d\x8e\x9c\x3a\x75\xdb\xf3\xb8\x67\x4b\xfa\xb2\x9b\x5d\xbf\xc1\x5a\x63\xd1\x0f\xae\x66\xcd\x1a\x6e\x6d\x24\x52\xd5\x57\x96\x7e\xaa\xd8\x9a\x4c\x98\x44\x97\x87\xb0\xb3\x16\x4c\xa5\xb7\x17\xa9\x3f\x24\xeb\x0b\x50\x6c\xeb\x70\xcb\xbc\xb8\xd7\x2b\x2a\x72\x99\x3f\x90\x9a\xad\x92\xf0\x44\xe0\xb5\xa2\xc9\xac\x9c\xb1\x6a\x0c\xa2\xf8\x1f\x49",
+       "\xb2\x39\x94\x1a\x31\x10\x0a\xb1\xb2\x4a\xf2\xd1\xfe\xf1\x49\xdb\xa3\x00\x10\x5a\x31\xb7\x2a\x8f\x21\x7e\x30\x6a\x06\x02\xd7\x22\xcc\xd5\x93\xa2\x3e\x65\x39\xd3\xe4\x19\x5a\x7e\x12\xca\x19\xae\x2b\xae\x8b\x83\x99\xf7\xa9\xd5\x0d\xb3\x02\x16\xe9\x73\xf2\xbf",
+       97 },
+      { GCRY_MD_SHA3_512,
+       "\x6d\x8c\x6e\x44\x9b\xc1\x36\x34\xf1\x15\x74\x9c\x24\x8c\x17\xcd\x14\x8b\x72\x15\x7a\x2c\x37\xbf\x89\x69\xea\x83\xb4\xd6\xba\x8c\x0e\xe2\x71\x1c\x28\xee\x11\x49\x5f\x43\x04\x95\x96\x52\x0c\xe4\x36\x00\x4b\x02\x6b\x6c\x1f\x72\x92\xb9\xc4\x36\xb0\x55\xcb\xb7\x2d\x53\x0d\x86\x0d\x12\x76\xa1\x50\x2a\x51\x40\xe3\xc3\xf5\x4a\x93\x66\x3e\x4d\x20\xed\xec\x32\xd2\x84\xe2\x55\x64\xf6\x24\x95\x5b\x52",
+       "\xd6\xab\x0d\x0b\x41\x6d\x1b\xbc\x85\x47\x9f\x98\x50\x58\x57\x61\xb9\x17\x75\xa6\x03\x07\xaf\xac\xf7\x09\x43\xfe\xb5\x86\x57\x74\x0f\xe3\x5d\xc7\x60\xab\x9c\xfa\x67\x2c\x6b\x55\x52\xaa\x67\xbf\xa1\xf0\xd6\xa6\xf9\x43\xb3\x91\x2c\x22\x9b\x8e\x01\x55\xc0\x02",
+       98 },
+      { GCRY_MD_SHA3_512,
+       "\x6e\xfc\xbc\xaf\x45\x1c\x12\x9d\xbe\x00\xb9\xce\xf0\xc3\x74\x9d\x3e\xe9\xd4\x1c\x7b\xd5\x00\xad\xe4\x0c\xdc\x65\xde\xdb\xbb\xad\xb8\x85\xa5\xb1\x4b\x32\xa0\xc0\xd0\x87\x82\x52\x01\xe3\x03\x28\x8a\x73\x38\x42\xfa\x7e\x59\x9c\x0c\x51\x4e\x07\x8f\x05\xc8\x21\xc7\xa4\x49\x8b\x01\xc4\x00\x32\xe9\xf1\x87\x2a\x1c\x92\x5f\xa1\x7c\xe2\x53\xe8\x93\x5e\x4c\x3c\x71\x28\x22\x42\xcb\x71\x6b\x20\x89\xcc\xc1",
+       "\xbc\x0a\x28\x45\x03\x68\xc2\x88\x01\x3e\x2e\xb1\x19\x6e\x58\x93\x3c\xe0\x58\x69\xcb\x55\xfa\x2b\xda\x61\xd9\xd9\x2f\x83\xb9\x03\xe5\x9d\xde\x0b\x92\x7c\xa6\xdb\xc4\x6f\x5a\xf2\xeb\x7e\x88\x31\xe8\x66\x88\x88\xbf\xea\x46\xd7\x8f\x4d\x27\x48\x18\xd5\x63\x28",
+       99 },
+      { GCRY_MD_SHA3_512,
+       "\x43\x3c\x53\x03\x13\x16\x24\xc0\x02\x1d\x86\x8a\x30\x82\x54\x75\xe8\xd0\xbd\x30\x52\xa0\x22\x18\x03\x98\xf4\xca\x44\x23\xb9\x82\x14\xb6\xbe\xaa\xc2\x1c\x88\x07\xa2\xc3\x3f\x8c\x93\xbd\x42\xb0\x92\xcc\x1b\x06\xce\xdf\x32\x24\xd5\xed\x1e\xc2\x97\x84\x44\x4f\x22\xe0\x8a\x55\xaa\x58\x54\x2b\x52\x4b\x02\xcd\x3d\x5d\x5f\x69\x07\xaf\xe7\x1c\x5d\x74\x62\x22\x4a\x3f\x9d\x9e\x53\xe7\xe0\x84\x6d\xcb\xb4\xce",
+       "\x78\x20\xa2\x00\x56\xdf\x74\x1e\x19\xff\x4d\x15\x06\x63\x48\x8c\xf8\x6f\x93\x63\x53\xe9\x9e\x25\xb9\x32\x20\xf5\x23\x0b\xfb\xc1\x33\x63\xb4\x58\xd6\xdb\x92\xf9\xd2\x11\xd7\x05\x36\x2b\x01\x78\x2e\xc1\x18\xac\xfe\x53\xba\xe4\xc6\xac\x2c\x7e\x5d\x01\x11\xfb",
+       100 },
+      { GCRY_MD_SHA3_512,
+       "\xa8\x73\xe0\xc6\x7c\xa6\x39\x02\x6b\x66\x83\x00\x8f\x7a\xa6\x32\x4d\x49\x79\x55\x0e\x9b\xce\x06\x4c\xa1\xe1\xfb\x97\xa3\x0b\x14\x7a\x24\xf3\xf6\x66\xc0\xa7\x2d\x71\x34\x8e\xde\x70\x1c\xf2\xd1\x7e\x22\x53\xc3\x4d\x1e\xc3\xb6\x47\xdb\xce\xf2\xf8\x79\xf4\xeb\x88\x1c\x48\x30\xb7\x91\x37\x8c\x90\x1e\xb7\x25\xea\x5c\x17\x23\x16\xc6\xd6\x06\xe0\xaf\x7d\xf4\xdf\x7f\x76\xe4\x90\xcd\x30\xb2\xba\xdf\x45\x68\x5f",
+       "\x09\x84\xa4\x32\x86\xa3\xcb\x22\xfb\x59\xf7\x88\x0e\x11\x4e\x23\xe3\xad\x3b\x0d\x43\x02\x5f\x39\x87\xd0\xaa\x6f\xa8\xe5\x3e\x60\x66\xf8\x0f\x47\x69\x24\x1d\xcd\x06\x24\x31\xc7\xf6\x71\x2c\x57\xc6\xe3\x27\x5e\xd3\xf2\xbc\x59\x1d\xb6\xdc\x20\xe5\xbe\x09\x53",
+       101 },
+      { GCRY_MD_SHA3_512,
+       "\x00\x69\x17\xb6\x4f\x9d\xcd\xf1\xd2\xd8\x7c\x8a\x61\x73\xb6\x4f\x65\x87\x16\x8e\x80\xfa\xa8\x0f\x82\xd8\x4f\x60\x30\x1e\x56\x1e\x31\x2d\x9f\xbc\xe6\x2f\x39\xa6\xfb\x47\x6e\x01\xe9\x25\xf2\x6b\xcc\x91\xde\x62\x14\x49\xbe\x65\x04\xc5\x04\x83\x0a\xae\x39\x40\x96\xc8\xfc\x76\x94\x65\x10\x51\x36\x5d\x4e\xe9\x07\x01\x01\xec\x9b\x68\x08\x6f\x2e\xa8\xf8\xab\x7b\x81\x1e\xa8\xad\x93\x4d\x5c\x9b\x62\xc6\x0a\x47\x71",
+       "\xa6\x30\x04\x97\xf6\x50\x85\x9c\xd7\x44\x67\x98\x85\xcd\x54\x37\xa6\x4c\xc3\x96\x15\x74\xdc\xce\x65\xe1\x61\x16\x16\xa9\xf9\x71\x90\xf3\x91\x30\xba\x53\x20\x94\xbd\x62\x46\x4d\x0b\x8b\x52\x29\x7a\x2c\x9c\x27\x9b\x2c\x98\x60\xc0\x72\xcd\x44\x44\x9a\x9c\xdf",
+       102 },
+      { GCRY_MD_SHA3_512,
+       "\xf1\x3c\x97\x2c\x52\xcb\x3c\xc4\xa4\xdf\x28\xc9\x7f\x2d\xf1\x1c\xe0\x89\xb8\x15\x46\x6b\xe8\x88\x63\x24\x3e\xb3\x18\xc2\xad\xb1\xa4\x17\xcb\x10\x41\x30\x85\x98\x54\x17\x20\x19\x7b\x9b\x1c\xb5\xba\x23\x18\xbd\x55\x74\xd1\xdf\x21\x74\xaf\x14\x88\x41\x49\xba\x9b\x2f\x44\x6d\x60\x9d\xf2\x40\xce\x33\x55\x99\x95\x7b\x8e\xc8\x08\x76\xd9\xa0\x85\xae\x08\x49\x07\xbc\x59\x61\xb2\x0b\xf5\xf6\xca\x58\xd5\xda\xb3\x8a\xdb",
+       "\xe2\x05\x28\x84\xd1\x12\x23\x88\x07\xc0\x2c\x13\x52\x47\xf7\x6e\x0e\x39\x4b\xd6\x58\x3b\xa8\x3e\xd2\x73\x1c\xf6\x8f\x05\x72\x76\x27\x2b\x89\x1a\x76\x1c\xde\xc6\xd8\xad\x2e\x3f\x33\xe8\x6a\xe9\xd9\xa2\x34\x68\x2b\xce\x7a\x53\x81\x62\x35\x69\x2d\x2c\xf8\x21",
+       103 },
+      { GCRY_MD_SHA3_512,
+       "\xe3\x57\x80\xeb\x97\x99\xad\x4c\x77\x53\x5d\x4d\xdb\x68\x3c\xf3\x3e\xf3\x67\x71\x53\x27\xcf\x4c\x4a\x58\xed\x9c\xbd\xcd\xd4\x86\xf6\x69\xf8\x01\x89\xd5\x49\xa9\x36\x4f\xa8\x2a\x51\xa5\x26\x54\xec\x72\x1b\xb3\xaa\xb9\x5d\xce\xb4\xa8\x6a\x6a\xfa\x93\x82\x6d\xb9\x23\x51\x7e\x92\x8f\x33\xe3\xfb\xa8\x50\xd4\x56\x60\xef\x83\xb9\x87\x6a\xcc\xaf\xa2\xa9\x98\x7a\x25\x4b\x13\x7c\x6e\x14\x0a\x21\x69\x1e\x10\x69\x41\x38\x48",
+       "\xff\x6a\x7d\x0e\xfe\xa4\x5e\x5f\x0a\xbc\xb1\x73\xfc\xe2\xbe\x76\xb5\x2d\x0f\x3f\xc3\x63\xaf\xe3\x1d\x21\x94\x72\x74\x2d\x73\xe5\x6c\xee\x2a\xb9\x1a\x94\xd4\x13\x35\xc4\xfa\x25\xcb\xdd\x6e\xbd\x1a\x08\x76\x37\xca\xa2\x50\x99\xd5\xa9\xd6\x06\x93\xcf\x62\xb9",
+       104 },
+      { GCRY_MD_SHA3_512,
+       "\x64\xec\x02\x1c\x95\x85\xe0\x1f\xfe\x6d\x31\xbb\x50\xd4\x4c\x79\xb6\x99\x3d\x72\x67\x81\x63\xdb\x47\x49\x47\xa0\x53\x67\x46\x19\xd1\x58\x01\x6a\xdb\x24\x3f\x5c\x8d\x50\xaa\x92\xf5\x0a\xb3\x6e\x57\x9f\xf2\xda\xbb\x78\x0a\x2b\x52\x93\x70\xda\xa2\x99\x20\x7c\xfb\xcd\xd3\xa9\xa2\x50\x06\xd1\x9c\x4f\x1f\xe3\x3e\x4b\x1e\xae\xc3\x15\xd8\xc6\xee\x1e\x73\x06\x23\xfd\x19\x41\x87\x5b\x92\x4e\xb5\x7d\x6d\x0c\x2e\xdc\x4e\x78\xd6",
+       "\x41\x83\xf9\x67\x59\xe7\xc0\x62\x8f\x2f\xc8\x19\x79\x27\x4f\x42\x11\x1a\x43\xbd\x5d\xbb\x36\x85\xbb\x21\x70\x4c\xe6\xb0\xed\x3d\x16\x4d\xec\xf2\x8a\x3a\x99\x1b\x30\x3e\x1d\x7b\x86\xe2\xb1\x75\xba\x89\x94\x5a\x85\x24\xf9\xc9\x31\x8f\x12\xb1\x60\xa1\xe4\xd1",
+       105 },
+      { GCRY_MD_SHA3_512,
+       "\x59\x54\xba\xb5\x12\xcf\x32\x7d\x66\xb5\xd9\xf2\x96\x18\x00\x80\x40\x26\x24\xad\x76\x28\x50\x6b\x55\x5e\xea\x83\x82\x56\x23\x24\xcf\x45\x2f\xba\x4a\x21\x30\xde\x3e\x16\x5d\x11\x83\x1a\x27\x0d\x9c\xb9\x7c\xe8\xc2\xd3\x2a\x96\xf5\x0d\x71\x60\x0b\xb4\xca\x26\x8c\xf9\x8e\x90\xd6\x49\x6b\x0a\x66\x19\xa5\xa8\xc6\x3d\xb6\xd8\xa0\x63\x4d\xfc\x6c\x7e\xc8\xea\x9c\x00\x6b\x6c\x45\x6f\x1b\x20\xcd\x19\xe7\x81\xaf\x20\x45\x4a\xc8\x80",
+       "\x94\x0c\x6f\x0b\xac\xf1\x1e\x4b\x04\x5f\x43\x20\x03\xf8\x89\x27\x87\x09\xf9\xc3\xd8\xe4\x20\xc9\xa1\x71\x55\xf5\x7e\x77\x6d\x72\xb4\x30\x6b\xba\x4a\xdf\x72\x17\x08\xf6\xef\x45\x74\x44\xab\x12\x23\x83\x72\xe2\x07\xab\x41\xd5\xef\x5a\x68\x52\x9e\xd0\xb2\x6c",
+       106 },
+      { GCRY_MD_SHA3_512,
+       "\x03\xd9\xf9\x2b\x2c\x56\x57\x09\xa5\x68\x72\x4a\x0a\xff\x90\xf8\xf3\x47\xf4\x3b\x02\x33\x8f\x94\xa0\x3e\xd3\x2e\x6f\x33\x66\x6f\xf5\x80\x2d\xa4\xc8\x1b\xdc\xe0\xd0\xe8\x6c\x04\xaf\xd4\xed\xc2\xfc\x8b\x41\x41\xc2\x97\x5b\x6f\x07\x63\x9b\x19\x94\xc9\x73\xd9\xa9\xaf\xce\x3d\x9d\x36\x58\x62\x00\x34\x98\x51\x3b\xfa\x16\x6d\x26\x29\xe3\x14\xd9\x74\x41\x66\x7b\x00\x74\x14\xe7\x39\xd7\xfe\xbf\x0f\xe3\xc3\x2c\x17\xaa\x18\x8a\x86\x83",
+       "\x17\x2f\x0c\x68\x03\x10\x37\x51\x56\x91\x1c\x07\xb1\x81\x9f\x0b\x9d\x12\x45\x14\xec\x2c\x37\x50\xcb\x2e\x39\x92\x6a\x28\xa4\x63\x6a\xb7\xec\xdc\xdd\x9d\x6a\x96\x0d\x16\xc8\x64\xdd\x58\x56\x45\xd8\x7f\x14\x5c\x5b\x31\x53\x81\xf3\x56\x65\x6d\x61\x7f\xe9\x7d",
+       107 },
+      { GCRY_MD_SHA3_512,
+       "\xf3\x1e\x8b\x4f\x9e\x06\x21\xd5\x31\xd2\x2a\x38\x0b\xe5\xd9\xab\xd5\x6f\xae\xc5\x3c\xbd\x39\xb1\xfa\xb2\x30\xea\x67\x18\x44\x40\xe5\xb1\xd1\x54\x57\xbd\x25\xf5\x62\x04\xfa\x91\x7f\xa4\x8e\x66\x90\x16\xcb\x48\xc1\xff\xc1\xe1\xe4\x52\x74\xb3\xb4\x73\x79\xe0\x0a\x43\x84\x3c\xf8\x60\x1a\x55\x51\x41\x1e\xc1\x25\x03\xe5\xaa\xc4\x3d\x86\x76\xa1\xb2\x29\x7e\xc7\xa0\x80\x0d\xbf\xee\x04\x29\x2e\x93\x7f\x21\xc0\x05\xf1\x74\x11\x47\x30\x41",
+       "\x41\x0d\xba\xa5\xe3\x45\x3f\x2d\xaf\xce\x13\x5d\xc0\x14\xf2\x8f\xbf\x69\x3c\x84\xeb\x7d\x4b\xec\xb8\x0a\x3d\xb3\x2e\x16\xe8\x90\x62\xb3\xff\x59\xc1\xdf\xdf\xab\x32\xd8\x4d\x20\x28\x46\x32\xa2\xac\x7f\x8f\x88\xd4\xb7\x02\x3f\x87\x94\x63\xba\x18\xff\x65\x53",
+       108 },
+      { GCRY_MD_SHA3_512,
+       "\x75\x8e\xa3\xfe\xa7\x38\x97\x3d\xb0\xb8\xbe\x7e\x59\x9b\xbe\xf4\x51\x93\x73\xd6\xe6\xdc\xd7\x19\x5e\xa8\x85\xfc\x99\x1d\x89\x67\x62\x99\x27\x59\xc2\xa0\x90\x02\x91\x2f\xb0\x8e\x0c\xb5\xb7\x6f\x49\x16\x2a\xeb\x8c\xf8\x7b\x17\x2c\xf3\xad\x19\x02\x53\xdf\x61\x2f\x77\xb1\xf0\xc5\x32\xe3\xb5\xfc\x99\xc2\xd3\x1f\x8f\x65\x01\x16\x95\xa0\x87\xa3\x5e\xe4\xee\xe5\xe3\x34\xc3\x69\xd8\xee\x5d\x29\xf6\x95\x81\x5d\x86\x6d\xa9\x9d\xf3\xf7\x94\x03",
+       "\xf9\x3a\x09\x91\x59\xc3\x96\x17\xb7\x5b\x18\x8d\x52\x7f\xc4\xdb\x28\x7c\xbb\x4f\xdd\xdb\xa5\xad\x4d\xcb\x4c\xff\xc4\xdc\x59\x76\x2b\xbc\x41\xa5\x8d\x3a\x78\x8e\xae\x15\x2a\xea\x02\x4b\xc4\xcc\x4f\x29\xfc\x7b\x8a\xb6\x80\x65\xa6\x86\x50\xa0\x4b\x51\x81\x8a",
+       109 },
+      { GCRY_MD_SHA3_512,
+       "\x47\xc6\xe0\xc2\xb7\x49\x48\x46\x59\x21\x86\x88\x04\xf0\xf7\xbd\x50\xdd\x32\x35\x83\xdc\x78\x4f\x99\x8a\x93\xcd\x1c\xa4\xc6\xef\x84\xd4\x1d\xc8\x1c\x2c\x40\xf3\x4b\x5b\xee\x6a\x93\x86\x7b\x3b\xdb\xa0\x05\x2c\x5f\x59\xe6\xf3\x65\x79\x18\xc3\x82\xe7\x71\xd3\x31\x09\x12\x2c\xc8\xbb\x0e\x1e\x53\xc4\xe3\xd1\x3b\x43\xce\x44\x97\x0f\x5e\x0c\x07\x9d\x2a\xd7\xd7\xa3\x54\x9c\xd7\x57\x60\xc2\x1b\xb1\x5b\x44\x75\x89\xe8\x6e\x8d\x76\xb1\xe9\xce\xd2",
+       "\x05\xe6\x99\x84\xee\x99\xaa\x2b\xc8\x51\x08\x3a\xa4\x4e\xe5\x6f\xee\xf8\x6c\x45\x88\x88\x67\xcd\xcd\xd0\xc7\xa8\x04\x90\x80\xae\x78\x58\xb9\x3c\x19\x95\x3a\x88\x1b\xe5\xc0\x36\xbd\x8f\xe8\x36\x28\xc2\xe3\xaa\x99\x39\xa2\x88\xb4\xac\x4b\xc2\x87\x6c\x2f\xbc",
+       110 },
+      { GCRY_MD_SHA3_512,
+       "\xf6\x90\xa1\x32\xab\x46\xb2\x8e\xdf\xa6\x47\x92\x83\xd6\x44\x4e\x37\x1c\x64\x59\x10\x8a\xfd\x9c\x35\xdb\xd2\x35\xe0\xb6\xb6\xff\x4c\x4e\xa5\x8e\x75\x54\xbd\x00\x24\x60\x43\x3b\x21\x64\xca\x51\xe8\x68\xf7\x94\x7d\x7d\x7a\x0d\x79\x2e\x4a\xbf\x0b\xe5\xf4\x50\x85\x3c\xc4\x0d\x85\x48\x5b\x2b\x88\x57\xea\x31\xb5\xea\x6e\x4c\xcf\xa2\xf3\xa7\xef\x33\x80\x06\x6d\x7d\x89\x79\xfd\xac\x61\x8a\xad\x3d\x7e\x88\x6d\xea\x4f\x00\x5a\xe4\xad\x05\xe5\x06\x5f",
+       "\xbe\x22\xf3\xe2\x53\xc2\x56\x3c\x33\x53\xe6\x93\xd2\xd5\xa6\x5d\xc6\xba\xc2\xcb\xcd\xa8\xe4\x3e\x85\x84\xf9\xd8\x51\xe6\x02\xd4\x37\x49\x36\x40\x3f\xd6\x88\xf0\x13\x5e\x36\x3d\xe8\x09\x9f\x24\x9d\xd2\x1c\x61\x69\x5c\x10\x9c\x27\xed\x5f\x4f\x4c\x18\x08\xbf",
+       111 },
+      { GCRY_MD_SHA3_512,
+       "\x58\xd6\xa9\x9b\xc6\x45\x88\x24\xb2\x56\x91\x67\x70\xa8\x41\x70\x40\x72\x1c\xcc\xfd\x4b\x79\xea\xcd\x8b\x65\xa3\x76\x7c\xe5\xba\x7e\x74\x10\x4c\x98\x5a\xc5\x6b\x8c\xc9\xae\xbd\x16\xfe\xbd\x4c\xda\x5a\xdb\x13\x0b\x0f\xf2\x32\x9c\xc8\xd6\x11\xeb\x14\xda\xc2\x68\xa2\xf9\xe6\x33\xc9\x9d\xe3\x39\x97\xfe\xa4\x1c\x52\xa7\xc5\xe1\x31\x7d\x5b\x5d\xae\xd3\x5e\xba\x7d\x5a\x60\xe4\x5d\x1f\xa7\xea\xab\xc3\x5f\x5c\x2b\x0a\x0f\x23\x79\x23\x19\x53\x32\x2c\x4e",
+       "\x1d\x18\x36\xc4\xe2\xc3\xeb\x27\xa7\x4a\x9c\xd6\x00\xc0\x64\x39\x1b\xd9\xed\xd4\x54\x64\xa5\x79\x51\x82\xc8\x79\x47\x48\xba\x51\xa3\x45\xc6\xfa\xe2\xb9\x1f\x57\x58\x40\x1e\x4f\x42\x7d\x50\xb6\x88\x2b\x1d\xf0\x97\x79\x76\xc2\xc9\x43\x2c\x1a\x9b\x3a\xe0\x3f",
+       112 },
+      { GCRY_MD_SHA3_512,
+       "\xbe\xfa\xb5\x74\x39\x6d\x7f\x8b\x67\x05\xe2\xd5\xb5\x8b\x2c\x1c\x82\x0b\xb2\x4e\x3f\x4b\xae\x3e\x8f\xbc\xd3\x6d\xbf\x73\x4e\xe1\x4e\x5d\x6a\xb9\x72\xae\xdd\x35\x40\x23\x54\x66\xe8\x25\x85\x0e\xe4\xc5\x12\xea\x97\x95\xab\xfd\x33\xf3\x30\xd9\xfd\x7f\x79\xe6\x2b\xbb\x63\xa6\xea\x85\xde\x15\xbe\xae\xea\x6f\x8d\x20\x4a\x28\x95\x60\x59\xe2\x63\x2d\x11\x86\x1d\xfb\x0e\x65\xbc\x07\xac\x8a\x15\x93\x88\xd5\xc3\x27\x7e\x22\x72\x86\xf6\x5f\xf5\xe5\xb5\xae\xc1",
+       "\xcb\x0d\x33\xc1\x73\xc7\x65\xbb\xa3\x71\x4d\x56\xa4\xcf\x48\xfd\x63\x20\xab\x8c\x53\x17\xe7\xab\x1a\x46\x47\x2a\xfb\x75\x62\x32\xcd\x27\xf5\x14\x73\xdc\xf9\xbd\x7d\xac\x1a\xa7\xf6\x69\x35\x3f\xd8\xf3\xd2\x7d\x17\xd3\xfe\x3e\xb3\x38\x68\x76\xec\xa3\x8a\x85",
+       113 },
+      { GCRY_MD_SHA3_512,
+       "\x8e\x58\x14\x4f\xa9\x17\x9d\x68\x64\x78\x62\x2c\xe4\x50\xc7\x48\x26\x0c\x95\xd1\xba\x43\xb8\xf9\xb5\x9a\xbe\xca\x8d\x93\x48\x8d\xa7\x34\x63\xef\x40\x19\x8b\x4d\x16\xfb\x0b\x07\x07\x20\x13\x47\xe0\x50\x6f\xf1\x9d\x01\xbe\xa0\xf4\x2b\x8a\xf9\xe7\x1a\x1f\x1b\xd1\x68\x78\x10\x69\xd4\xd3\x38\xfd\xef\x00\xbf\x41\x9f\xbb\x00\x30\x31\xdf\x67\x1f\x4a\x37\x97\x95\x64\xf6\x92\x82\xde\x9c\x65\x40\x78\x47\xdd\x0d\xa5\x05\xab\x16\x41\xc0\x2d\xea\x4f\x0d\x83\x49\x86",
+       "\xb5\x79\xad\x0c\x75\x0b\x91\xe0\x67\x1b\xb7\xf0\x48\x2a\x51\x98\x35\xd1\x55\xae\x1a\x4d\xb9\x21\x12\xe6\x6f\xbd\x15\x88\x35\xe0\xc2\x9e\x2f\x12\x2a\x8c\x54\xc5\x30\xf9\x26\x33\xf6\xec\x7b\x22\x2c\xa3\xce\xd4\x5b\x4b\x5a\x24\x42\x6d\x99\xc5\x9c\x1b\x66\x09",
+       114 },
+      { GCRY_MD_SHA3_512,
+       "\xb5\x5c\x10\xea\xe0\xec\x68\x4c\x16\xd1\x34\x63\xf2\x92\x91\xbf\x26\xc8\x2e\x2f\xa0\x42\x2a\x99\xc7\x1d\xb4\xaf\x14\xdd\x9c\x7f\x33\xed\xa5\x2f\xd7\x3d\x01\x7c\xc0\xf2\xdb\xe7\x34\xd8\x31\xf0\xd8\x20\xd0\x6d\x5f\x89\xda\xcc\x48\x57\x39\x14\x4f\x8c\xfd\x47\x99\x22\x3b\x1a\xff\x90\x31\xa1\x05\xcb\x6a\x02\x9b\xa7\x1e\x6e\x58\x67\xd8\x5a\x55\x49\x91\xc3\x8d\xf3\xc9\xef\x8c\x1e\x1e\x9a\x76\x30\xbe\x61\xca\xab\xca\x69\x28\x0c\x39\x9c\x1f\xb7\xa1\x2d\x12\xae\xfc",
+       "\x68\x9c\x87\x8d\x8a\x44\xc7\x9e\xaf\x05\x79\xdc\x96\xc0\xe7\xfe\x7d\x33\x49\x1f\x59\xa6\x05\x8b\xee\x60\xe1\x4b\x80\x06\xbd\xf6\xa6\x07\x0b\x2b\x6d\x3b\xb6\xd7\xc3\x1c\xca\xe0\x9e\xc4\x03\xdf\x49\xdd\x12\xba\x72\xc8\x53\x2a\x8e\x47\x6b\x4b\x41\x5d\x83\x69",
+       115 },
+      { GCRY_MD_SHA3_512,
+       "\x2e\xee\xa6\x93\xf5\x85\xf4\xed\x6f\x6f\x88\x65\xbb\xae\x47\xa6\x90\x8a\xec\xd7\xc4\x29\xe4\xbe\xc4\xf0\xde\x1d\x0c\xa0\x18\x3f\xa2\x01\xa0\xcb\x14\xa5\x29\xb7\xd7\xac\x0e\x6f\xf6\x60\x7a\x32\x43\xee\x9f\xb1\x1b\xcf\x3e\x23\x04\xfe\x75\xff\xcd\xdd\x6c\x5c\x2e\x2a\x4c\xd4\x5f\x63\xc9\x62\xd0\x10\x64\x50\x58\xd3\x65\x71\x40\x4a\x6d\x2b\x4f\x44\x75\x54\x34\xd7\x69\x98\xe8\x34\x09\xc3\x20\x5a\xa1\x61\x5d\xb4\x40\x57\xdb\x99\x12\x31\xd2\xcb\x42\x62\x45\x74\xf5\x45",
+       "\x4e\x4d\xc4\x9e\x41\x4c\x79\x4a\x4b\x6d\x8d\x20\x93\xfe\xab\x46\xd9\x13\x21\xcf\xd0\x89\xb1\xfd\x8c\xb5\x15\x4f\x3e\x34\x26\x45\xf6\x23\x3a\x92\x16\xdb\x04\xf0\x80\xe5\xaf\x8b\x15\x6e\x78\x2a\xd1\x6e\x0b\x15\xd8\x14\x17\x3e\x78\xfc\xf5\xe7\xcf\x8e\xa5\x1f",
+       116 },
+      { GCRY_MD_SHA3_512,
+       "\xda\xb1\x1d\xc0\xb0\x47\xdb\x04\x20\xa5\x85\xf5\x6c\x42\xd9\x31\x75\x56\x28\x52\x42\x84\x99\xf6\x6a\x0d\xb8\x11\xfc\xdd\xda\xb2\xf7\xcd\xff\xed\x15\x43\xe5\xfb\x72\x11\x0b\x64\x68\x6b\xc7\xb6\x88\x7a\x53\x8a\xd4\x4c\x05\x0f\x1e\x42\x63\x1b\xc4\xec\x8a\x9f\x2a\x04\x71\x63\xd8\x22\xa3\x89\x89\xee\x4a\xab\x01\xb4\xc1\xf1\x61\xb0\x62\xd8\x73\xb1\xcf\xa3\x88\xfd\x30\x15\x14\xf6\x22\x24\x15\x7b\x9b\xef\x42\x3c\x77\x83\xb7\xaa\xc8\xd3\x0d\x65\xcd\x1b\xba\x8d\x68\x9c\x2d",
+       "\x2c\x8f\x45\x6f\x90\x91\x51\x7c\xaf\xa9\xdf\x1d\x09\xee\x62\x1e\xdf\xeb\x2c\x00\xda\xb9\x44\x35\x5d\x59\x2d\xfd\xa1\x28\xf8\x37\x22\x85\x78\xe3\x96\x5d\x37\x67\x95\x9d\x3c\xdd\xe4\xe7\xb6\x7e\x02\x24\x1f\x28\xc5\x41\x7e\x33\xea\x74\xe3\x90\x32\xf9\x38\xea",
+       117 },
+      { GCRY_MD_SHA3_512,
+       "\x42\xe9\x9a\x2f\x80\xae\xe0\xe0\x01\x27\x9a\x24\x34\xf7\x31\xe0\x1d\x34\xa4\x4b\x1a\x81\x01\x72\x69\x21\xc0\x59\x0c\x30\xf3\x12\x0e\xb8\x30\x59\xf3\x25\xe8\x94\xa5\xac\x95\x9d\xca\x71\xce\x22\x14\x79\x99\x16\x42\x4e\x85\x9d\x27\xd7\x89\x43\x7b\x9d\x27\x24\x0b\xf8\xc3\x5a\xdb\xaf\xce\xcc\x32\x2b\x48\xaa\x20\x5b\x29\x39\x62\xd8\x58\x65\x2a\xba\xcb\xd5\x88\xbc\xf6\xcb\xc3\x88\xd0\x99\x3b\xd6\x22\xf9\x6e\xd5\x46\x14\xc2\x5b\x6a\x9a\xa5\x27\x58\x9e\xaa\xff\xcf\x17\xdd\xf7",
+       "\x3a\xe1\x84\x02\xad\x41\x23\xaf\x1a\xd8\x68\x45\x05\x91\xc4\x6f\x66\x43\x1d\x42\x2a\x29\xd9\x32\xdf\x94\xaf\x9a\xb3\xe2\x56\xf8\x06\x57\x5b\x3e\xb0\xd2\x4e\xdc\x75\x31\x72\x5e\x03\x36\x84\x7b\x2e\x57\x1a\xe6\x67\xb6\x19\xa9\xd7\x9a\x3e\x16\x89\x48\xaf\x5d",
+       118 },
+      { GCRY_MD_SHA3_512,
+       "\x3c\x9b\x46\x45\x0c\x0f\x2c\xae\x8e\x38\x23\xf8\xbd\xb4\x27\x7f\x31\xb7\x44\xce\x2e\xb1\x70\x54\xbd\xdc\x6d\xff\x36\xaf\x7f\x49\xfb\x8a\x23\x20\xcc\x3b\xdf\x8e\x0a\x2e\xa2\x9a\xd3\xa5\x5d\xe1\x16\x5d\x21\x9a\xde\xdd\xb5\x17\x52\x53\xe2\xd1\x48\x9e\x9b\x6f\xdd\x02\xe2\xc3\xd3\xa4\xb5\x4d\x60\xe3\xa4\x73\x34\xc3\x79\x13\xc5\x69\x53\x78\xa6\x69\xe9\xb7\x2d\xec\x32\xaf\x54\x34\xf9\x3f\x46\x17\x6e\xbf\x04\x4c\x47\x84\x46\x7c\x70\x04\x70\xd0\xc0\xb4\x0c\x8a\x08\x8c\x81\x58\x16",
+       "\x6f\x3e\x12\x94\xb6\x7d\x87\x51\x65\xfd\x09\xdd\x49\x3d\xd5\x59\x24\xe9\xe2\x8e\x53\xaf\xa2\xda\x80\x91\x6d\x7d\x54\xe1\x9c\x17\x05\x12\x1d\x61\x7e\x53\xf5\x6e\xba\x47\x67\xd6\x43\x5e\x98\x6f\xee\xae\xb9\x65\xec\x49\x56\xfd\x3c\x02\xde\x12\x88\xfb\xc6\x61",
+       119 },
+      { GCRY_MD_SHA3_512,
+       "\xd1\xe6\x54\xb7\x7c\xb1\x55\xf5\xc7\x79\x71\xa6\x4d\xf9\xe5\xd3\x4c\x26\xa3\xca\xd6\xc7\xf6\xb3\x00\xd3\x9d\xeb\x19\x10\x09\x46\x91\xad\xaa\x09\x5b\xe4\xba\x5d\x86\x69\x0a\x97\x64\x28\x63\x5d\x55\x26\xf3\xe9\x46\xf7\xdc\x3b\xd4\xdb\xc7\x89\x99\xe6\x53\x44\x11\x87\xa8\x1f\x9a\xdc\xd5\xa3\xc5\xf2\x54\xbc\x82\x56\xb0\x15\x8f\x54\x67\x3d\xcc\x12\x32\xf6\xe9\x18\xeb\xfc\x6c\x51\xce\x67\xea\xeb\x04\x2d\x9f\x57\xee\xc4\xbf\xe9\x10\xe1\x69\xaf\x78\xb3\xde\x48\xd1\x37\xdf\x4f\x28\x40",
+       "\xaa\x33\x98\xbc\x7d\xae\xb4\xf2\x2c\xa6\xd1\x93\x7b\x0c\x60\x97\xa4\x9a\xdb\x6d\xbc\x03\xfc\x0f\x52\x26\xa6\x44\xf2\x17\x29\x6b\xf5\x57\x47\x26\x9b\x86\x1f\xc7\xb2\x2b\xc5\x95\x6c\xe3\xd8\xda\x28\xe9\xf2\x5d\x8c\x95\x99\xbc\x65\x3c\xd0\xee\x0c\x85\x24\x73",
+       120 },
+      { GCRY_MD_SHA3_512,
+       "\x62\x6f\x68\xc1\x8a\x69\xa6\x59\x01\x59\xa9\xc4\x6b\xe0\x3d\x59\x65\x69\x8f\x2d\xac\x3d\xe7\x79\xb8\x78\xb3\xd9\xc4\x21\xe0\xf2\x1b\x95\x5a\x16\xc7\x15\xc1\xec\x1e\x22\xce\x3e\xb6\x45\xb8\xb4\xf2\x63\xf6\x06\x60\xea\x30\x28\x98\x1e\xeb\xd6\xc8\xc3\xa3\x67\x28\x5b\x69\x1c\x8e\xe5\x69\x44\xa7\xcd\x12\x17\x99\x7e\x1d\x9c\x21\x62\x0b\x53\x6b\xdb\xd5\xde\x89\x25\xff\x71\xde\xc6\xfb\xc0\x66\x24\xab\x6b\x21\xe3\x29\x81\x3d\xe9\x0d\x1e\x57\x2d\xfb\x89\xa1\x81\x20\xc3\xf6\x06\x35\x5d\x25",
+       "\x8b\xcb\xbe\x36\xdb\xe3\x05\xfb\xb5\x58\xea\x46\x72\x1d\x25\xde\x7a\xab\x78\x98\xe5\x83\xe8\xbd\xf2\x67\x01\x22\x43\x87\xc5\x24\xc6\x83\x47\x5c\x24\x2c\x7d\xe0\x90\x60\x8a\x4f\x17\x66\x3d\x21\x72\x76\xf9\x4f\x41\x88\xb9\x42\xa0\x30\x39\xb5\xe3\x8d\x6a\xe3",
+       121 },
+      { GCRY_MD_SHA3_512,
+       "\x65\x1a\x6f\xb3\xc4\xb8\x0c\x7c\x68\xc6\x01\x16\x75\xe6\x09\x4e\xb5\x6a\xbf\x5f\xc3\x05\x73\x24\xeb\xc6\x47\x78\x25\x06\x1f\x9f\x27\xe7\xa9\x46\x33\xab\xd1\xfa\x59\x8a\x74\x6e\x4a\x57\x7c\xaf\x52\x4c\x52\xec\x17\x88\x47\x1f\x92\xb8\xc3\x7f\x23\x79\x5c\xa1\x9d\x55\x9d\x44\x6c\xab\x16\xcb\xcd\xce\x90\xb7\x9f\xa1\x02\x6c\xee\x77\xbf\x4a\xb1\xb5\x03\xc5\xb9\x4c\x22\x56\xad\x75\xb3\xea\xc6\xfd\x5d\xcb\x96\xac\xa4\xb0\x3a\x83\x4b\xfb\x4e\x9a\xf9\x88\xce\xcb\xf2\xae\x59\x7c\xb9\x09\x79\x40",
+       "\x47\x82\xdf\xca\xb6\x50\xe7\xa8\xda\xe9\xa0\x10\xcb\x00\x2d\xd0\x37\x3b\xfb\xd3\x12\x47\xfa\x98\x60\x87\x6d\x7f\xff\xd2\xd5\x7c\x35\x5f\x20\x54\xcb\x2e\xfe\xb4\x5c\x58\x71\xf2\x84\xf4\x6b\x02\x57\x98\x34\x4a\x37\x19\xef\xab\x34\xd1\x51\x52\xdd\x0b\xbc\x6c",
+       122 },
+      { GCRY_MD_SHA3_512,
+       "\x8a\xaf\x07\x2f\xce\x8a\x2d\x96\xbc\x10\xb3\xc9\x1c\x80\x9e\xe9\x30\x72\xfb\x20\x5c\xa7\xf1\x0a\xbd\x82\xec\xd8\x2c\xf0\x40\xb1\xbc\x49\xea\x13\xd1\x85\x78\x15\xc0\xe9\x97\x81\xde\x3a\xdb\xb5\x44\x3c\xe1\xc8\x97\xe5\x51\x88\xce\xaf\x22\x1a\xa9\x68\x16\x38\xde\x05\xae\x1b\x32\x29\x38\xf4\x6b\xce\x51\x54\x3b\x57\xec\xdb\x4c\x26\x62\x72\x25\x9d\x17\x98\xde\x13\xbe\x90\xe1\x0e\xfe\xc2\xd0\x74\x84\xd9\xb2\x1a\x38\x70\xe2\xaa\x9e\x06\xc2\x1a\xa2\xd0\xc9\xcf\x42\x00\x80\xa8\x0a\x91\xde\xe1\x6f",
+       "\xa4\xd5\x38\xe4\x49\xe2\xb3\xeb\xf9\xaa\xfc\x88\xd2\x9e\x51\x4b\xa0\xd2\xc8\xde\x27\x06\xf3\xf6\xfa\x5a\x2c\x4f\x95\xf5\xdb\x5b\xab\x59\xc1\xa6\x9c\x16\xe4\x85\x9a\x19\x73\x0a\xbb\x2e\x6b\xf0\x61\x52\x44\x5e\xda\x80\xe3\xbe\x5c\xe6\x52\x02\x3e\xa5\x7e\x5e",
+       123 },
+      { GCRY_MD_SHA3_512,
+       "\x53\xf9\x18\xfd\x00\xb1\x70\x1b\xd5\x04\xf8\xcd\xea\x80\x3a\xcc\xa2\x1a\xc1\x8c\x56\x4a\xb9\x0c\x2a\x17\xda\x59\x2c\x7d\x69\x68\x8f\x65\x80\x57\x53\x95\x55\x1e\x8c\xd3\x3e\x0f\xef\x08\xca\x6e\xd4\x58\x8d\x4d\x14\x0b\x3e\x44\xc0\x32\x35\x5d\xf1\xc5\x31\x56\x4d\x7f\x48\x35\x75\x33\x44\x34\x5a\x67\x81\xe1\x1c\xd5\xe0\x95\xb7\x3d\xf5\xf8\x2c\x8a\xe3\xad\x00\x87\x79\x36\x89\x66\x71\xe9\x47\xcc\x52\xe2\xb2\x9d\xcd\x46\x3d\x90\xa0\xc9\x92\x91\x28\xda\x22\x2b\x5a\x21\x14\x50\xbb\xc0\xe0\x24\x48\xe2",
+       "\x87\x32\xd2\x43\xf1\xb3\x34\x9f\x90\x0d\xf4\x30\x65\x9b\x9a\xb9\xed\x99\xf6\x26\xad\x35\xcb\x20\x84\xb5\x7d\x60\xe5\xa5\xb4\x72\x13\xad\x21\x38\x59\xcd\x40\x96\x4c\x5a\x26\x7c\x23\x6d\x0e\x38\x16\x75\x25\xf7\x78\xe6\x7e\x37\xd4\xf6\x23\xa8\x88\x41\x28\xed",
+       124 },
+      { GCRY_MD_SHA3_512,
+       "\xa6\x45\x99\xb8\xa6\x1b\x5c\xce\xc9\xe6\x7a\xed\x69\x44\x74\x59\xc8\xda\x3d\x1e\xc6\xc7\xc7\xc8\x2a\x74\x28\xb9\xb5\x84\xfa\x67\xe9\x0f\x68\xe2\xc0\x0f\xbb\xed\x46\x13\x66\x6e\x51\x68\xda\x4a\x16\xf3\x95\xf7\xa3\xc3\x83\x2b\x3b\x13\x4b\xfc\x9c\xba\xa9\x5d\x2a\x0f\xe2\x52\xf4\x4a\xc6\x68\x1e\xb6\xd4\x0a\xb9\x1c\x1d\x02\x82\xfe\xd6\x70\x1c\x57\x46\x3d\x3c\x5f\x2b\xb8\xc6\xa7\x30\x1f\xb4\x57\x6a\xa3\xb5\xf1\x55\x10\xdb\x89\x56\xff\x77\x47\x8c\x26\xa7\xc0\x9b\xea\x7b\x39\x8c\xfc\x83\x50\x3f\x53\x8e",
+       "\x97\xdc\x26\x06\xe1\x4f\x7b\xff\xf1\xfc\xa4\x97\x96\x5e\x36\xca\xa3\xa8\x1c\xfd\x64\x59\xd0\x25\x45\x29\xf6\x4d\xa4\x0f\xfe\x74\x42\xc0\x8a\x15\x1d\x6c\xee\x3b\x46\xbf\x34\x14\xe8\x01\x10\xa0\xf7\x1e\xee\x44\xd7\x94\x00\x27\xde\xe9\x0e\x91\x9e\x49\x8d\x65",
+       125 },
+      { GCRY_MD_SHA3_512,
+       "\x0e\x3a\xb0\xe0\x54\x73\x9b\x00\xcd\xb6\xa8\x7b\xd1\x2c\xae\x02\x4b\x54\xcb\x5e\x55\x0e\x6c\x42\x53\x60\xc2\xe8\x7e\x59\x40\x1f\x5e\xc2\x4e\xf0\x31\x48\x55\xf0\xf5\x6c\x47\x69\x5d\x56\xa7\xfb\x14\x17\x69\x3a\xf2\xa1\xed\x52\x91\xf2\xfe\xe9\x5f\x75\xee\xd5\x4a\x1b\x1c\x2e\x81\x22\x6f\xbf\xf6\xf6\x3a\xde\x58\x49\x11\xc7\x19\x67\xa8\xeb\x70\x93\x3b\xc3\xf5\xd1\x5b\xc9\x1b\x5c\x26\x44\xd9\x51\x6d\x3c\x3a\x8c\x15\x4e\xe4\x8e\x11\x8b\xd1\x44\x2c\x04\x3c\x7a\x0d\xba\x5a\xc5\xb1\xd5\x36\x0a\xae\x5b\x90\x65",
+       "\xde\x59\x78\xea\xce\x4e\x51\xf7\xd2\x89\xf2\xbe\xfb\xec\xb3\xaa\xc8\xe9\xca\xd4\x8f\xa0\xf7\x31\x0c\x67\x3d\x52\xbb\xca\xee\xbd\xe4\x9c\xb5\xa7\x6d\x33\x4d\x6d\xfd\xd5\x1a\xc1\xab\x24\xe9\xe1\xcd\xc9\x15\x06\x9d\xbd\xdb\x3d\x2e\x30\xb0\xb0\xc2\x6b\x3e\xe1",
+       126 },
+      { GCRY_MD_SHA3_512,
+       "\xa6\x2f\xc5\x95\xb4\x09\x6e\x63\x36\xe5\x3f\xcd\xfc\x8d\x1c\xc1\x75\xd7\x1d\xac\x9d\x75\x0a\x61\x33\xd2\x31\x99\xea\xac\x28\x82\x07\x94\x4c\xea\x6b\x16\xd2\x76\x31\x91\x5b\x46\x19\xf7\x43\xda\x2e\x30\xa0\xc0\x0b\xbd\xb1\xbb\xb3\x5a\xb8\x52\xef\x3b\x9a\xec\x6b\x0a\x8d\xcc\x6e\x9e\x1a\xba\xa3\xad\x62\xac\x0a\x6c\x5d\xe7\x65\xde\x2c\x37\x11\xb7\x69\xe3\xfd\xe4\x4a\x74\x01\x6f\xff\x82\xac\x46\xfa\x8f\x17\x97\xd3\xb2\xa7\x26\xb6\x96\xe3\xde\xa5\x53\x04\x39\xac\xee\x3a\x45\xc2\xa5\x1b\xc3\x2d\xd0\x55\x65\x0b",
+       "\x33\xab\xca\x29\xa8\xa7\x09\x4c\xfb\x10\xbe\x4a\x80\xe8\x1f\x80\x01\xeb\xb9\x33\xc0\xd4\xb9\x8a\x69\x5b\x22\xab\x55\x3f\x94\xf0\x76\x46\xab\xce\x6a\xdf\x49\x18\x17\xd1\x7b\x78\xc4\x07\x47\xd5\x6f\xaf\x88\xa6\x13\x13\x8c\xa0\xe5\x96\x63\x6c\x67\x23\x97\xb4",
+       127 },
+      { GCRY_MD_SHA3_512,
+       "\x2b\x6d\xb7\xce\xd8\x66\x5e\xbe\x9d\xeb\x08\x02\x95\x21\x84\x26\xbd\xaa\x7c\x6d\xa9\xad\xd2\x08\x89\x32\xcd\xff\xba\xa1\xc1\x41\x29\xbc\xcd\xd7\x0f\x36\x9e\xfb\x14\x92\x85\x85\x8d\x2b\x1d\x15\x5d\x14\xde\x2f\xdb\x68\x0a\x8b\x02\x72\x84\x05\x51\x82\xa0\xca\xe2\x75\x23\x4c\xc9\xc9\x28\x63\xc1\xb4\xab\x66\xf3\x04\xcf\x06\x21\xcd\x54\x56\x5f\x5b\xff\x46\x1d\x3b\x46\x1b\xd4\x0d\xf2\x81\x98\xe3\x73\x25\x01\xb4\x86\x0e\xad\xd5\x03\xd2\x6d\x6e\x69\x33\x8f\x4e\x04\x56\xe9\xe9\xba\xf3\xd8\x27\xae\x68\x5f\xb1\xd8\x17",
+       "\x4f\xab\x45\x80\x6b\x46\x28\x06\x84\x58\xb5\xd0\xa2\xd4\xbf\x10\x1b\x8b\xfc\x92\x76\xef\x86\xad\x5d\x88\x37\x65\xc4\x3f\x72\xce\x8a\x5f\x7b\x4c\x5b\x53\x5a\x91\x51\x30\xbb\x18\x5e\x69\x9a\xb6\x22\x28\x01\x4e\x54\xdf\x79\x0c\x0e\x93\xaa\xdb\xe7\xe3\x9e\x19",
+       128 },
+      { GCRY_MD_SHA3_512,
+       "\x10\xdb\x50\x9b\x2c\xdc\xab\xa6\xc0\x62\xae\x33\xbe\x48\x11\x6a\x29\xeb\x18\xe3\x90\xe1\xbb\xad\xa5\xca\x0a\x27\x18\xaf\xbc\xd2\x34\x31\x44\x01\x06\x59\x48\x93\x04\x3c\xc7\xf2\x62\x52\x81\xbf\x7d\xe2\x65\x58\x80\x96\x6a\x23\x70\x5f\x0c\x51\x55\xc2\xf5\xcc\xa9\xf2\xc2\x14\x2e\x96\xd0\xa2\xe7\x63\xb7\x06\x86\xcd\x42\x1b\x5d\xb8\x12\xda\xce\xd0\xc6\xd6\x50\x35\xfd\xe5\x58\xe9\x4f\x26\xb3\xe6\xdd\xe5\xbd\x13\x98\x0c\xc8\x02\x92\xb7\x23\x01\x3b\xd0\x33\x28\x45\x84\xbf\xf2\x76\x57\x87\x1b\x0c\xf0\x7a\x84\x9f\x4a\xe2",
+       "\x5f\x0b\xfb\x41\x46\x91\x0c\xf0\xc3\x20\x36\x4b\x6a\xd8\xa0\x2b\x09\x66\x22\x9a\xb2\x67\x6d\x96\x70\xf0\xdd\x24\x1e\x81\x04\xdb\x02\x79\x7e\xef\xea\x0b\x9c\xab\xbe\x90\xa4\x47\x57\xb0\x33\x75\x59\x25\xb2\xfc\xcf\x3a\x00\x05\x4f\x9a\xe8\xfb\xce\xf7\x52\xa8",
+       129 },
+      { GCRY_MD_SHA3_512,
+       "\x93\x34\xde\x60\xc9\x97\xbd\xa6\x08\x61\x01\xa6\x31\x4f\x64\xe4\x45\x8f\x5f\xf9\x45\x0c\x50\x9d\xf0\x06\xe8\xc5\x47\x98\x3c\x65\x1c\xa9\x78\x79\x17\x5a\xab\xa0\xc5\x39\xe8\x2d\x05\xc1\xe0\x2c\x48\x09\x75\xcb\xb3\x01\x18\x12\x10\x61\xb1\xeb\xac\x4f\x8d\x9a\x37\x81\xe2\xdb\x6b\x18\x04\x2e\x01\xec\xf9\x01\x7a\x64\xa0\xe5\x74\x47\xec\x7f\xcb\xe6\xa7\xf8\x25\x85\xf7\x40\x3e\xe2\x22\x3d\x52\xd3\x7b\x4b\xf4\x26\x42\x86\x13\xd6\xb4\x25\x79\x80\x97\x2a\x0a\xca\xb5\x08\xa7\x62\x0c\x1c\xb2\x8e\xb4\xe9\xd3\x0f\xc4\x13\x61\xec",
+       "\xd3\x8e\xf3\xb1\x2e\xaa\x0b\xf6\x2a\x75\xb6\xb6\x3c\xff\x3c\x9e\xf1\x71\xde\x1b\x75\xf5\xd0\x26\x29\x36\x5b\xcf\xe6\x5b\xa7\xdd\xd3\x0f\xce\xf7\xfe\xbb\x82\xf1\x9f\x9b\xed\xcc\x1c\xc4\xc6\x79\xb4\x29\x2e\xa6\x2c\x2a\x90\xa7\x56\x2d\xa9\xa1\x31\x8f\xe2\x78",
+       130 },
+      { GCRY_MD_SHA3_512,
+       "\xe8\x8a\xb0\x86\x89\x16\x93\xaa\x53\x5c\xeb\x20\xe6\x4c\x7a\xb9\x7c\x7d\xd3\x54\x8f\x37\x86\x33\x98\x97\xa5\xf0\xc3\x90\x31\x54\x9c\xa8\x70\x16\x6e\x47\x77\x43\xcc\xfb\xe0\x16\xb4\x42\x8d\x89\x73\x8e\x42\x6f\x5f\xfe\x81\x62\x61\x37\xf1\x7a\xec\xff\x61\xb7\x2d\xbe\xe2\xdc\x20\x96\x18\x80\xcf\xe2\x81\xdf\xab\x5e\xe3\x8b\x19\x21\x88\x14\x50\xe1\x60\x32\xde\x5e\x4d\x55\xad\x8d\x4f\xca\x60\x97\x21\xb0\x69\x2b\xac\x79\xbe\x5a\x06\xe1\x77\xfe\x8c\x80\xc0\xc8\x35\x19\xfb\x33\x47\xde\x9f\x43\xd5\x56\x1c\xb8\x10\x7b\x9b\x5e\xdc",
+       "\x60\xc9\x5c\x27\x4f\x99\xb8\x64\x3a\x18\x63\x44\xbc\x01\xd1\x27\x90\x10\xbe\x55\xd1\xbe\x76\xf4\xe6\xf9\x19\xf6\xb5\x4d\x33\x5e\xe0\xe1\xca\x92\x13\x3f\x3d\x7a\x25\x20\xcd\x82\xc4\x00\x0e\x15\xef\xed\x8d\x8a\x66\xf3\x1b\x16\xb0\x97\x7c\x63\xde\x1b\xeb\x05",
+       131 },
+      { GCRY_MD_SHA3_512,
+       "\xfd\x19\xe0\x1a\x83\xeb\x6e\xc8\x10\xb9\x45\x82\xcb\x8f\xbf\xa2\xfc\xb9\x92\xb5\x36\x84\xfb\x74\x8d\x22\x64\xf0\x20\xd3\xb9\x60\xcb\x1d\x6b\x8c\x34\x8c\x2b\x54\xa9\xfc\xea\x72\x33\x0c\x2a\xaa\x9a\x24\xec\xdb\x00\xc4\x36\xab\xc7\x02\x36\x1a\x82\xbb\x88\x28\xb8\x53\x69\xb8\xc7\x2e\xce\x00\x82\xfe\x06\x55\x71\x63\x89\x9c\x2a\x0e\xfa\x46\x6c\x33\xc0\x43\x43\xa8\x39\x41\x70\x57\x39\x9a\x63\xa3\x92\x9b\xe1\xee\x48\x05\xd6\xce\x3e\x5d\x0d\x09\x67\xfe\x90\x04\x69\x6a\x56\x63\xf4\xca\xc9\x17\x90\x06\xa2\xce\xb7\x55\x42\xd7\x5d\x68",
+       "\x93\x85\xd0\xed\x9e\x73\x49\x8e\x24\xb8\xc6\xe7\x46\xa1\xc6\xbe\x80\x11\xee\x30\xfc\xac\x9b\xa1\x72\x24\xee\x20\x12\x37\x85\x22\xc7\x8f\x87\x37\xa2\x24\x62\x1f\xba\x19\xc4\x20\x40\xc5\xc7\xf3\x8a\xc0\x7b\x40\xe0\xe7\x5e\xbc\x59\xd1\x79\x75\xee\x85\xd6\x55",
+       132 },
+      { GCRY_MD_SHA3_512,
+       "\x59\xae\x20\xb6\xf7\xe0\xb3\xc7\xa9\x89\xaf\xb2\x83\x24\xa4\x0f\xca\x25\xd8\x65\x1c\xf1\xf4\x6a\xe3\x83\xef\x6d\x84\x41\x58\x7a\xa1\xc0\x4c\x3e\x3b\xf8\x8e\x81\x31\xce\x61\x45\xcf\xb8\x97\x3d\x96\x1e\x84\x32\xb2\x02\xfa\x5a\xf3\xe0\x9d\x62\x5f\xaa\xd8\x25\xbc\x19\xda\x9b\x5c\x6c\x20\xd0\x2a\xbd\xa2\xfc\xc5\x8b\x5b\xd3\xfe\x50\x7b\xf2\x01\x26\x3f\x30\x54\x38\x19\x51\x0c\x12\xbc\x23\xe2\xdd\xb4\xf7\x11\xd0\x87\xa8\x6e\xdb\x1b\x35\x53\x13\x36\x3a\x2d\xe9\x96\xb8\x91\x02\x5e\x14\x70\x36\x08\x74\x01\xcc\xf3\xca\x78\x15\xbf\x3c\x49",
+       "\x74\x87\x16\x4d\x40\x88\x74\xaf\xdf\x07\xeb\xda\xde\x8c\x62\xe7\x56\x14\x7b\xea\xb3\x23\x8b\x87\x38\xae\xed\x92\x7f\x54\xfe\x6d\x33\xaf\x39\x17\xd4\xe1\x81\xb5\x0c\xbc\x88\xa3\x79\xc7\x35\x85\xf9\xfb\xa4\xc1\xb6\x7b\x4b\xe4\x49\x00\x4e\xa0\xf6\x6d\x11\xad",
+       133 },
+      { GCRY_MD_SHA3_512,
+       "\x77\xee\x80\x4b\x9f\x32\x95\xab\x23\x62\x79\x8b\x72\xb0\xa1\xb2\xd3\x29\x1d\xce\xb8\x13\x98\x96\x35\x58\x30\xf3\x4b\x3b\x32\x85\x61\x53\x1f\x80\x79\xb7\x9a\x6e\x99\x80\x70\x51\x50\x86\x64\x02\xfd\xc1\x76\xc0\x58\x97\xe3\x59\xa6\xcb\x1a\x7a\xb0\x67\x38\x3e\xb4\x97\x18\x2a\x7e\x5a\xef\x70\x38\xe4\xc9\x6d\x13\x3b\x27\x82\x91\x74\x17\xe3\x91\x53\x5b\x5e\x1b\x51\xf4\x7d\x8e\xd7\xe4\xd4\x02\x5f\xe9\x8d\xc8\x7b\x9c\x16\x22\x61\x4b\xff\x3d\x10\x29\xe6\x8e\x37\x2d\xe7\x19\x80\x38\x57\xca\x52\x06\x7c\xdd\xaa\xd9\x58\x95\x1c\xb2\x06\x8c\xc6",
+       "\x0f\x41\xab\x2d\x10\xc5\x1e\x28\x63\x8d\xad\x17\x86\x55\xf1\x60\xb2\xf7\x53\xdb\x44\xee\xd6\xce\x41\x04\x69\x3c\xc4\xa9\x38\xd8\x87\x61\x77\x74\xaf\xec\xb3\x3b\x89\x0e\xe7\xfc\x57\x76\x56\xce\x16\x8e\xea\x42\xc6\x04\xd1\x52\xb9\x52\xc9\xb7\x72\xc9\xb5\x30",
+       134 },
+      { GCRY_MD_SHA3_512,
+       "\xb7\x71\xd5\xce\xf5\xd1\xa4\x1a\x93\xd1\x56\x43\xd7\x18\x1d\x2a\x2e\xf0\xa8\xe8\x4d\x91\x81\x2f\x20\xed\x21\xf1\x47\xbe\xf7\x32\xbf\x3a\x60\xef\x40\x67\xc3\x73\x4b\x85\xbc\x8c\xd4\x71\x78\x0f\x10\xdc\x9e\x82\x91\xb5\x83\x39\xa6\x77\xb9\x60\x21\x8f\x71\xe7\x93\xf2\x79\x7a\xea\x34\x94\x06\x51\x28\x29\x06\x5d\x37\xbb\x55\xea\x79\x6f\xa4\xf5\x6f\xd8\x89\x6b\x49\xb2\xcd\x19\xb4\x32\x15\xad\x96\x7c\x71\x2b\x24\xe5\x03\x2d\x06\x52\x32\xe0\x2c\x12\x74\x09\xd2\xed\x41\x46\xb9\xd7\x5d\x76\x3d\x52\xdb\x98\xd9\x49\xd3\xb0\xfe\xd6\xa8\x05\x2f\xbb",
+       "\x75\x75\xa1\xfb\x4f\xc9\xa8\xf9\xc0\x46\x6b\xd5\xfc\xa4\x96\xd1\xcb\x78\x69\x67\x73\xa2\x12\xa5\xf6\x2d\x02\xd1\x4e\x32\x59\xd1\x92\xa8\x7e\xba\x44\x07\xdd\x83\x89\x35\x27\x33\x14\x07\xb6\xda\xda\xad\x92\x0d\xbc\x46\x48\x9b\x67\x74\x93\xce\x5f\x20\xb5\x95",
+       135 },
+      { GCRY_MD_SHA3_512,
+       "\xb3\x2d\x95\xb0\xb9\xaa\xd2\xa8\x81\x6d\xe6\xd0\x6d\x1f\x86\x00\x85\x05\xbd\x8c\x14\x12\x4f\x6e\x9a\x16\x3b\x5a\x2a\xde\x55\xf8\x35\xd0\xec\x38\x80\xef\x50\x70\x0d\x3b\x25\xe4\x2c\xc0\xaf\x05\x0c\xcd\x1b\xe5\xe5\x55\xb2\x30\x87\xe0\x4d\x7b\xf9\x81\x36\x22\x78\x0c\x73\x13\xa1\x95\x4f\x87\x40\xb6\xee\x2d\x3f\x71\xf7\x68\xdd\x41\x7f\x52\x04\x82\xbd\x3a\x08\xd4\xf2\x22\xb4\xee\x9d\xbd\x01\x54\x47\xb3\x35\x07\xdd\x50\xf3\xab\x42\x47\xc5\xde\x9a\x8a\xbd\x62\xa8\xde\xce\xa0\x1e\x3b\x87\xc8\xb9\x27\xf5\xb0\x8b\xeb\x37\x67\x4c\x6f\x8e\x38\x0c\x04",
+       "\x2e\x29\x37\x65\x02\x2d\x48\x99\x6c\xe8\xef\xf0\xbe\x54\xe8\x7e\xfb\x94\xa1\x4c\x72\xde\x5a\xcd\x10\xd0\xeb\x5e\xce\x02\x9c\xad\xfa\x3b\xa1\x7a\x40\xb2\xff\xa2\x16\x39\x91\xb1\x77\x86\xe5\x1c\xab\xa7\x9e\x5e\x0f\xfd\x34\xcf\x08\x5e\x2a\x09\x8b\xe8\xba\xcb",
+       136 },
+      { GCRY_MD_SHA3_512,
+       "\x04\x41\x0e\x31\x08\x2a\x47\x58\x4b\x40\x6f\x05\x13\x98\xa6\xab\xe7\x4e\x4d\xa5\x9b\xb6\xf8\x5e\x6b\x49\xe8\xa1\xf7\xf2\xca\x00\xdf\xba\x54\x62\xc2\xcd\x2b\xfd\xe8\xb6\x4f\xb2\x1d\x70\xc0\x83\xf1\x13\x18\xb5\x6a\x52\xd0\x3b\x81\xca\xc5\xee\xc2\x9e\xb3\x1b\xd0\x07\x8b\x61\x56\x78\x6d\xa3\xd6\xd8\xc3\x30\x98\xc5\xc4\x7b\xb6\x7a\xc6\x4d\xb1\x41\x65\xaf\x65\xb4\x45\x44\xd8\x06\xdd\xe5\xf4\x87\xd5\x37\x3c\x7f\x97\x92\xc2\x99\xe9\x68\x6b\x7e\x58\x21\xe7\xc8\xe2\x45\x83\x15\xb9\x96\xb5\x67\x7d\x92\x6d\xac\x57\xb3\xf2\x2d\xa8\x73\xc6\x01\x01\x6a\x0d",
+       "\xbe\x8e\x14\xb6\x75\x7f\xfe\x53\xc9\xb7\x5f\x6d\xde\x9a\x7b\x6c\x40\x47\x40\x41\xde\x83\xd4\xa6\x06\x45\xa8\x26\xd7\xaf\x1a\xbe\x1e\xef\xcb\x7b\x74\xb6\x2c\xa6\xa5\x14\xe5\xf2\x69\x7d\x58\x5b\xfe\xce\xce\x12\x93\x1b\xbe\x1d\x4e\xd7\xeb\xf7\xb0\xbe\x66\x0e",
+       137 },
+      { GCRY_MD_SHA3_512,
+       "\x8b\x81\xe9\xba\xdd\xe0\x26\xf1\x4d\x95\xc0\x19\x97\x70\x24\xc9\xe1\x3d\xb7\xa5\xcd\x21\xf9\xe9\xfc\x49\x1d\x71\x61\x64\xbb\xac\xdc\x70\x60\xd8\x82\x61\x5d\x41\x14\x38\xae\xa0\x56\xc3\x40\xcd\xf9\x77\x78\x8f\x6e\x17\xd1\x18\xde\x55\x02\x68\x55\xf9\x32\x70\x47\x2d\x1f\xd1\x8b\x9e\x7e\x81\x2b\xae\x10\x7e\x0d\xfd\xe7\x06\x33\x01\xb7\x1f\x6c\xfe\x4e\x22\x5c\xab\x3b\x23\x29\x05\xa5\x6e\x99\x4f\x08\xee\x28\x91\xba\x92\x2d\x49\xc3\xda\xfe\xb7\x5f\x7c\x69\x75\x0c\xb6\x7d\x82\x2c\x96\x17\x6c\x46\xbd\x8a\x29\xf1\x70\x13\x73\xfb\x09\xa1\xa6\xe3\xc7\x15\x8f",
+       "\x6c\x7e\x64\xee\x0d\x82\x60\x73\xd4\xf4\x4b\xcf\x15\x86\xa8\x3b\xac\xf3\xe2\xe1\x38\xdf\xdb\x65\xb8\xb8\xb3\x5f\xd7\xda\xe3\x00\xea\x6e\x32\xc6\x24\x5c\xca\x27\xc6\x74\xfe\xb2\x19\x67\x55\x94\x5a\xb7\xc5\xdc\xe9\x9e\xab\x91\x58\xa7\x55\x18\xac\x27\xc4\x31",
+       138 },
+      { GCRY_MD_SHA3_512,
+       "\xfa\x6e\xed\x24\xda\x66\x66\xa2\x22\x08\x14\x6b\x19\xa5\x32\xc2\xec\x9b\xa9\x4f\x09\xf1\xde\xf1\xe7\xfc\x13\xc3\x99\xa4\x8e\x41\xac\xc2\xa5\x89\xd0\x99\x27\x62\x96\x34\x8f\x39\x62\x53\xb5\x7c\xb0\xe4\x02\x91\xbd\x28\x27\x73\x65\x6b\x6e\x0d\x8b\xea\x1c\xda\x08\x4a\x37\x38\x81\x6a\x84\x04\x85\xfc\xf3\xfb\x30\x7f\x77\x7f\xa5\xfe\xac\x48\x69\x5c\x2a\xf4\x76\x97\x20\x25\x8c\x77\x94\x3f\xb4\x55\x6c\x36\x2d\x9c\xba\x8b\xf1\x03\xae\xb9\x03\x4b\xaa\x8e\xa8\xbf\xb9\xc4\xf8\xe6\x74\x2c\xe0\xd5\x2c\x49\xea\x8e\x97\x4f\x33\x96\x12\xe8\x30\xe9\xe7\xa9\xc2\x90\x65",
+       "\x58\x42\xd4\xda\x2c\x30\x9d\x9b\x2a\xa7\xcf\xae\x70\x22\x62\xf7\x70\xa8\xe6\x46\x62\x0d\x65\xc1\x72\x71\x41\x6e\x9d\x79\x81\xff\x93\xd2\x28\xcd\x60\xdc\x1c\xc1\x69\x21\x02\x0d\x84\x1e\x43\x9e\x87\xf0\x85\xe5\x03\xd4\x66\xc9\x04\xab\xf8\xcd\xd5\xec\xca\xa9",
+       139 },
+      { GCRY_MD_SHA3_512,
+       "\x9b\xb4\xaf\x1b\x4f\x09\xc0\x71\xce\x3c\xaf\xa9\x2e\x4e\xb7\x3c\xe8\xa6\xf5\xd8\x2a\x85\x73\x34\x40\x36\x8d\xee\x4e\xb1\xcb\xc7\xb5\x5a\xc1\x50\x77\x3b\x6f\xe4\x7d\xbe\x03\x6c\x45\x58\x2e\xd6\x7e\x23\xf4\xc7\x45\x85\xda\xb5\x09\xdf\x1b\x83\x61\x05\x64\x54\x56\x42\xb2\xb1\xec\x46\x3e\x18\x04\x8f\xc2\x34\x77\xc6\xb2\xaa\x03\x55\x94\xec\xd3\x37\x91\xaf\x6a\xf4\xcb\xc2\xa1\x16\x6a\xba\x8d\x62\x8c\x57\xe7\x07\xf0\xb0\xe8\x70\x7c\xaf\x91\xcd\x44\xbd\xb9\x15\xe0\x29\x6e\x01\x90\xd5\x6d\x33\xd8\xdd\xe1\x0b\x5b\x60\x37\x78\x38\x97\x3c\x1d\x94\x3c\x22\xed\x33\x5e",
+       "\xf8\xb2\x45\x27\xb5\xc8\x4c\xa9\xa7\x02\xdb\x2f\x53\x5f\x78\xed\x03\x23\xc2\x93\x2a\x25\x5d\xb2\x4f\x87\x25\x51\xca\x7f\x5c\x04\x82\xb3\x69\x0c\x62\xee\xc8\xad\x69\x30\x8d\xb2\xd7\x23\x08\xc4\xd6\x15\xcd\xe3\x83\x5b\x39\xb4\xf6\xff\x11\x54\x66\xf3\x27\x63",
+       140 },
+      { GCRY_MD_SHA3_512,
+       "\x21\x67\xf0\x21\x18\xcc\x62\x04\x3e\x90\x91\xa6\x47\xca\xdb\xed\x95\x61\x1a\x52\x1f\xe0\xd6\x4e\x85\x18\xf1\x6c\x80\x8a\xb2\x97\x72\x55\x98\xae\x29\x68\x80\xa7\x73\x60\x7a\x79\x8f\x7c\x3c\xfc\xe8\x0d\x25\x1e\xbe\xc6\x88\x50\x15\xf9\xab\xf7\xea\xab\xae\x46\x79\x8f\x82\xcb\x59\x26\xde\x5c\x23\xf4\x4a\x3f\x9f\x95\x34\xb3\xc6\xf4\x05\xb5\x36\x4c\x2f\x8a\x8b\xdc\x5c\xa4\x9c\x74\x9b\xed\x8c\xe4\xba\x48\x89\x70\x62\xae\x84\x24\xca\x6d\xde\x5f\x55\xc0\xe4\x2a\x95\xd1\xe2\x92\xca\x54\xfb\x46\xa8\x4f\xbc\x9c\xd8\x7f\x2d\x0c\x9e\x74\x48\xde\x30\x43\xae\x22\xfd\xd2\x29",
+       "\x08\xc6\xe3\x93\x8d\xe4\x81\x71\xa9\x96\x46\xbd\x09\x0b\x7d\x53\xff\x42\x2a\xe6\x3f\x99\x85\x00\x32\xbd\x13\x1a\xc7\xbd\xfb\xa8\xf8\x34\x66\xad\x31\xfa\xd3\x16\x9d\x8a\x32\x0f\xd9\x54\x8b\xdf\xf2\xc4\x0b\xa2\x0e\x0d\x03\x1a\x80\x54\x01\x9c\x40\xed\x26\x62",
+       141 },
+      { GCRY_MD_SHA3_512,
+       "\x94\xb7\xfa\x0b\xc1\xc4\x4e\x94\x9b\x1d\x76\x17\xd3\x1b\x47\x20\xcb\xe7\xca\x57\xc6\xfa\x4f\x40\x94\xd4\x76\x15\x67\xe3\x89\xec\xc6\x4f\x69\x68\xe4\x06\x4d\xf7\x0d\xf8\x36\xa4\x7d\x0c\x71\x33\x36\xb5\x02\x8b\x35\x93\x0d\x29\xeb\x7a\x7f\x9a\x5a\xf9\xad\x5c\xf4\x41\x74\x5b\xae\xc9\xbb\x01\x4c\xee\xff\x5a\x41\xba\x5c\x1c\xe0\x85\xfe\xb9\x80\xba\xb9\xcf\x79\xf2\x15\x8e\x03\xef\x7e\x63\xe2\x9c\x38\xd7\x81\x6a\x84\xd4\xf7\x1e\x0f\x54\x8b\x7f\xc3\x16\x08\x5a\xe3\x8a\x06\x0f\xf9\xb8\xde\xc3\x6f\x91\xad\x9e\xbc\x0a\x5b\x6c\x33\x8c\xbb\x8f\x66\x59\xd3\x42\xa2\x43\x68\xcf",
+       "\x69\x78\xad\x4b\xc4\xf0\xfc\x44\xc3\x5c\x66\x91\xca\x46\x62\x7d\x84\x0b\xaa\x57\x2d\xe9\xb0\x21\x66\x73\xc9\x88\x19\x71\x91\xcd\xf8\x12\xcf\x21\x92\x0e\x05\x2c\xc9\xce\x1d\x50\x7d\x1b\xa7\xdb\x6f\x15\x1d\x01\x62\x0a\xda\x70\x2d\xc6\x37\xbf\x90\x80\x9c\x19",
+       142 },
+      { GCRY_MD_SHA3_512,
+       "\xea\x40\xe8\x3c\xb1\x8b\x3a\x24\x2c\x1e\xcc\x6c\xcd\x0b\x78\x53\xa4\x39\xda\xb2\xc5\x69\xcf\xc6\xdc\x38\xa1\x9f\x5c\x90\xac\xbf\x76\xae\xf9\xea\x37\x42\xff\x3b\x54\xef\x7d\x36\xeb\x7c\xe4\xff\x1c\x9a\xb3\xbc\x11\x9c\xff\x6b\xe9\x3c\x03\xe2\x08\x78\x33\x35\xc0\xab\x81\x37\xbe\x5b\x10\xcd\xc6\x6f\xf3\xf8\x9a\x1b\xdd\xc6\xa1\xee\xd7\x4f\x50\x4c\xbe\x72\x90\x69\x0b\xb2\x95\xa8\x72\xb9\xe3\xfe\x2c\xee\x9e\x6c\x67\xc4\x1d\xb8\xef\xd7\xd8\x63\xcf\x10\xf8\x40\xfe\x61\x8e\x79\x36\xda\x3d\xca\x5c\xa6\xdf\x93\x3f\x24\xf6\x95\x4b\xa0\x80\x1a\x12\x94\xcd\x8d\x7e\x66\xdf\xaf\xec",
+       "\x3a\x8e\x93\x8c\x45\xf3\xf1\x77\x99\x12\x96\xb2\x45\x65\xd9\xa6\x60\x55\x16\x61\x5d\x96\xa0\x62\xc8\xbe\x53\xa0\xd6\xc5\xa6\x48\x7b\xe3\x5d\x2a\x8f\x3c\xf6\x62\x0d\x0c\x2d\xba\x2c\x56\x0d\x68\x29\x5f\x28\x4b\xe7\xf8\x2f\x3b\x92\x91\x90\x33\xc9\xce\x5d\x80",
+       143 },
+      { GCRY_MD_SHA3_512,
+       "\x15\x7d\x5b\x7e\x45\x07\xf6\x6d\x9a\x26\x74\x76\xd3\x38\x31\xe7\xbb\x76\x8d\x4d\x04\xcc\x34\x38\xda\x12\xf9\x01\x02\x63\xea\x5f\xca\xfb\xde\x25\x79\xdb\x2f\x6b\x58\xf9\x11\xd5\x93\xd5\xf7\x9f\xb0\x5f\xe3\x59\x6e\x3f\xa8\x0f\xf2\xf7\x61\xd1\xb0\xe5\x70\x80\x05\x5c\x11\x8c\x53\xe5\x3c\xdb\x63\x05\x52\x61\xd7\xc9\xb2\xb3\x9b\xd9\x0a\xcc\x32\x52\x0c\xbb\xdb\xda\x2c\x4f\xd8\x85\x6d\xbc\xee\x17\x31\x32\xa2\x67\x91\x98\xda\xf8\x30\x07\xa9\xb5\xc5\x15\x11\xae\x49\x76\x6c\x79\x2a\x29\x52\x03\x88\x44\x4e\xbe\xfe\x28\x25\x6f\xb3\x3d\x42\x60\x43\x9c\xba\x73\xa9\x47\x9e\xe0\x0c\x63",
+       "\xfe\x45\x28\x98\x74\x87\x97\x20\xce\x2a\x84\x4a\xe3\x4b\xb7\x35\x22\x77\x5d\xcb\x60\x19\xdc\xd2\x2b\x88\x85\x99\x46\x72\xa0\x88\x9c\x69\xe8\x11\x5c\x64\x1d\xc8\xb8\x3e\x39\xf7\x31\x18\x15\xa1\x64\xdc\x46\xe0\xba\x2f\xca\x34\x4d\x86\xd4\xbc\x2e\xf2\x53\x2c",
+       144 },
+      { GCRY_MD_SHA3_512,
+       "\x83\x6b\x34\xb5\x15\x47\x6f\x61\x3f\xe4\x47\xa4\xe0\xc3\xf3\xb8\xf2\x09\x10\xac\x89\xa3\x97\x70\x55\xc9\x60\xd2\xd5\xd2\xb7\x2b\xd8\xac\xc7\x15\xa9\x03\x53\x21\xb8\x67\x03\xa4\x11\xdd\xe0\x46\x6d\x58\xa5\x97\x69\x67\x2a\xa6\x0a\xd5\x87\xb8\x48\x1d\xe4\xbb\xa5\x52\xa1\x64\x57\x79\x78\x95\x01\xec\x53\xd5\x40\xb9\x04\x82\x1f\x32\xb0\xbd\x18\x55\xb0\x4e\x48\x48\xf9\xf8\xcf\xe9\xeb\xd8\x91\x1b\xe9\x57\x81\xa7\x59\xd7\xad\x97\x24\xa7\x10\x2d\xbe\x57\x67\x76\xb7\xc6\x32\xbc\x39\xb9\xb5\xe1\x90\x57\xe2\x26\x55\x2a\x59\x94\xc1\xdb\xb3\xb5\xc7\x87\x1a\x11\xf5\x53\x70\x11\x04\x4c\x53",
+       "\xaf\xf6\x1c\x6e\x11\xb9\x8e\x55\xac\x21\x3b\x1a\x0b\xc7\xde\x04\x05\x22\x1a\xc5\xef\xb1\x22\x98\x42\xe4\x61\x4f\x4a\x02\x9c\x9b\xd1\x4a\x0e\xd7\xfd\x99\xaf\x36\x81\x42\x9f\x3f\x30\x9f\xdb\x53\x16\x6a\xa9\xa3\xcd\x9f\x1f\x12\x23\xd0\x4b\x4a\x90\x15\xe9\x4a",
+       145 },
+      { GCRY_MD_SHA3_512,
+       "\xcc\x77\x84\xa4\x91\x2a\x7a\xb5\xad\x36\x20\xaa\xb2\x9b\xa8\x70\x77\xcd\x3c\xb8\x36\x36\xad\xc9\xf3\xdc\x94\xf5\x1e\xdf\x52\x1b\x21\x61\xef\x10\x8f\x21\xa0\xa2\x98\x55\x79\x81\xc0\xe5\x3c\xe6\xce\xd4\x5b\xdf\x78\x2c\x1e\xf2\x00\xd2\x9b\xab\x81\xdd\x64\x60\x58\x69\x64\xed\xab\x7c\xeb\xdb\xbe\xc7\x5f\xd7\x92\x50\x60\xf7\xda\x2b\x85\x3b\x2b\x08\x95\x88\xfa\x0f\x8c\x16\xec\x64\x98\xb1\x4c\x55\xdc\xee\x33\x5c\xb3\xa9\x1d\x69\x8e\x4d\x39\x3a\xb8\xe8\xea\xc0\x82\x5f\x8a\xde\xbe\xee\x19\x6d\xf4\x12\x05\xc0\x11\x67\x4e\x53\x42\x6c\xaa\x45\x3f\x8d\xe1\xcb\xb5\x79\x32\xb0\xb7\x41\xd4\xc6",
+       "\x26\x41\x0e\x1a\x0d\x1e\x36\x59\x43\x8d\xdd\xb2\x95\x3e\xb3\xaa\x08\x2c\xeb\x02\xa3\x27\xfa\x00\x98\x57\x4d\x89\xf9\x23\x6f\x5d\xff\x9c\x17\xde\xf3\x7f\x6c\xe4\xb5\xdc\x1e\xe5\xf2\x3f\x57\x8f\xe1\x91\xee\x8b\x51\xf1\xb8\x03\x4b\xcb\xbb\xb7\xb6\xa5\x00\xa5",
+       146 },
+      { GCRY_MD_SHA3_512,
+       "\x76\x39\xb4\x61\xff\xf2\x70\xb2\x45\x5a\xc1\xd1\xaf\xce\x78\x29\x44\xae\xa5\xe9\x08\x7e\xb4\xa3\x9e\xb9\x6b\xb5\xc3\xba\xaf\x0e\x86\x8c\x85\x26\xd3\x40\x4f\x94\x05\xe7\x9e\x77\xbf\xac\x5f\xfb\x89\xbf\x19\x57\xb5\x23\xe1\x7d\x34\x1d\x73\x23\xc3\x02\xea\x70\x83\x87\x2d\xd5\xe8\x70\x56\x94\xac\xdd\xa3\x6d\x5a\x1b\x89\x5a\xaa\x16\xec\xa6\x10\x4c\x82\x68\x85\x32\xc8\xbf\xe1\x79\x0b\x5d\xc9\xf4\xec\x5f\xe9\x5b\xae\xd3\x7e\x1d\x28\x7b\xe7\x10\x43\x1f\x1e\x5e\x8e\xe1\x05\xbc\x42\xed\x37\xd7\x4b\x1e\x55\x98\x4b\xf1\xc0\x9f\xe6\xa1\xfa\x13\xef\x3b\x96\xfa\xea\xed\x6a\x2a\x19\x50\xa1\x21\x53",
+       "\x50\x15\xda\x2a\x2e\x16\x61\xd3\xa5\x2a\x65\xd1\x9f\x02\x93\x30\x29\x83\x9f\x72\x71\x7a\x77\xb5\x04\x51\x98\x66\x50\x93\xf9\x44\xcf\xf8\x5e\x09\x4d\x41\x83\x96\xa5\x1c\x57\x41\x57\xee\xd9\xfb\x6b\xdd\x4e\xca\x53\x27\x8f\xab\x62\xaf\x69\x9b\x53\xc8\x2f\x58",
+       147 },
+      { GCRY_MD_SHA3_512,
+       "\xeb\x65\x13\xfc\x61\xb3\x0c\xfb\xa5\x8d\x4d\x7e\x80\xf9\x4d\x14\x58\x90\x90\xcf\x1d\x80\xb1\xdf\x2e\x68\x08\x8d\xc6\x10\x49\x59\xba\x0d\x58\x3d\x58\x5e\x95\x78\xab\x0a\xec\x0c\xf3\x6c\x48\x43\x5e\xb5\x2e\xd9\xab\x4b\xbc\xe7\xa5\xab\xe6\x79\xc9\x7a\xe2\xdb\xe3\x5e\x8c\xc1\xd4\x5b\x06\xdd\xa3\xcf\x41\x86\x65\xc5\x7c\xbe\xe4\xbb\xb4\x7f\xa4\xca\xf7\x8f\x4e\xe6\x56\xfe\xc2\x37\xfe\x4e\xeb\xba\xfa\x20\x6e\x1e\xf2\xbd\x0e\xe4\xae\x71\xbd\x0e\x9b\x2f\x54\xf9\x1d\xaa\xdf\x1f\xeb\xfd\x70\x32\x38\x1d\x63\x6b\x73\x3d\xcb\x3b\xf7\x6f\xb1\x4e\x23\xaf\xf1\xf6\x8e\xd3\xdb\xcf\x75\xc9\xb9\x9c\x6f\x26",
+       "\xb2\x78\x28\xcf\xeb\xcf\x4d\x89\x6e\xab\xf1\xf8\x4d\x07\x98\x27\xb7\xdc\xc7\xf3\x08\xa2\x04\x76\x47\x4d\xe5\x18\x82\x9a\x89\xaa\xc3\xdc\x50\x27\x2c\xfa\x97\x6b\x0b\x58\x19\xc4\x5c\x9e\xef\xc5\x1b\x87\xa2\x7d\x11\xc9\xe5\xf9\x57\x91\x21\x12\x5a\x88\x75\x42",
+       148 },
+      { GCRY_MD_SHA3_512,
+       "\x15\x94\xd7\x4b\xf5\xdd\xe4\x44\x26\x5d\x4c\x04\xda\xd9\x72\x1f\xf3\xe3\x4c\xbf\x62\x2d\xaf\x34\x1f\xe1\x6b\x96\x43\x1f\x6c\x4d\xf1\xf7\x60\xd3\x4f\x29\x6e\xb9\x7d\x98\xd5\x60\xad\x52\x86\xfe\xc4\xdc\xe1\x72\x4f\x20\xb5\x4f\xd7\xdf\x51\xd4\xbf\x13\x7a\xdd\x65\x6c\x80\x54\x6f\xb1\xbf\x51\x6d\x62\xee\x82\xba\xa9\x92\x91\x0e\xf4\xcc\x18\xb7\x0f\x3f\x86\x98\x27\x6f\xcf\xb4\x4e\x0e\xc5\x46\xc2\xc3\x9c\xfd\x8e\xe9\x10\x34\xff\x93\x03\x05\x8b\x42\x52\x46\x2f\x86\xc8\x23\xeb\x15\xbf\x48\x1e\x6b\x79\xcc\x3a\x02\x21\x85\x95\xb3\x65\x8e\x8b\x37\x38\x2b\xd5\x04\x8e\xae\xd5\xfd\x02\xc3\x79\x44\xe7\x3b",
+       "\x42\xfc\x06\xdc\xf9\x9b\x4e\x80\x4b\xb3\x49\x10\x1b\x46\xd6\xa6\xa7\x36\x6e\x47\x55\x54\x06\xea\x55\x42\x48\xba\xef\x52\xe1\x7a\xfa\x40\x82\x9f\x57\x09\xd0\x7f\xf4\x07\x88\x1d\xf1\x06\xf1\x56\xca\x73\x56\x22\xb0\xf0\x51\xd8\xc3\x72\xf6\xe8\x11\xcd\xae\x25",
+       149 },
+      { GCRY_MD_SHA3_512,
+       "\x4c\xfa\x12\x78\x90\x30\x26\xf6\x6f\xed\xd4\x13\x74\x55\x8b\xe1\xb5\x85\xd0\x3c\x5c\x55\xda\xc9\x43\x61\xdf\x28\x6d\x4b\xd3\x9c\x7c\xb8\x03\x7e\xd3\xb2\x67\xb0\x7c\x34\x66\x26\x44\x9d\x0c\xc5\xb0\xdd\x2c\xf2\x21\xf7\xe4\xc3\x44\x9a\x4b\xe9\x99\x85\xd2\xd5\xe6\x7b\xff\x29\x23\x35\x7d\xde\xab\x5a\xbc\xb4\x61\x9f\x3a\x3a\x57\xb2\xcf\x92\x8a\x02\x2e\xb2\x76\x76\xc6\xcf\x80\x56\x89\x00\x4f\xca\x4d\x41\xea\x6c\x2d\x0a\x47\x89\xc7\x60\x5f\x7b\xb8\x38\xdd\x88\x3b\x3a\xd3\xe6\x02\x7e\x77\x5b\xcf\x26\x28\x81\x42\x80\x99\xc7\xff\xf9\x5b\x14\xc0\x95\xea\x13\x0e\x0b\x99\x38\xa5\xe2\x2f\xc5\x26\x50\xf5\x91",
+       "\x0c\xa8\x9c\x9b\x72\x73\xde\x38\x4f\xf3\x3f\x1b\xac\xbb\x85\x05\x62\x8c\x4d\x3e\x30\x35\x0b\x33\x53\x61\x56\x3a\xd4\x16\xad\xa5\x23\x12\x2d\x37\xac\xbe\xc5\x77\x21\xf7\xbc\x5d\x9b\x04\x9e\x1f\x4f\xe3\xc4\xcf\xe0\x47\xe3\x3a\x0e\x44\x8e\xf5\xd5\x53\x6c\xf0",
+       150 },
+      { GCRY_MD_SHA3_512,
+       "\xd3\xe6\x5c\xb9\x2c\xfa\x79\x66\x2f\x6a\xf4\x93\xd6\x96\xa0\x7c\xcf\x32\xaa\xad\xcc\xef\xf0\x6e\x73\xe8\xd9\xf6\xf9\x09\x20\x9e\x66\x71\x5d\x6e\x97\x87\x88\xc4\x9e\xfb\x90\x87\xb1\x70\xec\xf3\xaa\x86\xd2\xd4\xd1\xa0\x65\xae\x0e\xfc\x89\x24\xf3\x65\xd6\x76\xb3\xcb\x9e\x2b\xec\x91\x8f\xd9\x6d\x0b\x43\xde\xe8\x37\x27\xc9\xa9\x3b\xf5\x6c\xa2\xb2\xe5\x9a\xdb\xa8\x56\x96\x54\x6a\x81\x50\x67\xfc\x7a\x78\x03\x96\x29\xd4\x94\x8d\x15\x7e\x7b\x0d\x82\x6d\x1b\xf8\xe8\x12\x37\xba\xb7\x32\x13\x12\xfd\xaa\x4d\x52\x17\x44\xf9\x88\xdb\x6f\xdf\x04\x54\x9d\x0f\xdc\xa3\x93\xd6\x39\xc7\x29\xaf\x71\x6e\x9c\x8b\xba\x48",
+       "\x78\xc5\x9a\x8c\xdf\x4d\x1d\x07\xa6\x6b\xb2\xfa\xa7\xff\xa2\x11\x2d\x5c\x0f\xca\xbf\x7e\x35\x89\xe9\x76\x23\xbd\xb9\x22\xaf\x9a\xf2\x49\x18\xc2\xcc\xfc\xe2\xb8\x80\xbf\x64\x14\x5c\x70\xdc\x9a\x4f\xde\x78\xfd\xf0\x91\x8d\xd2\xce\x5f\xea\x9c\xf9\x9a\xcd\x41",
+       151 },
+      { GCRY_MD_SHA3_512,
+       "\x84\x2c\xc5\x83\x50\x45\x39\x62\x2d\x7f\x71\xe7\xe3\x18\x63\xa2\xb8\x85\xc5\x6a\x0b\xa6\x2d\xb4\xc2\xa3\xf2\xfd\x12\xe7\x96\x60\xdc\x72\x05\xca\x29\xa0\xdc\x0a\x87\xdb\x4d\xc6\x2e\xe4\x7a\x41\xdb\x36\xb9\xdd\xb3\x29\x3b\x9a\xc4\xba\xae\x7d\xf5\xc6\xe7\x20\x1e\x17\xf7\x17\xab\x56\xe1\x2c\xad\x47\x6b\xe4\x96\x08\xad\x2d\x50\x30\x9e\x7d\x48\xd2\xd8\xde\x4f\xa5\x8a\xc3\xcf\xea\xfe\xee\x48\xc0\xa9\xee\xc8\x84\x98\xe3\xef\xc5\x1f\x54\xd3\x00\xd8\x28\xdd\xdc\xcb\x9d\x0b\x06\xdd\x02\x1a\x29\xcf\x5c\xb5\xb2\x50\x69\x15\xbe\xb8\xa1\x19\x98\xb8\xb8\x86\xe0\xf9\xb7\xa8\x0e\x97\xd9\x1a\x7d\x01\x27\x0f\x9a\x77\x17",
+       "\xcf\x4d\x52\xd2\x02\x72\xde\x01\x4d\x36\x73\x10\x77\x52\x87\xee\x5e\x5c\xb3\x4c\xf9\xaf\x78\xe6\x5d\x1d\x1f\xe7\xfb\x1f\x13\xb6\x2d\xd9\xb8\x3c\x38\x2b\xaa\x6a\xb4\xf6\x94\x94\x78\xc8\x59\x8f\xef\x78\xe8\xd5\x35\x31\x1f\xc1\x98\x08\xcb\x75\xe2\x2d\xad\xed",
+       152 },
+      { GCRY_MD_SHA3_512,
+       "\x6c\x4b\x0a\x07\x19\x57\x3e\x57\x24\x86\x61\xe9\x8f\xeb\xe3\x26\x57\x1f\x9a\x1c\xa8\x13\xd3\x63\x85\x31\xae\x28\xb4\x86\x0f\x23\xc3\xa3\xa8\xac\x1c\x25\x00\x34\xa6\x60\xe2\xd7\x1e\x16\xd3\xac\xc4\xbf\x9c\xe2\x15\xc6\xf1\x5b\x1c\x0f\xc7\xe7\x7d\x3d\x27\x15\x7e\x66\xda\x9c\xee\xc9\x25\x8f\x8f\x2b\xf9\xe0\x2b\x4a\xc9\x37\x93\xdd\x6e\x29\xe3\x07\xed\xe3\x69\x5a\x0d\xf6\x3c\xbd\xc0\xfc\x66\xfb\x77\x08\x13\xeb\x14\x9c\xa2\xa9\x16\x91\x1b\xee\x49\x02\xc4\x7c\x78\x02\xe6\x9e\x40\x5f\xe3\xc0\x4c\xeb\x55\x22\x79\x2a\x55\x03\xfa\x82\x9f\x70\x72\x72\x22\x66\x21\xf7\xc4\x88\xa7\x69\x8c\x0d\x69\xaa\x56\x1b\xe9\xf3\x78",
+       "\x33\xd6\x32\xe4\x03\xc9\xf9\xa9\x34\x9b\x28\xaa\x48\x21\xa1\x2b\x1d\xb5\x57\xd8\x92\x80\x03\xd3\x0c\x57\xd7\x01\xcf\xf1\xc4\x9b\xac\x94\x72\xce\xcf\xf4\x50\xe4\xd9\x1d\x36\xc6\xcd\x78\x22\x17\x90\xef\xf6\xf0\xfb\xf4\x98\x03\x40\x14\xcb\xba\xce\x5d\xcf\x09",
+       153 },
+      { GCRY_MD_SHA3_512,
+       "\x51\xb7\xdb\xb7\xce\x2f\xfe\xb4\x27\xa9\x1c\xcf\xe5\x21\x8f\xd4\x0f\x9e\x0b\x7e\x24\x75\x6d\x4c\x47\xcd\x55\x60\x60\x08\xbd\xc2\x7d\x16\x40\x09\x33\x90\x6f\xd9\xf3\x0e\xff\xdd\x48\x80\x02\x2d\x08\x11\x55\x34\x2a\xf3\xfb\x6c\xd5\x36\x72\xab\x7f\xb5\xb3\xa3\xbc\xbe\x47\xbe\x1f\xd3\xa2\x27\x8c\xae\x8a\x5f\xd6\x1c\x14\x33\xf7\xd3\x50\x67\x5d\xd2\x18\x03\x74\x6c\xad\xca\x57\x41\x30\xf0\x12\x00\x02\x4c\x63\x40\xab\x0c\xc2\xcf\x74\xf2\x23\x46\x69\xf3\x4e\x90\x09\xef\x2e\xb9\x48\x23\xd6\x2b\x31\x40\x7f\x4b\xa4\x6f\x1a\x1e\xec\x41\x64\x1e\x84\xd7\x77\x27\xb5\x9e\x74\x6b\x8a\x67\x1b\xef\x93\x6f\x05\xbe\x82\x07\x59\xfa",
+       "\x95\x4c\x70\x9a\xbc\xb0\xbb\x88\x15\x92\xd9\x3f\x5c\x24\x63\xce\x8c\x06\x0a\xd1\xdf\x30\x53\x30\x2e\xa7\xb1\x9f\x2b\x47\xbc\xf0\xfe\x35\x9a\x83\x2f\x9a\x86\x5a\x8d\x3d\xbd\x3b\xe5\x98\xdf\xd6\xd0\xfc\x1c\x57\x4e\xca\x0a\xec\x78\xd8\xe3\x28\x83\x99\xbe\x05",
+       154 },
+      { GCRY_MD_SHA3_512,
+       "\x83\x59\x9d\x93\xf5\x56\x1e\x82\x1b\xd0\x1a\x47\x23\x86\xbc\x2f\xf4\xef\xbd\x4a\xed\x60\xd5\x82\x1e\x84\xaa\xe7\x4d\x80\x71\x02\x98\x10\xf5\xe2\x86\xf8\xf1\x76\x51\xcd\x27\xda\x07\xb1\xeb\x43\x82\xf7\x54\xcd\x1c\x95\x26\x87\x83\xad\x09\x22\x0f\x55\x02\x84\x03\x70\xd4\x94\xbe\xb1\x71\x24\x22\x0f\x6a\xfc\xe9\x1e\xc8\xa0\xf5\x52\x31\xf9\x65\x24\x33\xe5\xce\x34\x89\xb7\x27\x71\x6c\xf4\xae\xba\x7d\xcd\xa2\x0c\xd2\x9a\xa9\xa8\x59\x20\x12\x53\xf9\x48\xdd\x94\x39\x5a\xba\x9e\x38\x52\xbd\x1d\x60\xdd\xa7\xae\x5d\xc0\x45\xb2\x83\xda\x00\x6e\x1c\xba\xd8\x3c\xc1\x32\x92\xa3\x15\xdb\x55\x53\x30\x5c\x62\x8d\xd0\x91\x14\x65\x97",
+       "\xa3\x37\x06\x2f\x5e\x5c\x9c\x35\x34\x1a\x51\x22\x4f\x2a\x59\xe6\xcf\x91\x9a\x63\xbf\x59\xa6\xcf\xce\x26\x11\x94\xbb\xd6\x60\xf2\x8c\x29\x48\xd0\x3c\xdc\xe5\xc7\xc1\x51\xec\x05\xb4\x2a\xad\xd8\x30\x51\xa1\x6a\x62\xf0\xc7\xdf\x39\xaa\xa4\xef\xc8\x2c\xe4\xd3",
+       155 },
+      { GCRY_MD_SHA3_512,
+       "\x2b\xe9\xbf\x52\x6c\x9d\x5a\x75\xd5\x65\xdd\x11\xef\x63\xb9\x79\xd0\x68\x65\x9c\x7f\x02\x6c\x08\xbe\xa4\xaf\x16\x1d\x85\xa4\x62\xd8\x0e\x45\x04\x0e\x91\xf4\x16\x5c\x07\x4c\x43\xac\x66\x13\x80\x31\x1a\x8c\xbe\xd5\x9c\xc8\xe4\xc4\x51\x8e\x80\xcd\x2c\x78\xab\x1c\xab\xf6\x6b\xff\x83\xea\xb3\xa8\x01\x48\x55\x03\x07\x31\x09\x50\xd0\x34\xa6\x28\x6c\x93\xa1\xec\xe8\x92\x9e\x63\x85\xc5\xe3\xbb\x6e\xa8\xa7\xc0\xfb\x6d\x63\x32\xe3\x20\xe7\x1c\xc4\xeb\x46\x2a\x2a\x62\xe2\xbf\xe0\x8f\x0c\xca\xd9\x3e\x61\xbe\xdb\x5d\xd0\xb7\x86\xa7\x28\xab\x66\x6f\x07\xe0\x57\x6d\x18\x9c\x92\xbf\x9f\xb2\x0d\xca\x49\xac\x2d\x39\x56\xd4\x73\x85\xe2",
+       "\x43\xe9\xd0\xea\x8e\x52\x6e\x83\x23\x4d\x7b\x63\xd8\x24\x4c\x7e\x7b\x12\xae\x2a\xcc\x80\x82\xf9\x86\x36\x72\x68\xf1\x01\x56\x57\x43\x00\x17\x28\x73\x84\x5b\x20\x7a\x72\x52\x62\x42\x46\xe7\xd3\x2c\xe0\xf7\x28\x2e\x00\xc4\x55\x2f\x61\x80\xf3\x4e\x59\x0e\x2e",
+       156 },
+      { GCRY_MD_SHA3_512,
+       "\xca\x76\xd3\xa1\x25\x95\xa8\x17\x68\x26\x17\x00\x68\x48\x67\x55\x47\xd3\xe8\xf5\x0c\x22\x10\xf9\xaf\x90\x6c\x0e\x7c\xe5\x0b\x44\x60\x18\x6f\xe7\x04\x57\xa9\xe8\x79\xe7\x9f\xd4\xd1\xa6\x88\xc7\x0a\x34\x73\x61\xc8\x47\xba\x0d\xd6\xaa\x52\x93\x6e\xaf\x8e\x58\xa1\xbe\x2f\x5c\x1c\x70\x4e\x20\x14\x6d\x36\x6a\xeb\x38\x53\xbe\xd9\xde\x9b\xef\xe9\x56\x9a\xc8\xaa\xea\x37\xa9\xfb\x71\x39\xa1\xa1\xa7\xd5\xc7\x48\x60\x5a\x8d\xef\xb2\x97\x86\x9e\xbe\xdd\x71\xd6\x15\xa5\xda\x23\x49\x6d\x11\xe1\x1a\xbb\xb1\x26\xb2\x06\xfa\x0a\x77\x97\xee\x7d\xe1\x17\x98\x60\x12\xd0\x36\x2d\xce\xf7\x75\xc2\xfe\x14\x5a\xda\x6b\xda\x1c\xcb\x32\x6b\xf6\x44",
+       "\xf7\xda\x8d\x1e\x49\xd0\xd9\x64\x40\x0e\xe4\x0f\x9c\x88\xe0\x70\x25\xa8\xb0\xb0\x0c\xad\xc6\x24\xa6\x3e\x2e\xa8\x5b\x15\x98\xe2\x2c\x88\x02\xbe\x0c\x1f\xf3\x68\x51\x95\x49\xa7\x52\xe0\x25\x46\x09\x3d\x3b\x98\x4e\x24\x60\x0b\xa2\xab\x7c\x79\x2b\x9e\x07\x4a",
+       157 },
+      { GCRY_MD_SHA3_512,
+       "\xf7\x6b\x85\xdc\x67\x42\x10\x25\xd6\x4e\x93\x09\x6d\x1d\x71\x2b\x7b\xaf\x7f\xb0\x01\x71\x6f\x02\xd3\x3b\x21\x60\xc2\xc8\x82\xc3\x10\xef\x13\xa5\x76\xb1\xc2\xd3\x0e\xf8\xf7\x8e\xf8\xd2\xf4\x65\x00\x71\x09\xaa\xd9\x3f\x74\xcb\x9e\x7d\x7b\xef\x7c\x95\x90\xe8\xaf\x3b\x26\x7c\x89\xc1\x5d\xb2\x38\x13\x8c\x45\x83\x3c\x98\xcc\x4a\x47\x1a\x78\x02\x72\x3e\xf4\xc7\x44\xa8\x53\xcf\x80\xa0\xc2\x56\x8d\xd4\xed\x58\xa2\xc9\x64\x48\x06\xf4\x21\x04\xce\xe5\x36\x28\xe5\xbd\xf7\xb6\x3b\x0b\x33\x8e\x93\x1e\x31\xb8\x7c\x24\xb1\x46\xc6\xd0\x40\x60\x55\x67\xce\xef\x59\x60\xdf\x9e\x02\x2c\xb4\x69\xd4\xc7\x87\xf4\xcb\xa3\xc5\x44\xa1\xac\x91\xf9\x5f",
+       "\xd9\xa4\x27\x61\xf9\x80\xc7\x8c\x36\xcf\x54\xc4\x20\x7b\x0a\x62\x95\x4e\x15\xa9\x07\xa7\xce\xa1\x49\xb3\x7a\x4e\x0a\x63\x76\x20\x2f\xf8\xf1\x2e\x16\xeb\xad\x3a\xec\xc7\xff\x3a\x9d\x6a\xd0\x93\xb0\x68\xdf\xe2\x72\xe3\xb9\x64\x6b\x1a\xed\xc0\x49\x61\xdc\x81",
+       158 },
+      { GCRY_MD_SHA3_512,
+       "\x25\xb8\xc9\xc0\x32\xea\x6b\xcd\x73\x3f\xfc\x87\x18\xfb\xb2\xa5\x03\xa4\xea\x8f\x71\xde\xa1\x17\x61\x89\xf6\x94\x30\x4f\x0f\xf6\x8e\x86\x2a\x81\x97\xb8\x39\x95\x75\x49\xef\x24\x3a\x52\x79\xfc\x26\x46\xbd\x4c\x00\x9b\x6d\x1e\xde\xbf\x24\x73\x81\x97\xab\xb4\xc9\x92\xf6\xb1\xdc\x9b\xa8\x91\xf5\x70\x87\x9a\xcc\xd5\xa6\xb1\x86\x91\xa9\x3c\x7d\x0a\x8d\x38\xf9\x5b\x63\x9c\x1d\xae\xb4\x8c\x4c\x2f\x15\xcc\xf5\xb9\xd5\x08\xf8\x33\x3c\x32\xde\x78\x78\x1b\x41\x85\x0f\x26\x1b\x85\x5c\x4b\xeb\xcc\x12\x5a\x38\x0c\x54\xd5\x01\xc5\xd3\xbd\x07\xe6\xb5\x21\x02\x11\x60\x88\xe5\x3d\x76\x58\x3b\x01\x61\xe2\xa5\x8d\x07\x78\xf0\x91\x20\x6a\xab\xd5\xa1",
+       "\xbb\x65\xd8\x94\x34\x13\xce\xf8\x9f\xdb\x05\xb3\x5a\x55\xec\x75\x03\xe4\x54\x6a\x50\xfc\x3e\xcc\x82\x5d\xab\xc1\xa1\xda\xe6\xc7\x71\xbb\x19\x7f\x32\x36\x25\x87\x7e\x0b\xcc\xaa\x41\x25\x3c\x99\xb6\x69\x29\x76\xb9\x9f\xc6\x87\xb0\xb6\xb3\xe9\xaa\xb4\x78\xc4",
+       159 },
+      { GCRY_MD_SHA3_512,
+       "\x21\xcf\xdc\x2a\x7c\xcb\x7f\x33\x1b\x3d\x2e\xef\xff\x37\xe4\x8a\xd9\xfa\x9c\x78\x8c\x3f\x3c\x20\x0e\x01\x73\xd9\x99\x63\xe1\xcb\xca\x93\x62\x3b\x26\x4e\x92\x03\x94\xae\x48\xbb\x4c\x3a\x5b\xb9\x6f\xfb\xc8\xf0\xe5\x3f\x30\xe2\x29\x56\xad\xab\xc2\x76\x5f\x57\xfb\x76\x1e\x14\x7e\xcb\xf8\x56\x75\x33\xdb\x6e\x50\xc8\xa1\xf8\x94\x31\x0a\x94\xed\xf8\x06\xdd\x8c\xa6\xa0\xe1\x41\xc0\xfa\x7c\x9f\xae\x6c\x6a\xe6\x5f\x18\xc9\x3a\x85\x29\xe6\xe5\xb5\x53\xbf\x55\xf2\x5b\xe2\xe8\x0a\x98\x82\xbd\x37\xf1\x45\xfe\xcb\xeb\x3d\x44\x7a\x3c\x4e\x46\xc2\x15\x24\xcc\x55\xcd\xd6\x2f\x52\x1a\xb9\x2a\x8b\xa7\x2b\x89\x79\x96\xc4\x9b\xb2\x73\x19\x8b\x7b\x1c\x9e",
+       "\x54\x0d\xf2\x21\x80\xb6\x9b\x9a\x83\x30\x66\x19\xb2\xca\x8c\xd8\xe0\x7a\x34\xbb\xeb\x22\x19\xac\x7c\xf8\x8b\x46\x8a\x94\x7c\x44\x48\x48\x9b\x30\x3b\xd6\x55\x06\xc9\xe1\xce\x59\x34\x8a\x9d\x86\x3a\xab\x51\x54\x84\x8e\x95\xb5\x38\x97\x83\xf6\xf5\xfb\x6a\xd8",
+       160 },
+      { GCRY_MD_SHA3_512,
+       "\x4e\x45\x2b\xa4\x21\x27\xdc\xc9\x56\xef\x4f\x8f\x35\xdd\x68\xcb\x22\x5f\xb7\x3b\x5b\xc7\xe1\xec\x5a\x89\x8b\xba\x29\x31\x56\x3e\x74\xfa\xff\x3b\x67\x31\x4f\x24\x1e\xc4\x9f\x4a\x70\x61\xe3\xbd\x02\x13\xae\x82\x6b\xab\x38\x0f\x1f\x14\xfa\xab\x8b\x0e\xfd\xdd\x5f\xd1\xbb\x49\x37\x38\x53\xa0\x8f\x30\x55\x3d\x5a\x55\xcc\xbb\xb8\x15\x3d\xe4\x70\x4f\x29\xca\x2b\xde\xef\x04\x19\x46\x8e\x05\xdd\x51\x55\x7c\xcc\x80\xc0\xa9\x61\x90\xbb\xcc\x4d\x77\xec\xff\x21\xc6\x6b\xdf\x48\x64\x59\xd4\x27\xf9\x86\x41\x0f\x88\x3a\x80\xa5\xbc\xc3\x2c\x20\xf0\x47\x8b\xb9\xa9\x7a\x12\x6f\xc5\xf9\x54\x51\xe4\x0f\x29\x2a\x46\x14\x93\x0d\x05\x4c\x85\x1a\xcd\x01\x9c\xcf",
+       "\x06\x2e\x4a\x11\xa7\x9f\xdb\x9c\xbc\x3a\x0e\x4c\x5f\x98\x75\xca\xaa\x56\x8b\xc7\x13\x06\x6e\x02\xd2\xa9\xca\x4d\x27\x88\x6c\xe2\x3f\x70\x08\x3a\x2b\xf4\xd0\xe7\xc5\x5b\x12\x0f\xe6\xd1\x97\x20\x3d\xc1\xc2\xfd\x34\x69\x11\x2a\x08\x83\x67\x27\x85\x9e\x1f\x83",
+       161 },
+      { GCRY_MD_SHA3_512,
+       "\xfa\x85\x67\x1d\xf7\xda\xdf\x99\xa6\xff\xee\x97\xa3\xab\x99\x91\x67\x1f\x56\x29\x19\x50\x49\x88\x04\x97\x48\x78\x67\xa6\xc4\x46\xb6\x00\x87\xfa\xc9\xa0\xf2\xfc\xc8\xe3\xb2\x4e\x97\xe4\x23\x45\xb9\x3b\x5f\x7d\x36\x91\x82\x9d\x3f\x8c\xcd\x4b\xb3\x64\x11\xb8\x5f\xc2\x32\x8e\xb0\xc5\x1c\xb3\x15\x1f\x70\x86\x0a\xd3\x24\x6c\xe0\x62\x3a\x8d\xc8\xb3\xc4\x9f\x95\x8f\x86\x90\xf8\xe3\x86\x0e\x71\xeb\x2b\x14\x79\xa5\xce\xa0\xb3\xf8\xbe\xfd\x87\xac\xaf\x53\x62\x43\x5e\xae\xcc\xb5\x2f\x38\x61\x7b\xc6\xc5\xc2\xc6\xe2\x69\xea\xd1\xfb\xd6\x9e\x94\x1d\x4a\xd2\x01\x2d\xa2\xc5\xb2\x1b\xcf\xbf\x98\xe4\xa7\x7a\xb2\xaf\x1f\x3f\xda\x32\x33\xf0\x46\xd3\x8f\x1d\xc8",
+       "\x9e\x1c\x6e\xe0\xc4\x7b\x2d\x2c\xb7\x7f\x60\x2c\xab\x53\xac\x4c\x69\xc6\x97\x78\x29\x78\x94\x55\x41\x96\xcb\x58\x06\x03\x32\xc9\xfd\x89\x23\xf4\x5c\x4b\x8e\xc2\x6e\x16\xa5\xd0\x4e\x63\x07\xfb\x99\x85\x0a\x45\x40\xea\x83\xe3\xf2\x62\x6f\x33\x43\xe9\x72\x25",
+       162 },
+      { GCRY_MD_SHA3_512,
+       "\xe9\x08\x47\xae\x67\x97\xfb\xc0\xb6\xb3\x6d\x6e\x58\x8c\x0a\x74\x3d\x72\x57\x88\xca\x50\xb6\xd7\x92\x35\x2e\xa8\x29\x4f\x5b\xa6\x54\xa1\x53\x66\xb8\xe1\xb2\x88\xd8\x4f\x51\x78\x24\x08\x27\x97\x5a\x76\x3b\xc4\x5c\x7b\x04\x30\xe8\xa5\x59\xdf\x44\x88\x50\x5e\x00\x9c\x63\xda\x99\x4f\x14\x03\xf4\x07\x95\x82\x03\xce\xbb\x6e\x37\xd8\x9c\x94\xa5\xea\xcf\x60\x39\xa3\x27\xf6\xc4\xdb\xbc\x7a\x2a\x30\x7d\x97\x6a\xa3\x9e\x41\xaf\x65\x37\x24\x3f\xc2\x18\xdf\xa6\xab\x4d\xd8\x17\xb6\xa3\x97\xdf\x5c\xa6\x91\x07\xa9\x19\x87\x99\xed\x24\x86\x41\xb6\x3b\x42\xcb\x4c\x29\xbf\xdd\x79\x75\xac\x96\xed\xfc\x27\x4a\xc5\x62\xd0\x47\x4c\x60\x34\x7a\x07\x8c\xe4\xc2\x5e\x88",
+       "\xf1\x8f\x0b\x07\x2a\x6b\xf6\x08\xa6\xc7\x42\x0e\x89\x1b\xe3\x79\x5a\x6d\x19\xba\x3e\x12\x76\xc8\x26\xf1\xae\x77\x5c\xf1\x25\xe4\x28\xae\x1a\x39\x7c\xfd\x07\x4b\xe0\xcd\x24\xf7\x10\x0f\x51\x80\x0f\x14\x47\x1c\xcf\x4f\x48\x5a\x65\x71\xe2\xb3\x2e\x02\x61\x1f",
+       163 },
+      { GCRY_MD_SHA3_512,
+       "\xf6\xd5\xc2\xb6\xc9\x39\x54\xfc\x62\x76\x02\xc0\x0c\x4c\xa9\xa7\xd3\xed\x12\xb2\x71\x73\xf0\xb2\xc9\xb0\xe4\xa5\x93\x93\x98\xa6\x65\xe6\x7e\x69\xd0\xb1\x2f\xb7\xe4\xce\xb2\x53\xe8\x08\x3d\x1c\xeb\x72\x4a\xc0\x7f\x00\x9f\x09\x4e\x42\xf2\xd6\xf2\x12\x94\x89\xe8\x46\xea\xff\x07\x00\xa8\xd4\x45\x3e\xf4\x53\xa3\xed\xdc\x18\xf4\x08\xc7\x7a\x83\x27\x56\x17\xfa\xbc\x4e\xa3\xa2\x83\x3a\xa7\x34\x06\xc0\xe9\x66\x27\x60\x79\xd3\x8e\x8e\x38\x53\x9a\x70\xe1\x94\xcc\x55\x13\xaa\xa4\x57\xc6\x99\x38\x3f\xd1\x90\x0b\x1e\x72\xbd\xfb\x83\x5d\x1f\xd3\x21\xb3\x7b\xa8\x05\x49\xb0\x78\xa4\x9e\xa0\x81\x52\x86\x9a\x91\x8c\xa5\x7f\x5b\x54\xed\x71\xe4\xfd\x3a\xc5\xc0\x67\x29",
+       "\x28\x59\xa3\x16\x5f\x38\xcb\x59\xde\x42\x75\x65\x8b\xba\xe9\xa0\xad\x64\x7d\x97\x2c\xf9\x8f\xa0\xee\xc4\xc0\x7e\xe7\x5d\x57\x6d\xbf\x9f\x5d\xd1\x9a\x88\x1d\xb4\xe4\xf7\xdb\x31\xec\x0d\x77\x16\x59\x11\x32\x9c\xbe\x8a\x46\xd1\x4d\x3e\xa7\xfd\xcb\x8a\x5c\x80",
+       164 },
+      { GCRY_MD_SHA3_512,
+       "\xcf\x85\x62\xb1\xbe\xd8\x98\x92\xd6\x7d\xda\xaf\x3d\xee\xb2\x82\x46\x45\x6e\x97\x23\x26\xdb\xcd\xb5\xcf\x3f\xb2\x89\xac\xa0\x1e\x68\xda\x5d\x59\x89\x6e\x3a\x61\x65\x35\x8b\x07\x1b\x30\x4d\x6a\xb3\xd0\x18\x94\x4b\xe5\x04\x9d\x5e\x0e\x2b\xb8\x19\xac\xf6\x7a\x60\x06\x11\x10\x89\xe6\x76\x71\x32\xd7\x2d\xd8\x5b\xed\xdc\xbb\x2d\x64\x49\x6d\xb0\xcc\x92\x95\x5a\xb4\xc6\x23\x4f\x1e\xea\x24\xf2\xd5\x14\x83\xf2\xe2\x09\xe4\x58\x9b\xf9\x51\x9f\xac\x51\xb4\xd0\x61\xe8\x01\x12\x5e\x60\x5f\x80\x93\xbb\x69\x97\xbc\x16\x3d\x55\x15\x96\xfe\x4a\xb7\xcf\xae\x8f\xb9\xa9\x0f\x69\x80\x48\x0c\xe0\xc2\x29\xfd\x16\x75\x40\x9b\xd7\x88\x35\x4d\xaf\x31\x62\x40\xcf\xe0\xaf\x93\xeb",
+       "\x92\x81\xbd\x03\xfe\x95\x54\x5e\x53\x21\xa9\x1a\x0a\xd8\xfa\x75\xa0\x05\xb9\x28\xc8\x34\x50\xdf\x65\x74\x19\x87\x0c\x4e\x98\x0e\x32\x48\x4f\xcf\x1f\x59\x87\x02\xed\x20\x40\x4f\xec\xe4\x8a\x2e\xe9\xdb\xcf\x22\x12\x06\x54\xae\x40\x29\x51\x60\x5b\xed\x19\x7e",
+       165 },
+      { GCRY_MD_SHA3_512,
+       "\x2a\xce\x31\xab\xb0\xa2\xe3\x26\x79\x44\xd2\xf7\x5e\x15\x59\x98\x5d\xb7\x35\x4c\x6e\x60\x5f\x18\xdc\x84\x70\x42\x3f\xca\x30\xb7\x33\x1d\x9b\x33\xc4\xa4\x32\x67\x83\xd1\xca\xae\x1b\x4f\x07\x06\x0e\xff\x97\x8e\x47\x46\xbf\x0c\x7e\x30\xcd\x61\x04\x0b\xd5\xec\x27\x46\xb2\x98\x63\xeb\x7f\x10\x3e\xbd\xa6\x14\xc4\x29\x1a\x80\x5b\x6a\x4c\x82\x14\x23\x05\x64\xa0\x55\x7b\xc7\x10\x2e\x0b\xd3\xed\x23\x71\x92\x52\xf7\x43\x5d\x64\xd2\x10\xee\x2a\xaf\xc5\x85\xbe\x90\x3f\xa4\x1e\x19\x68\xc5\x0f\xd5\xd5\x36\x79\x26\xdf\x7a\x05\xe3\xa4\x2c\xf0\x7e\x65\x6f\xf9\x2d\xe7\x3b\x03\x6c\xf8\xb1\x98\x98\xc0\xcb\x34\x55\x7c\x0c\x12\xc2\xd8\xb8\x4e\x91\x18\x1a\xf4\x67\xbc\x75\xa9\xd1",
+       "\x6c\xa7\x02\x3e\x20\x73\x56\x24\xe8\x39\x95\xa9\xe8\xae\xba\x66\xb9\xbc\x8d\x0a\x30\xdf\x67\x10\x8e\xff\x8a\xed\xeb\x3b\x3c\xa4\x84\x45\x7b\xd0\x27\x7c\x25\x52\xcb\xc7\xd6\x3d\xc8\x7e\xb5\x56\xf2\x19\x9c\x54\xea\x73\xba\xe6\x47\x76\x4d\xe1\x84\x89\xb1\xf1",
+       166 },
+      { GCRY_MD_SHA3_512,
+       "\x0d\x8d\x09\xae\xd1\x9f\x10\x13\x96\x9c\xe5\xe7\xeb\x92\xf8\x3a\x20\x9a\xe7\x6b\xe3\x1c\x75\x48\x44\xea\x91\x16\xce\xb3\x9a\x22\xeb\xb6\x00\x30\x17\xbb\xcf\x26\x55\x5f\xa6\x62\x41\x85\x18\x7d\xb8\xf0\xcb\x35\x64\xb8\xb1\xc0\x6b\xf6\x85\xd4\x7f\x32\x86\xed\xa2\x0b\x83\x35\x8f\x59\x9d\x20\x44\xbb\xf0\x58\x3f\xab\x8d\x78\xf8\x54\xfe\x0a\x59\x61\x83\x23\x0c\x5e\xf8\xe5\x44\x26\x75\x0e\xaf\x2c\xc4\xe2\x9d\x3b\xdd\x03\x7e\x73\x4d\x86\x3c\x2b\xd9\x78\x9b\x4c\x24\x30\x96\x13\x8f\x76\x72\xc2\x32\x31\x4e\xff\xdf\xc6\x51\x34\x27\xe2\xda\x76\x91\x6b\x52\x48\x93\x3b\xe3\x12\xeb\x5d\xde\x4c\xf7\x08\x04\xfb\x25\x8a\xc5\xfb\x82\xd5\x8d\x08\x17\x7a\xc6\xf4\x75\x60\x17\xff\xf5",
+       "\xa9\x65\xe6\x99\xc1\xff\xae\xe3\x69\xb3\x65\x1c\x3a\x31\x85\x82\xae\x32\x9a\xe5\x1e\x6c\xcf\xb5\x27\x5f\x58\xf7\x48\xce\xdb\x8f\x6b\x84\x34\xfa\xc4\xa1\x13\x5a\xd9\xb5\x55\xaa\x8c\xc1\xff\x99\xa2\x22\x0c\xbe\x83\xbf\xc1\xc3\x74\xff\xc9\x27\xbb\x00\xab\xd3",
+       167 },
+      { GCRY_MD_SHA3_512,
+       "\xc3\x23\x6b\x73\xde\xb7\x66\x2b\xf3\xf3\xda\xa5\x8f\x13\x7b\x35\x8b\xa6\x10\x56\x0e\xf7\x45\x57\x85\xa9\xbe\xfd\xb0\x35\xa0\x66\xe9\x07\x04\xf9\x29\xbd\x96\x89\xce\xf0\xce\x3b\xda\x5a\xcf\x44\x80\xbc\xeb\x8d\x09\xd1\x0b\x09\x8a\xd8\x50\x0d\x9b\x60\x71\xdf\xc3\xa1\x4a\xf6\xc7\x75\x11\xd8\x1e\x3a\xa8\x84\x49\x86\xc3\xbe\xa6\xf4\x69\xf9\xe0\x21\x94\xc9\x28\x68\xcd\x5f\x51\x64\x62\x56\x79\x8f\xf0\x42\x49\x54\xc1\x43\x4b\xdf\xed\x9f\xac\xb3\x90\xb0\x7d\x34\x2e\x99\x29\x36\xe0\xf8\x8b\xfd\x0e\x88\x4a\x0d\xdb\x67\x9d\x05\x47\xcc\xde\xc6\x38\x42\x85\xa4\x54\x29\xd1\x15\xac\x7d\x23\x5a\x71\x72\x42\x02\x1d\x1d\xc3\x56\x41\xf5\xf0\xa4\x8e\x84\x45\xdb\xa5\x8e\x6c\xb2\xc8\xea",
+       "\x4b\x44\xec\x2d\x18\x48\xd0\xec\x43\xab\x07\x93\x39\x0d\x24\x53\x5f\x33\x28\xad\x23\xc5\xf8\xfc\x43\xf5\x57\x9b\xd1\x6d\x84\xbb\xa0\x8b\x23\x3b\x0b\x5e\x24\xe2\x2b\xf6\xca\x2d\xef\xea\xca\x16\xbb\x98\xf8\xcd\xea\xf2\x6e\xec\xf2\xfc\x94\xaf\xe4\x60\x4c\xf4",
+       168 },
+      { GCRY_MD_SHA3_512,
+       "\xb3\x9f\xeb\x82\x83\xea\xdc\x63\xe8\x18\x4b\x51\xdf\x5a\xe3\xfd\x41\xaa\xc8\xa9\x63\xbb\x0b\xe1\xcd\x08\xaa\x58\x67\xd8\xd9\x10\xc6\x69\x22\x1e\x73\x24\x33\x60\x64\x6f\x65\x53\xd1\xca\x05\xa8\x4e\x8d\xc0\xde\x05\xb6\x41\x9e\xc3\x49\xca\x99\x44\x80\x19\x3d\x01\xc9\x25\x25\xf3\xfb\x3d\xce\xfb\x08\xaf\xc6\xd2\x69\x47\xbd\xbb\xfd\x85\x19\x3f\x53\xb5\x06\x09\xc6\x14\x09\x05\xc5\x3a\x66\x86\xb5\x8e\x53\xa3\x19\xa5\x7b\x96\x23\x31\xed\xe9\x81\x49\xaf\x3d\xe3\x11\x8a\x81\x9d\xa4\xd7\x67\x06\xa0\x42\x4b\x4e\x1d\x29\x10\xb0\xed\x26\xaf\x61\xd1\x50\xeb\xcb\x46\x59\x5d\x42\x66\xa0\xbd\x7f\x65\x1b\xa4\x7d\x0c\x7f\x17\x9c\xa2\x85\x45\x00\x7d\x92\xe8\x41\x9d\x48\xfd\xfb\xd7\x44\xce",
+       "\x73\x16\x9f\x0b\xe2\x64\x56\x5e\x45\xfb\x8f\x46\x65\x75\x3e\x55\xf2\x40\x84\x6e\xb0\xd4\x81\xce\xf0\x27\x4e\x4a\x3d\x85\x95\x21\x76\x7d\x9f\x67\x5c\x06\x28\xdd\xce\x15\x52\x67\xba\x68\x6f\x21\x42\x80\x57\x13\xf2\x0c\x4c\x25\xe0\xb2\x43\x98\xc6\x5e\x34\x80",
+       169 },
+      { GCRY_MD_SHA3_512,
+       "\xa9\x83\xd5\x4f\x50\x38\x03\xe8\xc7\x99\x9f\x4e\xdb\xbe\x82\xe9\x08\x4f\x42\x21\x43\xa9\x32\xdd\xdd\xc4\x7a\x17\xb0\xb7\x56\x4a\x7f\x37\xa9\x9d\x07\x86\xe9\x94\x76\x42\x8d\x29\xe2\x9d\x3c\x19\x7a\x72\xbf\xab\x13\x42\xc1\x2a\x0f\xc4\x78\x7f\xd7\x01\x7d\x7a\x61\x74\x04\x9e\xa4\x3b\x57\x79\x16\x9e\xf7\x47\x2b\xdb\xbd\x94\x1d\xcb\x82\xfc\x73\xaa\xc4\x5a\x8a\x94\xc9\xf2\xbd\x34\x77\xf6\x1f\xd3\xb7\x96\xf0\x2a\x1b\x82\x64\xa2\x14\xc6\xfe\xa7\x4b\x70\x51\xb2\x26\xc7\x22\x09\x9e\xc7\x88\x3a\x46\x2b\x83\xb6\xaf\xdd\x40\x09\x24\x8b\x8a\x23\x7f\x60\x5f\xe5\xa0\x8f\xe7\xd8\xb4\x53\x21\x42\x1e\xbb\xa6\x7b\xd7\x0a\x0b\x00\xdd\xbf\x94\xba\xab\x7f\x35\x9d\x5d\x1e\xea\x10\x5f\x28\xdc\xfb",
+       "\x9e\x1c\x19\x6c\xb7\x3d\x1e\xfa\x28\x8d\x63\x90\x2c\x64\xce\x1a\x34\x0b\xcd\xb8\x19\x7f\x4a\xfe\xcb\x11\x18\xda\xdd\x0d\x07\x6b\x5f\xb7\xf6\xf8\x09\x66\x6c\xc5\x8d\x2a\x8c\x1a\x68\xc6\x5d\x0e\x91\x55\x4c\x41\xd0\x83\xf5\x6d\x7b\x3d\xd3\x7d\xf1\xb6\xc4\x94",
+       170 },
+      { GCRY_MD_SHA3_512,
+       "\xe4\xd1\xc1\x89\x7a\x0a\x86\x6c\xe5\x64\x63\x5b\x74\x22\x2f\x96\x96\xbf\x2c\x7f\x64\x0d\xd7\x8d\x7e\x2a\xca\x66\xe1\xb6\x1c\x64\x2b\xb0\x3e\xa7\x53\x6a\xae\x59\x78\x11\xe9\xbf\x4a\x7b\x45\x3e\xde\x31\xf9\x7b\x46\xa5\xf0\xef\x51\xa0\x71\xa2\xb3\x91\x8d\xf1\x6b\x15\x25\x19\xae\x37\x76\xf9\xf1\xed\xab\x4c\x2a\x37\x7c\x32\x92\xe9\x64\x08\x35\x9d\x36\x13\x84\x4d\x5e\xb3\x93\x00\x02\x83\xd5\xad\x34\x01\xa3\x18\xb1\x2f\xd1\x47\x4b\x86\x12\xf2\xbb\x50\xfb\x6a\x8b\x9e\x02\x3a\x54\xd7\xdd\xe2\x8c\x43\xd6\xd8\x85\x4c\x8d\x9d\x11\x55\x93\x5c\x19\x98\x11\xdb\xfc\x87\xe9\xe0\x07\x2e\x90\xeb\x88\x68\x1c\xc7\x52\x97\x14\xf8\xfb\x8a\x2c\x9d\x88\x56\x7a\xdf\xb9\x74\xee\x20\x5a\x9b\xf7\xb8\x48",
+       "\x0c\x42\x9c\xc1\x64\x25\x3c\x09\x53\x86\x68\x13\x5c\x94\x36\xfd\xbc\x79\xda\x8e\x1f\xbe\x92\xe7\xbb\xc6\xeb\x30\x62\x75\x91\xe7\x34\x7c\xcb\x43\xf7\xae\xc2\xd3\x7f\xf3\xda\xbc\xfc\x9f\xa0\xc8\x06\x29\x93\x7c\x0c\x17\x7c\x1c\x7e\xd0\xfc\x76\xa1\x5d\xf0\x75",
+       171 },
+      { GCRY_MD_SHA3_512,
+       "\xb1\x0c\x59\x72\x3e\x3d\xca\xdd\x6d\x75\xdf\x87\xd0\xa1\x58\x0e\x73\x13\x3a\x9b\x7d\x00\xcb\x95\xec\x19\xf5\x54\x70\x27\x32\x3b\xe7\x51\x58\xb1\x1f\x80\xb6\xe1\x42\xc6\xa7\x85\x31\x88\x6d\x90\x47\xb0\x8e\x55\x1e\x75\xe6\x26\x1e\x79\x78\x53\x66\xd7\x02\x4b\xd7\xcd\x9c\xf3\x22\xd9\xbe\x7d\x57\xfb\x66\x10\x69\xf2\x48\x1c\x7b\xb7\x59\xcd\x71\xb4\xb3\x6c\xa2\xbc\x2d\xf6\xd3\xa3\x28\xfa\xeb\xdb\x99\x5a\x97\x94\xa8\xd7\x21\x55\xed\x55\x1a\x1f\x87\xc8\x0b\xf6\x05\x9b\x43\xfc\x76\x49\x00\xb1\x8a\x1c\x24\x41\xf7\x48\x77\x43\xcf\x84\xe5\x65\xf6\x1f\x8d\xd2\xec\xe6\xb6\xcc\xc9\x44\x40\x49\x19\x7a\xaa\xf5\x3e\x92\x6f\xbe\xe3\xbf\xca\x8b\xe5\x88\xec\x77\xf2\x9d\x21\x1b\xe8\x9d\xe1\x8b\x15\xf6",
+       "\x70\x01\x12\xfa\x90\xa1\xa2\xfd\x03\x9a\x41\xb6\x48\x54\x01\x63\x4e\x75\x78\x40\xe4\x22\xae\xb4\xa2\x36\x63\x49\x58\x19\x2f\xfb\x2f\x2d\xdf\xa2\x25\x3f\xc1\xec\xb2\x11\xc7\xe0\x36\x09\x8b\x71\x4e\x62\xf7\xbf\x2b\x69\x75\xb1\xe9\x5f\xaa\x9b\x8d\x02\xa7\x3a",
+       172 },
+      { GCRY_MD_SHA3_512,
+       "\xdb\x11\xf6\x09\xba\xba\x7b\x0c\xa6\x34\x92\x6b\x1d\xd5\x39\xc8\xcb\xad\xa2\x49\x67\xd7\xad\xd4\xd9\x87\x6f\x77\xc2\xd8\x0c\x0f\x4d\xce\xfb\xd7\x12\x15\x48\x37\x35\x82\x70\x5c\xca\x24\x95\xbd\x2a\x43\x71\x6f\xe6\x4e\xd2\x6d\x05\x9c\xfb\x56\x6b\x33\x64\xbd\x49\xee\x07\x17\xbd\xd9\x81\x0d\xd1\x4d\x8f\xad\x80\xdb\xbd\xc4\xca\xfb\x37\xcc\x60\xfb\x0f\xe2\xa8\x0f\xb4\x54\x1b\x8c\xa9\xd5\x9d\xce\x45\x77\x38\xa9\xd3\xd8\xf6\x41\xaf\x8c\x3f\xd6\xda\x16\x2d\xc1\x6f\xc0\x1a\xac\x52\x7a\x4a\x02\x55\xb4\xd2\x31\xc0\xbe\x50\xf4\x4f\x0d\xb0\xb7\x13\xaf\x03\xd9\x68\xfe\x7f\x0f\x61\xed\x08\x24\xc5\x5c\x4b\x52\x65\x54\x8f\xeb\xd6\xaa\xd5\xc5\xee\xdf\x63\xef\xe7\x93\x48\x9c\x39\xb8\xfd\x29\xd1\x04\xce",
+       "\x90\x1c\x6d\x85\x50\x9f\x01\xa4\x7e\xa2\xe2\x79\x2a\x5d\xb7\x28\xea\x39\xe5\x70\x3e\xed\xea\xe4\x13\x65\xed\xf1\x0a\x86\x6b\x92\x2b\x10\x93\xe5\x2e\x68\x7e\x31\x2d\xb1\x29\xda\x1f\x05\x3e\xf6\x84\x8c\xb0\xb3\x14\xc9\xa3\xa9\x99\xeb\x3e\x75\xe1\x4c\x9c\xc2",
+       173 },
+      { GCRY_MD_SHA3_512,
+       "\xbe\xbd\x4f\x1a\x84\xfc\x8b\x15\xe4\x45\x2a\x54\xbd\x02\xd6\x9e\x30\x4b\x7f\x32\x61\x6a\xad\xd9\x05\x37\x93\x71\x06\xae\x4e\x28\xde\x9d\x8a\xab\x02\xd1\x9b\xc3\xe2\xfd\xe1\xd6\x51\x55\x9e\x29\x64\x53\xe4\xdb\xa9\x43\x70\xa1\x4d\xbb\xb2\xd1\xd4\xe2\x02\x23\x02\xee\x90\xe2\x08\x32\x1e\xfc\xd8\x52\x8a\xd8\x9e\x46\xdc\x83\x9e\xa9\xdf\x61\x8e\xa8\x39\x4a\x6b\xff\x30\x8e\x77\x26\xba\xe0\xc1\x9b\xcd\x4b\xe5\x2d\xa6\x25\x8e\x2e\xf4\xe9\x6a\xa2\x12\x44\x42\x9f\x49\xef\x5c\xb4\x86\xd7\xff\x35\xca\xc1\xba\xcb\x7e\x95\x71\x19\x44\xbc\xcb\x2a\xb3\x47\x00\xd4\x2d\x1e\xb3\x8b\x5d\x53\x6b\x94\x73\x48\xa4\x58\xed\xe3\xdc\x6b\xd6\xec\x54\x7b\x1b\x0c\xae\x5b\x25\x7b\xe3\x6a\x71\x24\xe1\x06\x0c\x17\x0f\xfa",
+       "\x4c\xc9\xa6\x1f\xfe\x08\x98\x44\x17\x71\x2b\x80\xf9\x62\x36\x5a\xf3\x6e\xd6\x6a\x8a\xab\x2a\x78\x8d\x22\xa5\xc6\xb2\x39\x62\xd2\x35\x84\x63\x8e\x71\x2e\x91\x83\xc0\xa2\x71\x38\x3d\xb0\x87\x7f\x72\x2d\x39\x91\x16\xf9\xbe\xf7\x9a\x56\xab\x09\x6e\xf2\x17\x49",
+       174 },
+      { GCRY_MD_SHA3_512,
+       "\x5a\xca\x56\xa0\x3a\x13\x78\x4b\xdc\x32\x89\xd9\x36\x4f\x79\xe2\xa8\x5c\x12\x27\x6b\x49\xb9\x2d\xb0\xad\xaa\x4f\x20\x6d\x50\x28\xf2\x13\xf6\x78\xc3\x51\x0e\x11\x1f\x9d\xc4\xc1\xc1\xf8\xb6\xac\xb1\x7a\x64\x13\xaa\x22\x76\x07\xc5\x15\xc6\x2a\x73\x38\x17\xba\x5e\x76\x2c\xc6\x74\x8e\x7e\x0d\x68\x72\xc9\x84\xd7\x23\xc9\xbb\x3b\x11\x7e\xb8\x96\x31\x85\x30\x0a\x80\xbf\xa6\x5c\xde\x49\x5d\x70\xa4\x6c\x44\x85\x86\x05\xfc\xcb\xed\x08\x6c\x2b\x45\xce\xf9\x63\xd3\x32\x94\xdb\xe9\x70\x6b\x13\xaf\x22\xf1\xb7\xc4\xcd\x5a\x00\x1c\xfe\xc2\x51\xfb\xa1\x8e\x72\x2c\x6e\x1c\x4b\x11\x66\x91\x8b\x4f\x6f\x48\xa9\x8b\x64\xb3\xc0\x7f\xc8\x6a\x6b\x17\xa6\xd0\x48\x0a\xb7\x9d\x4e\x64\x15\xb5\x20\xf1\xc4\x84\xd6\x75\xb1",
+       "\xb3\x6e\xa5\x6b\xb6\xbf\x80\xd9\x1d\x5a\x60\x5f\x84\x09\xae\x6b\x7d\x87\x9e\xc4\x08\x15\xb3\x5c\x66\x4c\xc6\xb0\x1b\xf6\xc7\x18\xad\x46\x4f\x15\xc3\x4d\xd1\x31\x5a\x79\xa5\x45\x6b\x6c\x3f\x8e\xd8\x9e\x60\x39\x0b\xc7\x1e\xf7\x47\xe1\x2c\xdc\x77\x70\x62\x45",
+       175 },
+      { GCRY_MD_SHA3_512,
+       "\xa5\xaa\xd0\xe4\x64\x6a\x32\xc8\x5c\xfc\xac\x73\xf0\x2f\xc5\x30\x0f\x19\x82\xfa\xbb\x2f\x21\x79\xe2\x83\x03\xe4\x47\x85\x40\x94\xcd\xfc\x85\x43\x10\xe5\xc0\xf6\x09\x93\xce\xff\x54\xd8\x4d\x6b\x46\x32\x3d\x93\x0a\xdb\x07\xc1\x75\x99\xb3\x5b\x50\x5f\x09\xe7\x84\xbc\xa5\x98\x5e\x01\x72\x25\x77\x97\xfb\x53\x64\x9e\x2e\x97\x23\xef\xd1\x68\x65\xc3\x1b\x5c\x3d\x51\x13\xb5\x8b\xb0\xbf\xc8\x92\x0f\xab\xdd\xa0\x86\xd7\x53\x7e\x66\xd7\x09\xd0\x50\xbd\x14\xd0\xc9\x60\x87\x3f\x15\x6f\xad\x5b\x3d\x38\x40\xcd\xfc\xdc\x9b\xe6\xaf\x51\x9d\xb2\x62\xa2\x7f\x40\x89\x6a\xb2\x5c\xc3\x9f\x96\x98\x4d\x65\x06\x11\xc0\xd5\xa3\x08\x0d\x5b\x3a\x1b\xf1\x86\xab\xd4\x29\x56\x58\x8b\x3b\x58\xcd\x94\x89\x70\xd2\x98\x77\x60\x60",
+       "\x8e\xcb\x8f\x62\x2d\xab\x70\x87\xe9\xa9\x5c\xd0\x34\x11\x92\xfe\xa6\xb1\xc9\x56\xdf\x9a\xd3\xde\xd8\x23\x94\x8b\x78\x49\xc4\xf3\x15\x0c\x95\x59\x52\x09\x53\xeb\xde\x98\xed\x76\xf6\xe4\x3b\xfe\x4f\xb2\x5f\xda\x71\x25\x25\xc6\xd3\xda\xa8\x03\x23\xbe\x8e\x4a",
+       176 },
+      { GCRY_MD_SHA3_512,
+       "\x06\xcb\xbe\x67\xe9\x4a\x97\x82\x03\xea\xd6\xc0\x57\xa1\xa5\xb0\x98\x47\x8b\x4b\x4c\xbe\xf5\xa9\x7e\x93\xc8\xe4\x2f\x55\x72\x71\x35\x75\xfc\x2a\x88\x45\x31\xd7\x62\x2f\x8f\x87\x93\x87\xa8\x59\xa8\x0f\x10\xef\x02\x70\x8c\xd8\xf7\x41\x3a\xb3\x85\xaf\xc3\x57\x67\x8b\x95\x78\xc0\xeb\xf6\x41\xef\x07\x6a\x1a\x30\xf1\xf7\x53\x79\xe9\xdc\xb2\xa8\x85\xbd\xd2\x95\x90\x5e\xe8\x0c\x01\x68\xa6\x2a\x95\x97\xd1\x0c\xf1\x2d\xd2\xd8\xce\xe4\x66\x45\xc7\xe5\xa1\x41\xf6\xe0\xe2\x3a\xa4\x82\xab\xe5\x66\x1c\x16\xe6\x9e\xf1\xe2\x83\x71\xe2\xe2\x36\xc3\x59\xba\x4e\x92\xc2\x56\x26\xa7\xb7\xff\x13\xf6\xea\x4a\xe9\x06\xe1\xcf\xe1\x63\xe9\x17\x19\xb1\xf7\x50\xa9\x6c\xbd\xe5\xfb\xc9\x53\xd9\xe5\x76\xcd\x21\x6a\xfc\x90\x32\x3a",
+       "\x51\x92\x15\xda\x34\xac\xfc\xd6\x2d\xd6\x17\xec\xd5\x97\x83\x65\x41\x7d\x57\xc2\x67\x1a\x7b\x48\x65\x5b\x89\xf4\x48\xb2\x3b\x12\x8d\x3a\xd0\x49\x10\xa1\xbb\xbd\xc0\x0e\x95\x4a\x1e\x49\x76\x51\x76\xa8\xac\xa4\xc3\x7d\x56\xab\xf0\xe0\xb7\x2e\x33\x1a\x8d\x7c",
+       177 },
+      { GCRY_MD_SHA3_512,
+       "\xf1\xc5\x28\xcf\x77\x39\x87\x47\x07\xd4\xd8\xad\x5b\x98\xf7\xc7\x71\x69\xde\x0b\x57\x18\x8d\xf2\x33\xb2\xdc\x8a\x5b\x31\xed\xa5\xdb\x42\x91\xdd\x9f\x68\xe6\xba\xd3\x7b\x8d\x7f\x6c\x9c\x00\x44\xb3\xbf\x74\xbb\xc3\xd7\xd1\x79\x8e\x13\x87\x09\xb0\xd7\x5e\x7c\x59\x3d\x3c\xcc\xdc\x1b\x20\xc7\x17\x4b\x4e\x69\x2a\xdd\x82\x0a\xce\x26\x2d\x45\xcc\xfa\xe2\x07\x7e\x87\x87\x96\x34\x71\x68\x06\x0a\x16\x2e\xcc\xa8\xc3\x8c\x1a\x88\x35\x0b\xd6\x3b\xb5\x39\x13\x4f\x70\x0f\xd4\xad\xdd\x59\x59\xe2\x55\x33\x7d\xaa\x06\xbc\x86\x35\x8f\xab\xcb\xef\xdf\xb5\xbc\x88\x97\x83\xd8\x43\xc0\x8a\xad\xc6\xc4\xf6\xc3\x6f\x65\xf1\x56\xe8\x51\xc9\xa0\xf9\x17\xe4\xa3\x67\xb5\xad\x93\xd8\x74\x81\x2a\x1d\xe6\xa7\xb9\x3c\xd5\x3a\xd9\x72\x32",
+       "\x0d\x1c\x1a\xd4\xe1\xcf\xef\xee\x85\x4c\x4a\x73\x9a\x03\x42\xe3\x9d\x70\x0d\xba\xf4\x89\x19\x78\xd7\xc8\x39\xe8\x7c\x68\x07\x17\xd6\x3a\xb4\xaa\x1e\xd7\xeb\x65\x7c\xed\x9f\x8d\x2c\xf4\x72\x04\x26\x2e\x60\x96\x10\x84\x2f\xc5\xb2\x19\xac\xff\x7e\xb1\x88\xc4",
+       178 },
+      { GCRY_MD_SHA3_512,
+       "\x9d\x9f\x3a\x7e\xcd\x51\xb4\x1f\x65\x72\xfd\x0d\x08\x81\xe3\x03\x90\xdf\xb7\x80\x99\x1d\xae\x7d\xb3\xb4\x76\x19\x13\x47\x18\xe6\xf9\x87\x81\x0e\x54\x26\x19\xdf\xaa\x7b\x50\x5c\x76\xb7\x35\x0c\x64\x32\xd8\xbf\x1c\xfe\xbd\xf1\x06\x9b\x90\xa3\x5f\x0d\x04\xcb\xdf\x13\x0b\x0d\xfc\x78\x75\xf4\xa4\xe6\x2c\xdb\x8e\x52\x5a\xad\xd7\xce\x84\x25\x20\xa4\x82\xac\x18\xf0\x94\x42\xd7\x83\x05\xfe\x85\xa7\x4e\x39\xe7\x60\xa4\x83\x74\x82\xed\x2f\x43\x7d\xd1\x3b\x2e\xc1\x04\x2a\xfc\xf9\xde\xcd\xc3\xe8\x77\xe5\x0f\xf4\x10\x6a\xd1\x0a\x52\x52\x30\xd1\x19\x20\x32\x4a\x81\x09\x4d\xa3\x1d\xea\xb6\x47\x6a\xa4\x2f\x20\xc8\x48\x43\xcf\xc1\xc5\x85\x45\xee\x80\x35\x2b\xdd\x37\x40\xdd\x6a\x16\x79\x2a\xe2\xd8\x6f\x11\x64\x1b\xb7\x17\xc2",
+       "\x0a\x5d\x9e\xf4\x0b\xa2\xb9\x8e\xdb\xd7\x91\x8c\xc6\x77\x94\x83\xa1\xa0\x0b\xd9\x4c\xc1\xe1\x49\x54\x95\xca\xf6\xcd\x47\xc6\x23\x95\x71\xc3\x82\x8f\x45\x65\xa0\xd5\x37\x86\x78\x1d\x71\x2c\x10\xef\x73\x33\x22\x7f\x65\x19\x74\x62\x88\x87\xd4\x42\xa5\xef\x9d",
+       179 },
+      { GCRY_MD_SHA3_512,
+       "\x51\x79\x88\x87\x24\x81\x9f\xba\xd3\xaf\xa9\x27\xd3\x57\x77\x96\x66\x0e\x6a\x81\xc5\x2d\x98\xe9\x30\x32\x61\xd5\xa4\xa8\x32\x32\xf6\xf7\x58\x93\x4d\x50\xaa\x83\xff\x9e\x20\xa5\x92\x6d\xfe\xba\xac\x49\x52\x9d\x00\x6e\xb9\x23\xc5\xae\x50\x48\xed\x54\x4e\xc4\x71\xed\x71\x91\xed\xf4\x63\x63\x38\x38\x24\xf9\x15\x76\x9b\x3e\x68\x80\x94\xc6\x82\xb0\x21\x51\xe5\xee\x01\xe5\x10\xb4\x31\xc8\x86\x5a\xff\x8b\x6b\x6f\x2f\x59\xcb\x6d\x12\x9d\xa7\x9e\x97\xc6\xd2\xb8\xfa\x6c\x6d\xa3\xf6\x03\x19\x9d\x2d\x1b\xca\xb5\x47\x68\x2a\x81\xcd\x6c\xf6\x5f\x65\x51\x12\x13\x91\xd7\x8b\xcc\x23\xb5\xbd\x0e\x92\x2e\xc6\xd8\xbf\x97\xc9\x52\xe8\x4d\xd2\x8a\xef\x90\x9a\xba\x31\xed\xb9\x03\xb2\x8f\xbf\xc3\x3b\x77\x03\xcd\x99\x62\x15\xa1\x12\x38",
+       "\xea\x83\xde\x9a\xe0\x57\x70\x1f\x6e\xc6\x8f\xf6\x7e\x92\xe0\x33\x4c\x18\xeb\xb7\x9a\xf1\x95\x3c\x25\x14\x40\x8d\x58\xe6\x9f\x10\x54\x41\x64\x2a\x1d\x5b\x7d\x60\x10\xf7\xcb\x15\xd1\x31\xdd\x53\x18\x55\xca\x33\x7a\x7b\x0b\x79\x4f\xa6\xd6\x92\x3f\x01\x7a\xfa",
+       180 },
+      { GCRY_MD_SHA3_512,
+       "\x57\x6e\xf3\x52\x0d\x30\xb7\xa4\x89\x9b\x8c\x0d\x5e\x35\x9e\x45\xc5\x18\x9a\xdd\x10\x0e\x43\xbe\x42\x9a\x02\xfb\x3d\xe5\xff\x4f\x8f\xd0\xe7\x9d\x96\x63\xac\xca\x72\xcd\x29\xc9\x45\x82\xb1\x92\x92\xa5\x57\xc5\xb1\x31\x52\x97\xd1\x68\xfb\xb5\x4e\x9e\x2e\xcd\x13\x80\x9c\x2b\x5f\xce\x99\x8e\xdc\x65\x70\x54\x5e\x14\x99\xdb\xe7\xfb\x74\xd4\x7c\xd7\xf3\x58\x23\xb2\x12\xb0\x5b\xf3\xf5\xa7\x9c\xaa\x34\x22\x4f\xdd\x67\x0d\x33\x5f\xcb\x10\x6f\x5d\x92\xc3\x94\x6f\x44\xd3\xaf\xcb\xae\x2e\x41\xac\x55\x4d\x8e\x67\x59\xf3\x32\xb7\x6b\xe8\x9a\x03\x24\xaa\x12\xc5\x48\x2d\x1e\xa3\xee\x89\xde\xd4\x93\x6f\x3e\x3c\x08\x04\x36\xf5\x39\xfa\x13\x7e\x74\xc6\xd3\x38\x9b\xdf\x5a\x45\x07\x4c\x47\xbc\x7b\x20\xb0\x94\x84\x07\xa6\x6d\x85\x5e\x2f",
+       "\x66\x51\xc2\x5d\x33\xd1\x0b\x72\x53\x5f\x1d\xb2\x6a\x1d\xfe\x2e\xb9\x9c\xdd\x50\x54\x48\x01\x85\x89\xb5\xb8\x8b\x7c\xab\x63\xeb\x43\x9c\x31\xa4\x74\xc6\xf1\x19\x1d\xf1\x4e\xfc\x7d\x06\x65\xcc\x7b\x82\xa7\xdc\x54\xa7\xc6\xb0\xc2\xfd\x1f\x75\xc3\x0d\x68\x72",
+       181 },
+      { GCRY_MD_SHA3_512,
+       "\x0d\xf2\x15\x2f\xa4\xf4\x35\x7c\x87\x41\x52\x9d\xd7\x7e\x78\x39\x25\xd3\xd7\x6e\x95\xba\xfa\x2b\x54\x2a\x2c\x33\xf3\xd1\xd1\x17\xd1\x59\xcf\x47\x3f\x82\x31\x03\x56\xfe\xe4\xc9\x0a\x9e\x50\x5e\x70\xf8\xf2\x48\x59\x65\x63\x68\xba\x09\x38\x1f\xa2\x45\xeb\x6c\x3d\x76\x3f\x30\x93\xf0\xc8\x9b\x97\x2e\x66\xb5\x3d\x59\x40\x6d\x9f\x01\xae\xa0\x7f\x8b\x3b\x61\x5c\xac\x4e\xe4\xd0\x5f\x54\x2e\x7d\x0d\xab\x45\xd6\x7c\xcc\xcd\x3a\x60\x6c\xcb\xeb\x31\xea\x1f\xa7\x00\x5b\xa0\x71\x76\xe6\x0d\xab\x7d\x78\xf6\x81\x0e\xf0\x86\xf4\x2f\x08\xe5\x95\xf0\xec\x21\x73\x72\xb9\x89\x70\xcc\x63\x21\x57\x6d\x92\xce\x38\xf7\xc3\x97\xa4\x03\xba\xda\x15\x48\xd2\x05\xc3\x43\xac\x09\xde\xca\x86\x32\x53\x73\xc3\xb7\x6d\x9f\x32\x02\x8f\xea\x8e\xb3\x25\x15",
+       "\xa7\x54\x65\x22\x47\xf7\x28\x5c\xe2\xdd\x8a\x10\x03\x5c\x69\x96\x1e\x4f\x9c\x02\x5e\x1f\xd0\x87\xcb\xd3\x12\x6e\x04\x9a\x9e\x83\x2c\x3f\x3a\x49\x1f\xcd\xe3\x38\xb8\xc0\x19\x46\xcd\xd7\xde\xc3\x2a\x8f\xd7\xed\x1c\xb3\x04\x5b\xca\xf3\x39\x89\x05\xb1\xbb\x42",
+       182 },
+      { GCRY_MD_SHA3_512,
+       "\x3e\x15\x35\x0d\x87\xd6\xeb\xb5\xc8\xad\x99\xd4\x25\x15\xcf\xe1\x79\x80\x93\x3c\x7a\x8f\x6b\x8b\xbb\xf0\xa6\x37\x28\xce\xfa\xad\x20\x52\x62\x3c\x0b\xd5\x93\x18\x39\x11\x2a\x48\x63\x3f\xb3\xc2\x00\x4e\x07\x49\xc8\x7a\x41\xb2\x6a\x8b\x48\x94\x55\x39\xd1\xff\x41\xa4\xb2\x69\x46\x2f\xd1\x99\xbf\xec\xd4\x53\x74\x75\x6f\x55\xa9\x11\x6e\x92\x09\x3a\xc9\x94\x51\xae\xfb\x2a\xf9\xfd\x32\xd6\xd7\xf5\xfb\xc7\xf7\xa5\x40\xd5\x09\x7c\x09\x6e\xbc\x3b\x3a\x72\x15\x41\xde\x07\x3a\x1c\xc0\x2f\x7f\xb0\xfb\x1b\x93\x27\xfb\x0b\x12\x18\xca\x49\xc9\x48\x7a\xb5\x39\x66\x22\xa1\x3a\xe5\x46\xc9\x7a\xbd\xef\x6b\x56\x38\x0d\xda\x70\x12\xa8\x38\x40\x91\xb6\x65\x6d\x0a\xb2\x72\xd3\x63\xce\xa7\x81\x63\xff\x76\x5c\xdd\x13\xab\x17\x38\xb9\x40\xd1\x6c\xae",
+       "\xfc\x11\x27\xf6\x65\x0f\x32\x63\x84\x53\xab\x77\x3f\x5c\xe6\x0f\x9f\x61\x65\xbc\x99\x28\xef\xf1\x8c\x7a\x32\x81\x54\x0c\x7a\x61\x5d\x2d\x62\xa9\x2e\x55\x7d\x4a\x1e\xc1\x22\x9e\x84\x81\x9d\x2d\xbf\x06\xce\xd4\xde\x0f\xf9\x00\x40\xec\xb9\x61\xd6\x78\xe1\x81",
+       183 },
+      { GCRY_MD_SHA3_512,
+       "\xc3\x8d\x6b\x0b\x75\x7c\xb5\x52\xbe\x40\x94\x0e\xce\x00\x09\xef\x3b\x0b\x59\x30\x7c\x14\x51\x68\x6f\x1a\x22\x70\x29\x22\x80\x0d\x58\xbc\xe7\xa6\x36\xc1\x72\x7e\xe5\x47\xc0\x1b\x21\x47\x79\xe8\x98\xfc\x0e\x56\x0f\x8a\xe7\xf6\x1b\xef\x4d\x75\xea\xa6\x96\xb9\x21\xfd\x6b\x73\x5d\x17\x15\x35\xe9\xed\xd2\x67\xc1\x92\xb9\x98\x80\xc8\x79\x97\x71\x10\x02\x00\x90\x95\xd8\xa7\xa4\x37\xe2\x58\x10\x4a\x41\xa5\x05\xe5\xef\x71\xe5\x61\x3d\xdd\x20\x08\x19\x5f\x0c\x57\x4e\x6b\xa3\xfe\x40\x09\x9c\xfa\x11\x6e\x5f\x1a\x2f\xa8\xa6\xda\x04\xba\xdc\xb4\xe2\xd5\xd0\xde\x31\xfd\xc4\x80\x08\x91\xc4\x57\x81\xa0\xaa\xc7\xc9\x07\xb5\x6d\x63\x1f\xca\x5c\xe8\xb2\xcd\xe6\x20\xd1\x1d\x17\x77\xed\x9f\xa6\x03\x54\x1d\xe7\x94\xdd\xc5\x75\x8f\xcd\x5f\xad\x78\xc0",
+       "\x43\xc2\x1b\xcc\xac\x7a\xce\xe8\xed\x43\x7b\x87\x4e\xd7\xcd\xf2\x0e\xa2\xe9\xdc\x98\xab\x82\x12\x46\x10\xdc\x4f\x84\x16\x24\x8b\x51\x30\x90\x45\xcd\xfb\xce\x92\xef\xa9\xe5\x6c\x5b\x36\xd6\xe5\xd2\x75\x80\x31\x9c\xe6\x9c\x22\xe5\xd6\xc8\x7e\x55\x1e\xed\x4a",
+       184 },
+      { GCRY_MD_SHA3_512,
+       "\x8d\x2d\xe3\xf0\xb3\x7a\x63\x85\xc9\x07\x39\x80\x5b\x17\x00\x57\xf0\x91\xcd\x0c\x7a\x0b\xc9\x51\x54\x0f\x26\xa5\xa7\x5b\x3e\x69\x46\x31\xbb\x64\xc7\x63\x5e\xed\x31\x6f\x51\x31\x8e\x9d\x8d\xe1\x3c\x70\xa2\xab\xa0\x4a\x14\x83\x68\x55\xf3\x5e\x48\x05\x28\xb7\x76\xd0\xa1\xe8\xa2\x3b\x54\x7c\x8b\x8d\x6a\x0d\x09\xb2\x41\xd3\xbe\x93\x77\x16\x0c\xca\x4e\x67\x93\xd0\x0a\x51\x5d\xc2\x99\x2c\xb7\xfc\x74\x1d\xac\xa1\x71\x43\x1d\xa9\x9c\xce\x6f\x77\x89\xf1\x29\xe2\xac\x5c\xf6\x5b\x40\xd7\x03\x03\x5c\xd2\x18\x5b\xb9\x36\xc8\x20\x02\xda\xf8\xcb\xc2\x7a\x7a\x9e\x55\x4b\x06\x19\x66\x30\x44\x6a\x6f\x0a\x14\xba\x15\x5e\xd2\x6d\x95\xbd\x62\x7b\x72\x05\xc0\x72\xd0\x2b\x60\xdb\x0f\xd7\xe4\x9e\xa0\x58\xc2\xe0\xba\x20\x2d\xaf\xf0\xde\x91\xe8\x45\xcf\x79",
+       "\x89\x39\x34\xb8\xc6\x30\xa9\xbf\x71\x3c\x64\xff\xd1\x12\x8e\xac\x75\xd1\xce\xfd\xef\x66\x42\xfb\x27\xf2\x0c\xb5\x66\x94\xc2\xfa\x8b\xa6\xef\xcf\x3e\x0e\x56\xc7\x78\x9c\xfa\xac\x6b\x2f\x7b\x24\x7d\xea\x83\x67\xff\xd2\x69\xe7\x4b\x9c\xdf\xb0\x53\x70\x31\xea",
+       185 },
+      { GCRY_MD_SHA3_512,
+       "\xc4\x64\xbb\xda\xd2\x75\xc5\x0d\xcd\x98\x3b\x65\xad\x10\x19\xb9\xff\x85\xa1\xe7\x1c\x80\x7f\x32\x04\xbb\x2c\x92\x1d\xc3\x1f\xbc\xd8\xc5\xfc\x45\x86\x8a\xe9\xef\x85\xb6\xc9\xb8\x3b\xba\x2a\x5a\x82\x22\x01\xed\x68\x58\x6e\xc5\xec\x27\xfb\x28\x57\xa5\xd1\xa2\xd0\x9d\x09\x11\x5f\x22\xdc\xc3\x9f\xe6\x1f\x5e\x1b\xa0\xff\x6e\x8b\x4a\xcb\x4c\x6d\xa7\x48\xbe\x7f\x3f\x08\x39\x73\x93\x94\xff\x7f\xa8\xe3\x9f\x7f\x7e\x84\xa3\x3c\x38\x66\x87\x5c\x01\xbc\xb1\x26\x3c\x94\x05\xd9\x19\x08\xe9\xe0\xb5\x0e\x74\x59\xfa\xbb\x63\xd8\xc6\xbb\xb7\x3d\x8e\x34\x83\xc0\x99\xb5\x5b\xc3\x0f\xf0\x92\xff\x68\xb6\xad\xed\xfd\x47\x7d\x63\x57\x0c\x9f\x55\x15\x84\x7f\x36\xe2\x4b\xa0\xb7\x05\x55\x71\x30\xce\xc5\x7e\xba\xd1\xd0\xb3\x1a\x37\x8e\x91\x89\x4e\xe2\x6e\x3a\x04",
+       "\xb4\xcb\x58\xd8\x49\x79\x78\x91\x6d\xc3\x62\xd3\x7a\xde\x12\xc7\xa0\xd8\xfe\x3b\x08\xb3\x70\x65\x9b\x27\x21\x82\x91\xe0\x4e\xf3\x43\x09\x5a\x91\x88\x7b\x04\x09\x84\xcb\x80\xb0\xc8\x61\x1f\xd1\x2c\x18\xea\xd3\x7b\x95\x32\x0d\x59\xed\xdb\x32\x11\x3e\x42\xa4",
+       186 },
+      { GCRY_MD_SHA3_512,
+       "\x8b\x8d\x68\xbb\x8a\x75\x73\x2f\xe2\x72\x81\x5a\x68\xa1\xc9\xc5\xaa\x31\xb4\x1d\xed\xc8\x49\x3e\x76\x52\x5d\x1d\x01\x3d\x33\xce\xbd\x9e\x21\xa5\xbb\x95\xdb\x26\x16\x97\x6a\x8c\x07\xfc\xf4\x11\xf5\xf6\xbc\x6f\x7e\x0b\x57\xac\xa7\x8c\xc2\x79\x0a\x6f\x9b\x89\x88\x58\xac\x9c\x79\xb1\x65\xff\x24\xe6\x66\x77\x53\x1e\x39\xf5\x72\xbe\x5d\x81\xeb\x32\x64\x52\x41\x81\x11\x5f\x32\x78\x02\x57\xbf\xb9\xae\xec\x6a\xf1\x2a\xf2\x8e\x58\x7c\xac\x06\x8a\x1a\x29\x53\xb5\x9a\xd6\x80\xf4\xc2\x45\xb2\xe3\xec\x36\xf5\x99\x40\xd3\x7e\x1d\x3d\xb3\x8e\x13\xed\xb2\x9b\x5c\x0f\x40\x4f\x6f\xf8\x7f\x80\xfc\x8b\xe7\xa2\x25\xff\x22\xfb\xb9\xc8\xb6\xb1\xd7\x33\x0c\x57\x84\x0d\x24\xbc\x75\xb0\x6b\x80\xd3\x0d\xad\x68\x06\x54\x4d\x51\x0a\xf6\xc4\x78\x5e\x82\x3a\xc3\xe0\xb8",
+       "\x35\xc3\xf8\xf0\xdc\x28\x60\x8e\xc9\x42\xcb\x62\x87\x48\x22\x19\xb4\x2b\x2e\xbc\xba\xd9\x2b\x4c\x34\xe7\x7e\x21\xb7\xd9\x3b\x0e\x85\xeb\xf4\x83\xdb\x2d\x4a\x97\x9c\x48\xe5\x8f\x74\x6a\xc3\xdc\xf5\x63\xca\x7e\x1b\x29\x40\x37\x1d\x8d\x83\xbf\x07\x95\xec\x45",
+       187 },
+      { GCRY_MD_SHA3_512,
+       "\x6b\x01\x87\x10\x44\x6f\x36\x8e\x74\x21\xf1\xbc\x0c\xcf\x56\x2d\x9c\x18\x43\x84\x6b\xc8\xd9\x8d\x1c\x9b\xf7\xd9\xd6\xfc\xb4\x8b\xfc\x3b\xf8\x3b\x36\xd4\x4c\x4f\xa9\x34\x30\xaf\x75\xcd\x19\x0b\xde\x36\xa7\xf9\x2f\x86\x7f\x58\xa8\x03\x90\x0d\xf8\x01\x81\x50\x38\x4d\x85\xd8\x21\x32\xf1\x23\x00\x6a\xc2\xae\xba\x58\xe0\x2a\x03\x7f\xe6\xaf\xbd\x65\xec\xa7\xc4\x49\x77\xdd\x3d\xc7\x4f\x48\xb6\xe7\xa1\xbf\xd5\xcc\x4d\xcf\x24\xe4\xd5\x2e\x92\xbd\x44\x55\x84\x8e\x49\x28\xb0\xea\xc8\xb7\x47\x6f\xe3\xcc\x03\xe8\x62\xaa\x4d\xff\x44\x70\xdb\xfe\xd6\xde\x48\xe4\x10\xf2\x50\x96\x48\x7e\xcf\xc3\x2a\x27\x27\x7f\x3f\x50\x23\xb2\x72\x5a\xde\x46\x1b\x13\x55\x88\x95\x54\xa8\x83\x6c\x9c\xf5\x3b\xd7\x67\xf5\x73\x7d\x55\x18\x4e\xea\x1a\xb3\xf5\x3e\xdd\x09\x76\xc4\x85",
+       "\xb9\x0e\x0c\xc6\xbc\x53\x18\x2c\x4f\x2d\x17\xaa\x51\x39\x1c\x82\x50\xc3\x03\x2a\x12\xda\xf2\xfc\xc6\x41\xb4\x9a\xa8\x1e\xd9\x44\x94\x03\x56\x7b\x75\xd4\x12\x13\x76\xdd\x8c\xc2\xd2\xbd\xba\xfa\x45\x63\x08\xad\x7c\x0c\x13\xba\x85\x61\x9d\x75\x35\x07\x27\xe3",
+       188 },
+      { GCRY_MD_SHA3_512,
+       "\xc9\x53\x4a\x24\x71\x4b\xd4\xbe\x37\xc8\x8a\x3d\xa1\x08\x2e\xda\x7c\xab\xd1\x54\xc3\x09\xd7\xbd\x67\x0d\xcc\xd9\x5a\xa5\x35\x59\x44\x63\x05\x8a\x29\xf7\x90\x31\xd6\xec\xaa\x9f\x67\x5d\x12\x11\xe9\x35\x9b\xe8\x26\x69\xa7\x9c\x85\x5e\xa8\xd8\x9d\xd3\x8c\x2c\x76\x1d\xdd\x0e\xc0\xce\x9e\x97\x59\x74\x32\xe9\xa1\xbe\xae\x06\x2c\xdd\x71\xed\xfd\xfd\x46\x41\x19\xbe\x9e\x69\xd1\x8a\x7a\x7f\xd7\xce\x0e\x21\x06\xf0\xc8\xb0\xab\xf4\x71\x5e\x2c\xa4\x8e\xf9\xf4\x54\xdc\x20\x3c\x96\x65\x66\x53\xb7\x27\x08\x35\x13\xf8\xef\xb8\x6e\x49\xc5\x13\xbb\x75\x8b\x3b\x05\x2f\xe2\x1f\x1c\x05\xbb\x33\xc3\x71\x29\xd6\xcc\x81\xf1\xae\xf6\xad\xc4\x5b\x0e\x88\x27\xa8\x30\xfe\x54\x5c\xf5\x7d\x09\x55\x80\x2c\x11\x7d\x23\xcc\xb5\x5e\xa2\x8f\x95\xc0\xd8\xc2\xf9\xc5\xa2\x42\xb3\x3f",
+       "\x99\x49\x73\x55\xae\x17\x91\x79\x9d\x11\x53\x6c\x73\x60\x5c\xdd\x14\x96\xc7\x4e\x3e\x93\x0b\x62\x72\xa1\x03\xc3\xaa\x8c\x98\x4d\x2d\x74\xb0\x1a\xe7\x2c\x94\xf2\xa4\xd3\xa0\x69\xea\xc6\xe0\x09\x84\xd2\x1e\xae\x3d\xd7\xb3\x2a\xd0\x82\xb3\x96\x60\x10\x93\xba",
+       189 },
+      { GCRY_MD_SHA3_512,
+       "\x07\x90\x6c\x87\x29\x7b\x86\x7a\xbf\x45\x76\xe9\xf3\xcc\x7f\x82\xf2\x2b\x15\x4a\xfc\xbf\x29\x3b\x93\x19\xf1\xb0\x58\x4d\xa6\xa4\x0c\x27\xb3\x2e\x0b\x1b\x7f\x41\x2c\x4f\x1b\x82\x48\x0e\x70\xa9\x23\x5b\x12\xec\x27\x09\x0a\x5a\x33\x17\x5a\x2b\xb2\x8d\x8a\xdc\x47\x5c\xef\xe3\x3f\x78\x03\xf8\xce\x27\x96\x72\x17\x38\x1f\x02\xe6\x7a\x3b\x4f\x84\xa7\x1f\x1c\x52\x28\xe0\xc2\xad\x97\x13\x73\xf6\xf6\x72\x62\x4f\xce\xa8\xd1\xa9\xf8\x51\x70\xfa\xd3\x0f\xa0\xbb\xd2\x50\x35\xc3\xb4\x1a\x61\x75\xd4\x67\x99\x8b\xd1\x21\x5f\x6f\x38\x66\xf5\x38\x47\xf9\xcf\x68\xef\x3e\x2f\xbb\x54\xbc\x99\x4d\xe2\x30\x2b\x82\x9c\x5e\xea\x68\xec\x44\x1f\xcb\xaf\xd7\xd1\x6a\xe4\xfe\x9f\xff\x98\xbf\x00\xe5\xbc\x2a\xd5\x4d\xd9\x1f\xf9\xfd\xa4\xdd\x77\xb6\xc7\x54\xa9\x19\x55\xd1\xfb\xaa\xd0",
+       "\xc9\x82\x65\x39\x6f\x32\x78\xfc\x53\x21\x25\xde\xd0\x97\xa6\x85\x1f\xc5\xbf\x37\xca\x32\xec\x26\xf4\x3e\x64\x87\x42\x41\x30\x9f\x56\x8a\x21\x71\x19\xba\x98\x4c\x54\x09\x9f\x88\x99\xac\x94\xb7\x90\x0a\x4d\xd9\xd3\x87\x7e\x18\x37\x1f\x5d\xaf\xd1\x92\x1f\x08",
+       190 },
+      { GCRY_MD_SHA3_512,
+       "\x58\x8e\x94\xb9\x05\x4a\xbc\x21\x89\xdf\x69\xb8\xba\x34\x34\x1b\x77\xcd\xd5\x28\xe7\x86\x0e\x5d\xef\xca\xa7\x9b\x0c\x9a\x45\x2a\xd4\xb8\x2a\xa3\x06\xbe\x84\x53\x6e\xb7\xce\xdc\xbe\x05\x8d\x7b\x84\xa6\xae\xf8\x26\xb0\x28\xb8\xa0\x27\x1b\x69\xac\x36\x05\xa9\x63\x5e\xa9\xf5\xea\x0a\xa7\x00\xf3\xeb\x78\x35\xbc\x54\x61\x1b\x92\x29\x64\x30\x0c\x95\x3e\xfe\x74\x91\xe3\x67\x7c\x2c\xeb\xe0\x82\x2e\x95\x6c\xd1\x64\x33\xb0\x2c\x68\xc4\xa2\x32\x52\xc3\xf9\xe1\x51\xa4\x16\xb4\x96\x32\x57\xb7\x83\xe0\x38\xf6\xb4\xd5\xc9\xf1\x10\xf8\x71\x65\x2c\x7a\x64\x9a\x7b\xce\xdc\xbc\xcc\x6f\x2d\x07\x25\xbb\x90\x3c\xc1\x96\xba\x76\xc7\x6a\xa9\xf1\x0a\x19\x0b\x1d\x11\x68\x99\x3b\xaa\x9f\xfc\x96\xa1\x65\x52\x16\x77\x34\x58\xbe\xc7\x2b\x0e\x39\xc9\xf2\xc1\x21\x37\x8f\xea\xb4\xe7\x6a",
+       "\xfc\x03\xbe\x19\x3a\x5e\xd0\xe6\xb3\x50\x26\x61\xc2\xd9\xe4\xe2\xa5\x03\xcf\x3f\xdb\x23\x15\x26\xa9\x0c\x3c\x4c\x26\x08\x9c\x78\x7e\xe6\xcb\xf5\x0d\x90\xaf\x61\xc1\x7c\x5d\xf0\xb2\x9c\x37\x3b\x42\x67\x40\xcd\x0d\x6f\xc3\x70\xde\x64\xeb\x21\x64\xbb\xae\xb2",
+       191 },
+      { GCRY_MD_SHA3_512,
+       "\x08\x95\x9a\x7e\x4b\xaa\xe8\x74\x92\x88\x13\x36\x40\x71\x19\x4e\x29\x39\x77\x2f\x20\xdb\x7c\x31\x57\x07\x89\x87\xc5\x57\xc2\xa6\xd5\xab\xe6\x8d\x52\x0e\xef\x3d\xc4\x91\x69\x2e\x1e\x21\xbc\xd8\x80\xad\xeb\xf6\x3b\xb4\x21\x3b\x50\x89\x7f\xa0\x05\x25\x6e\xd4\x1b\x56\x90\xf7\x8f\x52\x85\x5c\x8d\x91\x68\xa4\xb6\x66\xfc\xe2\xda\x2b\x45\x6d\x7a\x7e\x7c\x17\xab\x5f\x2f\xb1\xee\x90\xb7\x9e\x69\x87\x12\xe9\x63\x71\x59\x83\xfd\x07\x64\x1a\xe4\xb4\xe9\xdc\x73\x20\x3f\xac\x1a\xe1\x1f\xa1\xf8\xc7\x94\x1f\xcc\x82\xea\xb2\x47\xad\xdb\x56\xe2\x63\x84\x47\xe9\xd6\x09\xe6\x10\xb6\x0c\xe0\x86\x65\x6a\xae\xbf\x1d\xa3\xc8\xa2\x31\xd7\xd9\x4e\x2f\xd0\xaf\xe4\x6b\x39\x1f\xf1\x4a\x72\xea\xeb\x3f\x44\xad\x4d\xf8\x58\x66\xde\xf4\x3d\x47\x81\xa0\xb3\x57\x8b\xc9\x96\xc8\x79\x70\xb1\x32",
+       "\xfb\x9c\x3a\x91\x83\xb6\xd2\x51\xbf\x61\xfa\xf1\x84\x34\x55\xcb\x9c\x1b\xe3\x5e\xab\xdc\x13\x1d\x5b\xf3\x8e\x98\x33\x79\x34\x96\x82\x91\xe9\xd6\xdc\x10\x43\x74\xbc\x23\x4f\xf2\x2c\xc2\x3c\xd6\xf3\x38\xe7\xa3\xb0\x19\xcd\xc9\xdf\x6e\x37\x50\xb6\xb0\x1f\xde",
+       192 },
+      { GCRY_MD_SHA3_512,
+       "\xcb\x2a\x23\x4f\x45\xe2\xec\xd5\x86\x38\x95\xa4\x51\xd3\x89\xa3\x69\xaa\xb9\x9c\xfe\xf0\xd5\xc9\xff\xca\x1e\x6e\x63\xf7\x63\xb5\xc1\x4f\xb9\xb4\x78\x31\x3c\x8e\x8c\x0e\xfe\xb3\xac\x95\x00\xcf\x5f\xd9\x37\x91\xb7\x89\xe6\x7e\xac\x12\xfd\x03\x8e\x25\x47\xcc\x8e\x0f\xc9\xdb\x59\x1f\x33\xa1\xe4\x90\x7c\x64\xa9\x22\xdd\xa2\x3e\xc9\x82\x73\x10\xb3\x06\x09\x85\x54\xa4\xa7\x8f\x05\x02\x62\xdb\x5b\x54\x5b\x15\x9e\x1f\xf1\xdc\xa6\xeb\x73\x4b\x87\x23\x43\xb8\x42\xc5\x7e\xaf\xcf\xda\x84\x05\xee\xdb\xb4\x8e\xf3\x2e\x99\x69\x6d\x13\x59\x79\x23\x5c\x3a\x05\x36\x4e\x37\x1c\x2d\x76\xf1\x90\x2f\x1d\x83\x14\x6d\xf9\x49\x5c\x0a\x6c\x57\xd7\xbf\x9e\xe7\x7e\x80\xf9\x78\x7a\xee\x27\xbe\x1f\xe1\x26\xcd\xc9\xef\x89\x3a\x4a\x7d\xcb\xbc\x36\x7e\x40\xfe\x4e\x1e\xe9\x0b\x42\xea\x25\xaf\x01",
+       "\xf7\x96\x5b\x71\x19\x86\x36\xf1\x62\xd5\xa4\xe0\x8d\x73\xe8\xc8\xa9\xac\x1a\xdd\xbd\xfd\x7c\x18\x0c\x48\x9c\xca\x73\x60\xb3\xfe\xe3\xa4\x28\x61\x54\x46\x0b\xf8\x67\x92\x3b\x34\x8b\xfe\x32\xe7\x9d\x91\x39\xa0\xcb\x52\xc4\x6f\xa2\x07\x85\xfa\xea\xe0\xa8\xbc",
+       193 },
+      { GCRY_MD_SHA3_512,
+       "\xd1\x6b\xea\xdf\x02\xab\x1d\x4d\xc6\xf8\x8b\x8c\x45\x54\xc5\x1e\x86\x6d\xf8\x30\xb8\x9c\x06\xe7\x86\xa5\xf8\x75\x7e\x89\x09\x31\x0a\xf5\x1c\x84\x0e\xfe\x8d\x20\xb3\x53\x31\xf4\x35\x5d\x80\xf7\x32\x95\x97\x46\x53\xdd\xd6\x20\xcd\xde\x47\x30\xfb\x6c\x8d\x0d\x2d\xcb\x2b\x45\xd9\x2d\x4f\xbd\xb5\x67\xc0\xa3\xe8\x6b\xd1\xa8\xa7\x95\xaf\x26\xfb\xf2\x9f\xc6\xc6\x59\x41\xcd\xdb\x09\x0f\xf7\xcd\x23\x0a\xc5\x26\x8a\xb4\x60\x6f\xcc\xba\x9e\xde\xd0\xa2\xb5\xd0\x14\xee\x0c\x34\xf0\xb2\x88\x1a\xc0\x36\xe2\x4e\x15\x1b\xe8\x9e\xeb\x6c\xd9\xa7\xa7\x90\xaf\xcc\xff\x23\x4d\x7c\xb1\x1b\x99\xeb\xf5\x8c\xd0\xc5\x89\xf2\x0b\xda\xc4\xf9\xf0\xe2\x8f\x75\xe3\xe0\x4e\x5b\x3d\xeb\xce\x60\x7a\x49\x6d\x84\x8d\x67\xfa\x7b\x49\x13\x2c\x71\xb8\x78\xfd\x55\x57\xe0\x82\xa1\x8e\xca\x1f\xbd\xa9\x4d\x4b",
+       "\x53\x37\x47\x74\x87\xa0\xaf\x43\xeb\x7b\x99\x52\x93\xca\x2b\xef\x6e\xab\x24\x32\xb1\x33\x3d\xca\xea\xd7\x06\x44\x06\xe2\x28\x61\xfc\xea\x62\x3f\xd8\xb8\x5b\x30\x46\x57\x87\x35\x2a\x36\xc9\x43\x61\x0f\x14\x58\xfd\x22\xe3\xf5\x5d\xdd\x19\x5a\x6a\xca\xa3\x74",
+       194 },
+      { GCRY_MD_SHA3_512,
+       "\x8f\x65\xf6\xbc\x59\xa8\x57\x05\x01\x6e\x2b\xae\x7f\xe5\x79\x80\xde\x31\x27\xe5\xab\x27\x5f\x57\x3d\x33\x4f\x73\xf8\x60\x31\x06\xec\x35\x53\x01\x66\x08\xef\x2d\xd6\xe6\x9b\x24\xbe\x0b\x71\x13\xbf\x6a\x76\x0b\xa6\xe9\xce\x1c\x48\xf9\xe1\x86\x01\x2c\xf9\x6a\x1d\x48\x49\xd7\x5d\xf5\xbb\x83\x15\x38\x7f\xd7\x8e\x9e\x15\x3e\x76\xf8\xba\x7e\xc6\xc8\x84\x98\x10\xf5\x9f\xb4\xbb\x9b\x00\x43\x18\x21\x0b\x37\xf1\x29\x95\x26\x86\x6f\x44\x05\x9e\x01\x7e\x22\xe9\x6c\xbe\x41\x86\x99\xd0\x14\xc6\xea\x01\xc9\xf0\x03\x8b\x10\x29\x98\x84\xdb\xec\x31\x99\xbb\x05\xad\xc9\x4e\x95\x5a\x15\x33\x21\x9c\x11\x15\xfe\xd0\xe5\xf2\x12\x28\xb0\x71\xf4\x0d\xd5\x7c\x42\x40\xd9\x8d\x37\xb7\x3e\x41\x2f\xe0\xfa\x47\x03\x12\x0d\x7c\x0c\x67\x97\x2e\xd2\x33\xe5\xde\xb3\x00\xa2\x26\x05\x47\x2f\xa3\xa3\xba\x86",
+       "\x28\xab\x5c\x62\x98\xa6\x02\xae\x51\xee\xec\x40\x80\x24\x5f\x7c\xa1\x0f\x9a\x8c\x30\x4f\x22\xb5\xaa\x88\xd0\xe4\x92\x26\xc0\x1c\x2f\xd3\xcc\x5d\x8e\x99\x30\x97\x67\x81\x6e\x4f\x6d\x52\x71\x98\x76\x06\x54\x95\xdd\xb6\x1d\xd1\x13\xcf\xff\x06\xb1\x1d\x86\x04",
+       195 },
+      { GCRY_MD_SHA3_512,
+       "\x84\x89\x1e\x52\xe0\xd4\x51\x81\x32\x10\xc3\xfd\x63\x5b\x39\xa0\x3a\x6b\x7a\x73\x17\xb2\x21\xa7\xab\xc2\x70\xdf\xa9\x46\xc4\x26\x69\xaa\xcb\xbb\xdf\x80\x1e\x15\x84\xf3\x30\xe2\x8c\x72\x98\x47\xea\x14\x15\x2b\xd6\x37\xb3\xd0\xf2\xb3\x8b\x4b\xd5\xbf\x9c\x79\x1c\x58\x80\x62\x81\x10\x3a\x3e\xab\xba\xed\xe5\xe7\x11\xe5\x39\xe6\xa8\xb2\xcf\x29\x7c\xf3\x51\xc0\x78\xb4\xfa\x8f\x7f\x35\xcf\x61\xbe\xbf\x88\x14\xbf\x24\x8a\x01\xd4\x1e\x86\xc5\x71\x5e\xa4\x0c\x63\xf7\x37\x53\x79\xa7\xeb\x1d\x78\xf2\x76\x22\xfb\x46\x8a\xb7\x84\xaa\xab\xa4\xe5\x34\xa6\xdf\xd1\xdf\x6f\xa1\x55\x11\x34\x1e\x72\x5e\xd2\xe8\x7f\x98\x73\x7c\xcb\x7b\x6a\x6d\xfa\xe4\x16\x47\x74\x72\xb0\x46\xbf\x18\x11\x18\x7d\x15\x1b\xfa\x9f\x7b\x2b\xf9\xac\xdb\x23\xa3\xbe\x50\x7c\xdf\x14\xcf\xdf\x51\x7d\x2c\xb5\xfb\x9e\x4a\xb6",
+       "\x2a\xee\xac\x01\x5d\x93\x24\x5f\x6b\xf7\x27\xcd\x18\x28\x94\x09\x7b\x90\x2c\xd4\x07\xd7\xe0\xdd\x06\xda\x1a\x63\xf4\x45\x1c\x65\x7f\xf3\x9f\x92\x5e\x7c\x8a\x89\x4a\xe5\x93\xd1\x1e\xbc\x2d\x5d\x1d\xe3\xd9\xa1\x80\x18\x80\x67\x19\x27\x7d\x99\x3f\x7f\xab\xed",
+       196 },
+      { GCRY_MD_SHA3_512,
+       "\xfd\xd7\xa9\x43\x3a\x3b\x4a\xfa\xbd\x7a\x3a\x5e\x34\x57\xe5\x6d\xeb\xf7\x8e\x84\xb7\xa0\xb0\xca\x0e\x8c\x6d\x53\xbd\x0c\x2d\xae\x31\xb2\x70\x0c\x61\x28\x33\x4f\x43\x98\x1b\xe3\xb2\x13\xb1\xd7\xa1\x18\xd5\x9c\x7e\x6b\x64\x93\xa8\x6f\x86\x6a\x16\x35\xc1\x28\x59\xcf\xb9\xad\x17\x46\x0a\x77\xb4\x52\x2a\x5c\x18\x83\xc3\xd6\xac\xc8\x6e\x61\x62\x66\x7e\xc4\x14\xe9\xa1\x04\xaa\x89\x20\x53\xa2\xb1\xd7\x21\x65\xa8\x55\xba\xcd\x8f\xaf\x80\x34\xa5\xdd\x9b\x71\x6f\x47\xa0\x81\x8c\x09\xbb\x6b\xaf\x22\xaa\x50\x3c\x06\xb4\xca\x26\x1f\x55\x77\x61\x98\x9d\x2a\xfb\xd8\x8b\x6a\x67\x8a\xd1\x28\xaf\x68\x67\x21\x07\xd0\xf1\xfc\x73\xc5\xca\x74\x04\x59\x29\x7b\x32\x92\xb2\x81\xe9\x3b\xce\xb7\x61\xbd\xe7\x22\x1c\x3a\x55\x70\x8e\x5e\xc8\x44\x72\xcd\xdc\xaa\x84\xec\xf2\x37\x23\xcc\x09\x91\x35\x5c\x62\x80",
+       "\xd0\xa1\x19\x61\x7b\x7e\x30\xc2\xa8\x5e\xcb\xb3\xbb\xf3\x25\xdd\xd5\x89\x43\x1c\x8c\x2e\x2f\x9f\xc6\xe3\x24\xa6\xed\x8b\xaf\x11\x87\x0a\x80\x55\x6c\xc0\x68\x8f\xee\x4d\xb7\x0f\x22\xb9\x42\x4b\x4f\x37\xa0\xf1\xe7\xea\x31\x46\x84\xda\x31\xbf\x47\x3b\x3f\x34",
+       197 },
+      { GCRY_MD_SHA3_512,
+       "\x70\xa4\x0b\xfb\xef\x92\x27\x7a\x1a\xad\x72\xf6\xb7\x9d\x01\x77\x19\x7c\x4e\xbd\x43\x26\x68\xcf\xec\x05\xd0\x99\xac\xcb\x65\x10\x62\xb5\xdf\xf1\x56\xc0\xb2\x73\x36\x68\x7a\x94\xb2\x66\x79\xcf\xdd\x9d\xaf\x7a\xd2\x04\x33\x8d\xd9\xc4\xd1\x41\x14\x03\x3a\x5c\x22\x5b\xd1\x1f\x21\x7b\x5f\x47\x32\xda\x16\x7e\xe3\xf9\x39\x26\x2d\x40\x43\xfc\x9c\xba\x92\x30\x3b\x7b\x5e\x96\xae\xa1\x2a\xdd\xa6\x48\x59\xdf\x4b\x86\xe9\xee\x0b\x58\xe3\x90\x91\xe6\xb1\x88\xb4\x08\xac\x94\xe1\x29\x4a\x89\x11\x24\x5e\xe3\x61\xe6\x0e\x60\x1e\xff\x58\xd1\xd3\x76\x39\xf3\x75\x3b\xec\x80\xeb\xb4\xef\xde\x25\x81\x74\x36\x07\x66\x23\xfc\x65\x41\x5f\xe5\x1d\x1b\x02\x80\x36\x6d\x12\xc5\x54\xd8\x67\x43\xf3\xc3\xb6\x57\x2e\x40\x03\x61\xa6\x07\x26\x13\x14\x41\xba\x49\x3a\x83\xfb\xe9\xaf\xda\x90\xf7\xaf\x1a\xe7\x17\x23\x8d",
+       "\x1c\x88\x78\x98\x85\xdc\xcc\x9a\xe8\x10\x29\xac\xf0\xb6\xc9\xd0\x83\xcd\xb9\x77\x4c\x34\x5f\x1c\x75\x5e\x54\xc4\x5e\x9a\xf6\x3a\x70\xdc\x2a\xba\xef\xeb\x1a\xd4\x16\xf1\xbd\x3d\x9b\x69\xd4\xc4\x40\x4d\x22\xc8\x5e\x63\x6a\x47\x03\x76\x9c\x01\x12\xb5\x50\xb8",
+       198 },
+      { GCRY_MD_SHA3_512,
+       "\x74\x35\x6e\x44\x9f\x4b\xf8\x64\x4f\x77\xb1\x4f\x4d\x67\xcb\x6b\xd9\xc1\xf5\xae\x35\x76\x21\xd5\xb8\x14\x7e\x56\x2b\x65\xc6\x65\x85\xca\xf2\xe4\x91\xb4\x85\x29\xa0\x1a\x34\xd2\x26\xd4\x36\x95\x91\x53\x81\x53\x80\xd5\x68\x9e\x30\xb3\x53\x57\xcd\xac\x6e\x08\xd3\xf2\xb0\xe8\x8e\x20\x06\x00\xd6\x2b\xd9\xf5\xea\xf4\x88\xdf\x86\xa4\x47\x0e\xa2\x27\x00\x61\x82\xe4\x48\x09\x00\x98\x68\xc4\xc2\x80\xc4\x3d\x7d\x64\xa5\x26\x8f\xa7\x19\x07\x49\x60\x08\x7b\x3a\x6a\xbc\x83\x78\x82\xf8\x82\xc8\x37\x83\x45\x35\x92\x93\x89\xa1\x2b\x2c\x78\x18\x7e\x2e\xa0\x7e\xf8\xb8\xee\xf2\x7d\xc8\x50\x02\xc3\xae\x35\xf1\xa5\x0b\xee\x6a\x1c\x48\xba\x7e\x17\x5f\x33\x16\x67\x0b\x27\x98\x34\x72\xaa\x6a\x61\xee\xd0\xa6\x83\xa3\x9e\xe3\x23\x08\x06\x20\xea\x44\xa9\xf7\x44\x11\xae\x5c\xe9\x90\x30\x52\x8f\x9a\xb4\x9c\x79\xf2",
+       "\xf5\x2d\x7d\xd7\xff\x24\x8a\x1b\xca\x7b\x71\x4f\x14\xa7\x9d\xf5\x76\x6f\xd6\x7c\x00\x31\xa4\x71\xcc\x50\x9f\x35\x16\xd7\xc3\x48\xc3\x3f\x7d\x4b\x1c\xa3\x31\xb9\x32\x38\x96\xb7\x07\x4e\x10\xa8\x91\xce\xa8\x51\xf9\xac\x20\x24\x58\x12\xb8\xcf\xaa\x55\x63\x52",
+       199 },
+      { GCRY_MD_SHA3_512,
+       "\x8c\x37\x98\xe5\x1b\xc6\x84\x82\xd7\x33\x7d\x3a\xbb\x75\xdc\x9f\xfe\x86\x07\x14\xa9\xad\x73\x55\x1e\x12\x00\x59\x86\x0d\xde\x24\xab\x87\x32\x72\x22\xb6\x4c\xf7\x74\x41\x5a\x70\xf7\x24\xcd\xf2\x70\xde\x3f\xe4\x7d\xda\x07\xb6\x1c\x9e\xf2\xa3\x55\x1f\x45\xa5\x58\x48\x60\x24\x8f\xab\xde\x67\x6e\x1c\xd7\x5f\x63\x55\xaa\x3e\xae\xab\xe3\xb5\x1d\xc8\x13\xd9\xfb\x2e\xaa\x4f\x0f\x1d\x9f\x83\x4d\x7c\xad\x9c\x7c\x69\x5a\xe8\x4b\x32\x93\x85\xbc\x0b\xef\x89\x5b\x9f\x1e\xdf\x44\xa0\x3d\x4b\x41\x0c\xc2\x3a\x79\xa6\xb6\x2e\x4f\x34\x6a\x5e\x8d\xd8\x51\xc2\x85\x79\x95\xdd\xbf\x5b\x2d\x71\x7a\xeb\x84\x73\x10\xe1\xf6\xa4\x6a\xc3\xd2\x6a\x7f\x9b\x44\x98\x5a\xf6\x56\xd2\xb7\xc9\x40\x6e\x8a\x9e\x8f\x47\xdc\xb4\xef\x6b\x83\xca\xac\xf9\xae\xfb\x61\x18\xbf\xcf\xf7\xe4\x4b\xef\x69\x37\xeb\xdd\xc8\x91\x86\x83\x9b\x77",
+       "\xa8\xae\xe4\x2a\x77\xc9\xb6\x38\x7d\xc9\x73\x19\x58\x19\x59\xd9\xbd\x87\x8d\x06\x14\x87\xfd\x06\x9a\xca\x04\xd6\xf8\x4d\x34\x7e\x23\x58\x7a\x6c\x7c\x56\x32\x9b\x2d\xf8\x8c\x56\xc7\x10\x0e\xd5\x1a\xce\x5b\x5f\x77\x8d\x65\x47\x8f\x05\x9c\xaf\xd6\xc0\x98\xfd",
+       200 },
+      { GCRY_MD_SHA3_512,
+       "\xfa\x56\xbf\x73\x0c\x4f\x83\x95\x87\x51\x89\xc1\x0c\x4f\xb2\x51\x60\x57\x57\xa8\xfe\xcc\x31\xf9\x73\x7e\x3c\x25\x03\xb0\x26\x08\xe6\x73\x1e\x85\xd7\xa3\x83\x93\xc6\x7d\xe5\x16\xb8\x53\x04\x82\x4b\xfb\x13\x5e\x33\xbf\x22\xb3\xa2\x3b\x91\x3b\xf6\xac\xd2\xb7\xab\x85\x19\x8b\x81\x87\xb2\xbc\xd4\x54\xd5\xe3\x31\x8c\xac\xb3\x2f\xd6\x26\x1c\x31\xae\x7f\x6c\x54\xef\x6a\x7a\x2a\x4c\x9f\x3e\xcb\x81\xce\x35\x55\xd4\xf0\xad\x46\x6d\xd4\xc1\x08\xa9\x03\x99\xd7\x00\x41\x99\x7c\x3b\x25\x34\x5a\x96\x53\xf3\xc9\xa6\x71\x1a\xb1\xb9\x1d\x6a\x9d\x22\x16\x44\x2d\xa2\xc9\x73\xcb\xd6\x85\xee\x76\x43\xbf\xd7\x73\x27\xa2\xf7\xae\x9c\xb2\x83\x62\x0a\x08\x71\x6d\xfb\x46\x2e\x5c\x1d\x65\x43\x2c\xa9\xd5\x6a\x90\xe8\x11\x44\x3c\xd1\xec\xb8\xf0\xde\x17\x9c\x9c\xb4\x8b\xa4\xf6\xfe\xc3\x60\xc6\x6f\x25\x2f\x6e\x64\xed\xc9\x6b",
+       "\x4b\x96\x1c\x4b\xb6\x03\x5e\x7b\xdd\xa2\xe1\xa3\xb6\xf9\xcd\x52\xd1\x78\x98\x66\x04\x4c\x4a\x92\x56\x93\xbe\xa8\x8f\x65\xd0\x46\x23\x8b\xbe\xb4\xe7\xd3\xb0\x60\xe4\x72\x88\x04\x14\x07\x39\x2b\x29\x1a\xe6\x10\xba\x70\xd6\xb4\xd6\x4e\x74\xe7\xa7\xd0\x25\x6f",
+       201 },
+      { GCRY_MD_SHA3_512,
+       "\xb6\x13\x4f\x9c\x3e\x91\xdd\x80\x00\x74\x0d\x00\x9d\xd8\x06\x24\x08\x11\xd5\x1a\xb1\x54\x6a\x97\x4b\xcb\x18\xd3\x44\x64\x2b\xaa\x5c\xd5\x90\x3a\xf8\x4d\x58\xec\x5b\xa1\x73\x01\xd5\xec\x0f\x10\xcc\xd0\x50\x9c\xbb\x3f\xd3\xff\xf9\x17\x2d\x19\x3a\xf0\xf7\x82\x25\x2f\xd1\x33\x8c\x72\x44\xd4\x0e\x0e\x42\x36\x22\x75\xb2\x2d\x01\xc4\xc3\x38\x9f\x19\xdd\x69\xbd\xf9\x58\xeb\xe2\x8e\x31\xa4\xff\xe2\xb5\xf1\x8a\x87\x83\x1c\xfb\x70\x95\xf5\x8a\x87\xc9\xfa\x21\xdb\x72\xba\x26\x93\x79\xb2\xdc\x23\x84\xb3\xda\x95\x3c\x79\x25\x76\x1f\xed\x32\x46\x20\xac\xea\x43\x5e\x52\xb4\x24\xa7\x72\x3f\x6a\x23\x57\x37\x41\x57\xa3\x4c\xd8\x25\x23\x51\xc2\x5a\x1b\x23\x28\x26\xce\xfe\x1b\xd3\xe7\x0f\xfc\x15\xa3\x1e\x7c\x05\x98\x21\x9d\x7f\x00\x43\x62\x94\xd1\x18\x91\xb8\x24\x97\xbc\x78\xaa\x53\x63\x89\x2a\x24\x95\xdf\x8c\x1e\xef",
+       "\xc0\x51\x5b\x65\xb6\x40\xb3\xff\xd0\xa1\x58\x2a\x54\xf4\xc8\xfb\x35\xc1\x09\xb7\xfb\x47\x26\x66\xe0\x43\xd3\xc0\x0a\xe3\xe0\xe0\xfa\x15\x6c\x4c\xef\xb4\x6b\x5b\x7b\x4c\x0e\x48\x06\x23\xe1\xa2\x60\x18\xbd\xae\xdc\x3e\x27\xd9\xc0\xd4\x4c\x3e\x1d\x86\x20\x15",
+       202 },
+      { GCRY_MD_SHA3_512,
+       "\xc9\x41\xcd\xb9\xc2\x8a\xb0\xa7\x91\xf2\xe5\xc8\xe8\xbb\x52\x85\x06\x26\xaa\x89\x20\x5b\xec\x3a\x7e\x22\x68\x23\x13\xd1\x98\xb1\xfa\x33\xfc\x72\x95\x38\x13\x54\x85\x87\x58\xae\x6c\x8e\xc6\xfa\xc3\x24\x5c\x6e\x45\x4d\x16\xfa\x2f\x51\xc4\x16\x6f\xab\x51\xdf\x27\x28\x58\xf2\xd6\x03\x77\x0c\x40\x98\x7f\x64\x44\x2d\x48\x7a\xf4\x9c\xd5\xc3\x99\x1c\xe8\x58\xea\x2a\x60\xda\xb6\xa6\x5a\x34\x41\x49\x65\x93\x39\x73\xac\x24\x57\x08\x9e\x35\x91\x60\xb7\xcd\xed\xc4\x2f\x29\xe1\x0a\x91\x92\x17\x85\xf6\xb7\x22\x4e\xe0\xb3\x49\x39\x3c\xdc\xff\x61\x51\xb5\x0b\x37\x7d\x60\x95\x59\x92\x3d\x09\x84\xcd\xa6\x00\x08\x29\xb9\x16\xab\x68\x96\x69\x3e\xf6\xa2\x19\x9b\x3c\x22\xf7\xdc\x55\x00\xa1\x5b\x82\x58\x42\x0e\x31\x4c\x22\x2b\xc0\x00\xbc\x4e\x54\x13\xe6\xdd\x82\xc9\x93\xf8\x33\x0f\x5c\x6d\x1b\xe4\xbc\x79\xf0\x8a\x1a\x0a\x46",
+       "\x45\xc5\x84\x56\x4d\x9e\x0b\x82\x39\xcc\x12\x84\x93\x9b\xa4\x07\xa8\xe5\xe9\x81\x69\x1e\xab\x6a\x04\xd9\x35\x4c\x9c\x85\x5e\x40\x0b\x30\x37\x15\x11\x22\xce\xd2\x37\x63\x6e\x61\xa7\xff\x29\x05\xe0\x21\x3a\x6d\x07\x30\x6c\x45\x9e\x21\x89\xe3\xe6\xa9\xe0\xb8",
+       203 },
+      { GCRY_MD_SHA3_512,
+       "\x44\x99\xef\xff\xac\x4b\xce\xa5\x27\x47\xef\xd1\xe4\xf2\x0b\x73\xe4\x87\x58\xbe\x91\x5c\x88\xa1\xff\xe5\x29\x9b\x0b\x00\x58\x37\xa4\x6b\x2f\x20\xa9\xcb\x3c\x6e\x64\xa9\xe3\xc5\x64\xa2\x7c\x0f\x1c\x6a\xd1\x96\x03\x73\x03\x6e\xc5\xbf\xe1\xa8\xfc\x6a\x43\x5c\x21\x85\xed\x0f\x11\x4c\x50\xe8\xb3\xe4\xc7\xed\x96\xb0\x6a\x03\x68\x19\xc9\x46\x3e\x86\x4a\x58\xd6\x28\x6f\x78\x5e\x32\xa8\x04\x44\x3a\x56\xaf\x0b\x4d\xf6\xab\xc5\x7e\xd5\xc2\xb1\x85\xdd\xee\x84\x89\xea\x08\x0d\xee\xee\x66\xaa\x33\xc2\xe6\xda\xb3\x62\x51\xc4\x02\x68\x2b\x68\x24\x82\x1f\x99\x8c\x32\x16\x31\x64\x29\x8e\x1f\xaf\xd3\x1b\xab\xbc\xff\xb5\x94\xc9\x18\x88\xc6\x21\x90\x79\xd9\x07\xfd\xb4\x38\xed\x89\x52\x9d\x6d\x96\x21\x2f\xd5\x5a\xbe\x20\x39\x9d\xbe\xfd\x34\x22\x48\x50\x74\x36\x93\x1c\xde\xad\x49\x6e\xb6\xe4\xa8\x03\x58\xac\xc7\x86\x47\xd0\x43",
+       "\x13\x67\x23\x35\x08\x57\xe0\x37\x56\xf0\x2e\x60\x45\x1a\x28\xe7\x11\x61\x19\x27\xb8\x13\x6d\xcf\xf3\xe5\x67\xdc\x61\x8f\xf3\x6b\x31\x00\x73\x7c\x97\x81\xb9\xc8\x4a\x57\x67\x45\xc1\xe6\xbe\x03\x0d\xac\x88\x03\xa7\x14\x64\xaf\x39\xdb\x94\xd0\x02\x53\xaf\x3e",
+       204 },
+      { GCRY_MD_SHA3_512,
+       "\xee\xcb\xb8\xfd\xfa\x4d\xa6\x21\x70\xfd\x06\x72\x7f\x69\x7d\x81\xf8\x3f\x60\x1f\xf6\x1e\x47\x81\x05\xd3\xcb\x75\x02\xf2\xc8\x9b\xf3\xe8\xf5\x6e\xdd\x46\x9d\x04\x98\x07\xa3\x88\x82\xa7\xee\xfb\xc8\x5f\xc9\xa9\x50\x95\x2e\x9f\xa8\x4b\x8a\xfe\xbd\x3c\xe7\x82\xd4\xda\x59\x80\x02\x82\x7b\x1e\xb9\x88\x82\xea\x1f\x0a\x8f\x7a\xa9\xce\x01\x3a\x6e\x9b\xc4\x62\xfb\x66\xc8\xd4\xa1\x8d\xa2\x14\x01\xe1\xb9\x33\x56\xeb\x12\xf3\x72\x5b\x6d\xb1\x68\x4f\x23\x00\xa9\x8b\x9a\x11\x9e\x5d\x27\xff\x70\x4a\xff\xb6\x18\xe1\x27\x08\xe7\x7e\x6e\x5f\x34\x13\x9a\x5a\x41\x13\x1f\xd1\xd6\x33\x6c\x27\x2a\x8f\xc3\x70\x80\xf0\x41\xc7\x13\x41\xbe\xe6\xab\x55\x0c\xb4\xa2\x0a\x6d\xdb\x6a\x8e\x02\x99\xf2\xb1\x4b\xc7\x30\xc5\x4b\x8b\x1c\x1c\x48\x7b\x49\x4b\xdc\xcf\xd3\xa5\x35\x35\xab\x2f\x23\x15\x90\xbf\x2c\x40\x62\xfd\x2a\xd5\x8f\x90\x6a\x2d\x0d",
+       "\xc0\xf7\x71\x3a\xa0\x21\xa0\x45\x25\xf7\x51\x72\x2a\x9a\xe5\xc4\xc7\x93\x4d\x0a\x28\x6f\x1f\xb0\x58\x23\xd8\x6a\x96\x25\x1c\x04\xde\xcd\x96\x0d\x8d\x4d\x66\xe2\xc5\x65\xe6\x20\x7a\x49\x61\x2e\x1e\xfd\xe3\x86\x53\x68\x54\xb6\xab\x9a\x48\x07\xb0\xa1\x45\xbe",
+       205 },
+      { GCRY_MD_SHA3_512,
+       "\xe6\x4f\x3e\x4a\xce\x5c\x84\x18\xd6\x5f\xec\x2b\xc5\xd2\xa3\x03\xdd\x45\x80\x34\x73\x6e\x3b\x0d\xf7\x19\x09\x8b\xe7\xa2\x06\xde\xaf\x52\xd6\xba\x82\x31\x6c\xaf\x33\x0e\xf8\x52\x37\x51\x88\xcd\xe2\xb3\x9c\xc9\x4a\xa4\x49\x57\x8a\x7e\x2a\x8e\x3f\x5a\x9d\x68\xe8\x16\xb8\xd1\x68\x89\xfb\xc0\xeb\xf0\x93\x9d\x04\xf6\x30\x33\xae\x9a\xe2\xbd\xab\x73\xb8\x8c\x26\xd6\xbd\x25\xee\x46\x0e\xe1\xef\x58\xfb\x0a\xfa\x92\xcc\x53\x9f\x8c\x76\xd3\xd0\x97\xe7\xa6\xa6\x3e\xbb\x9b\x58\x87\xed\xf3\xcf\x07\x60\x28\xc5\xbb\xd5\xb9\xdb\x32\x11\x37\x1a\xd3\xfe\x12\x1d\x4e\x9b\xf4\x42\x29\xf4\xe1\xec\xf5\xa0\xf9\xf0\xeb\xa4\xd5\xce\xb7\x28\x78\xab\x22\xc3\xf0\xeb\x5a\x62\x53\x23\xac\x66\xf7\x06\x1f\x4a\x81\xfa\xc8\x34\x47\x1e\x0c\x59\x55\x3f\x10\x84\x75\xfe\x29\x0d\x43\xe6\xa0\x55\xae\x3e\xe4\x6f\xb6\x74\x22\xf8\x14\xa6\x8c\x4b\xe3\xe8\xc9",
+       "\xfe\x1c\xb6\x7d\x77\xfb\x46\x3f\x77\x74\x7f\xed\x29\x2a\x98\x9a\x34\x10\x44\xa8\xb6\x5f\xa1\xdf\x14\x41\xaa\x41\xa5\xc7\x95\x91\x66\x26\xe0\xe4\x79\xfd\x0b\xa7\xf9\xb1\xdc\x15\xfe\xd2\x45\xb9\x95\x98\xd3\x53\x59\x83\x4e\x8f\xd2\x5c\xf1\x96\x85\x21\x9b\xe2",
+       206 },
+      { GCRY_MD_SHA3_512,
+       "\xd2\xcb\x2d\x73\x30\x33\xf9\xe9\x13\x95\x31\x28\x08\x38\x3c\xc4\xf0\xca\x97\x4e\x87\xec\x68\x40\x0d\x52\xe9\x6b\x3f\xa6\x98\x4a\xc5\x8d\x9a\xd0\x93\x8d\xde\x5a\x97\x30\x08\xd8\x18\xc4\x96\x07\xd9\xde\x22\x84\xe7\x61\x8f\x1b\x8a\xed\x83\x72\xfb\xd5\x2e\xd5\x45\x57\xaf\x42\x20\xfa\xc0\x9d\xfa\x84\x43\x01\x16\x99\xb9\x7d\x74\x3f\x8f\x2b\x1a\xef\x35\x37\xeb\xb4\x5d\xcc\x9e\x13\xdf\xb4\x38\x42\x8e\xe1\x90\xa4\xef\xdb\x3c\xae\xb7\xf3\x93\x31\x17\xbf\x63\xab\xdc\x7e\x57\xbe\xb4\x17\x1c\x7e\x1a\xd2\x60\xab\x05\x87\x80\x6c\x4d\x13\x7b\x63\x16\xb5\x0a\xbc\x9c\xce\x0d\xff\x3a\xca\xda\x47\xbb\xb8\x6b\xe7\x77\xe6\x17\xbb\xe5\x78\xff\x45\x19\x84\x4d\xb3\x60\xe0\xa9\x6c\x67\x01\x29\x0e\x76\xbb\x95\xd2\x6f\x0f\x80\x4c\x8a\x4f\x27\x17\xea\xc4\xe7\xde\x9f\x2c\xff\x3b\xbc\x55\xa1\x7e\x77\x6c\x0d\x02\x85\x60\x32\xa6\xcd\x10\xad\x28\x38",
+       "\x40\x43\xcd\xd3\xf0\xea\x79\x3e\x49\xa8\xec\x38\x2f\x80\x71\xf6\x02\x0b\x52\x9c\xf8\xc8\x2e\x96\x94\x29\x11\x7b\x36\x21\x29\xb7\x68\x9d\x3f\x1e\xa7\xff\x77\xee\x50\x26\x3c\xec\xda\xc5\xa4\x3a\xa2\xae\xe9\x7c\xf3\xe6\x65\xcc\xf5\x35\xf6\xde\x65\xad\x01\x00",
+       207 },
+      { GCRY_MD_SHA3_512,
+       "\xf2\x99\x89\x55\x61\x3d\xd4\x14\xcc\x11\x1d\xf5\xce\x30\xa9\x95\xbb\x79\x2e\x26\x0b\x0e\x37\xa5\xb1\xd9\x42\xfe\x90\x17\x1a\x4a\xc2\xf6\x6d\x49\x28\xd7\xad\x37\x7f\x4d\x05\x54\xcb\xf4\xc5\x23\xd2\x1f\x6e\x5f\x37\x9d\x6f\x4b\x02\x8c\xdc\xb9\xb1\x75\x8d\x3b\x39\x66\x32\x42\xff\x3c\xb6\xed\xe6\xa3\x6a\x6f\x05\xdb\x3b\xc4\x1e\x0d\x86\x1b\x38\x4b\x6d\xec\x58\xbb\x09\x6d\x0a\x42\x2f\xd5\x42\xdf\x17\x5e\x1b\xe1\x57\x1f\xb5\x2a\xe6\x6f\x2d\x86\xa2\xf6\x82\x4a\x8c\xfa\xac\xba\xc4\xa7\x49\x2a\xd0\x43\x3e\xeb\x15\x45\x4a\xf8\xf3\x12\xb3\xb2\xa5\x77\x75\x0e\x3e\xfb\xd3\x70\xe8\xa8\xca\xc1\x58\x25\x81\x97\x1f\xba\x3b\xa4\xbd\x0d\x76\xe7\x18\xda\xcf\x84\x33\xd3\x3a\x59\xd2\x87\xf8\xcc\x92\x23\x4e\x7a\x27\x10\x41\xb5\x26\xe3\x89\xef\xb0\xe4\x0b\x6a\x18\xb3\xaa\xf6\x58\xe8\x2e\xd1\xc7\x86\x31\xfd\x23\xb4\xc3\xeb\x27\xc3\xfa\xec\x86\x85",
+       "\x73\x92\xbd\x44\x5f\x58\xcd\x5d\x7d\x3c\xa9\x85\x79\xcb\xaa\x9a\x94\x37\xd0\xc9\x5e\x79\x32\xb4\x00\x41\x17\xf2\x07\xf8\xaa\x39\x15\x6b\xc4\x25\x37\xb0\xc7\x90\x15\x0d\x44\x3c\x2d\x68\xc2\xc4\x3e\x36\x2d\xf9\xd0\x19\x60\x17\x97\x16\x2e\x63\x07\x69\x36\xc3",
+       208 },
+      { GCRY_MD_SHA3_512,
+       "\x44\x77\x97\xe2\x89\x9b\x72\xa3\x56\xba\x55\xbf\x4d\xf3\xac\xca\x6c\xdb\x10\x41\xeb\x47\x7b\xd1\x83\x4a\x9f\x9a\xcb\xc3\x40\xa2\x94\xd7\x29\xf2\xf9\x7d\xf3\xa6\x10\xbe\x0f\xf1\x5e\xdb\x9c\x6d\x5d\xb4\x16\x44\xb9\x87\x43\x60\x14\x0f\xc6\x4f\x52\xaa\x03\xf0\x28\x6c\x8a\x64\x06\x70\x06\x7a\x84\xe0\x17\x92\x6a\x70\x43\x8d\xb1\xbb\x36\x1d\xef\xee\x73\x17\x02\x14\x25\xf8\x82\x1d\xef\x26\xd1\xef\xd7\x7f\xc8\x53\xb8\x18\x54\x5d\x05\x5a\xdc\x92\x84\x79\x6e\x58\x3c\x76\xe6\xfe\x74\xc9\xac\x25\x87\xaa\x46\xaa\x8f\x88\x04\xf2\xfe\xb5\x83\x6c\xc4\xb3\xab\xab\xab\x84\x29\xa5\x78\x3e\x17\xd5\x99\x9f\x32\x24\x2e\xb5\x9e\xf3\x0c\xd7\xad\xab\xc1\x6d\x72\xdb\xdb\x09\x76\x23\x04\x7c\x98\x98\x9f\x88\xd1\x4e\xaf\x02\xa7\x21\x2b\xe1\x6e\xc2\xd0\x79\x81\xaa\xa9\x99\x49\xdd\xf8\x9e\xcd\x90\x33\x3a\x77\xbc\x4e\x19\x88\xa8\x2a\xbf\x7c\x7c\xaf\x32\x91",
+       "\x9f\xf0\xf0\xd7\x0c\xa0\x76\xca\x44\xc3\x53\xa3\xc6\x78\xc2\x09\x5c\x89\xf6\x19\xbb\x53\xec\x9c\xb4\x88\x8e\x2f\x14\xe5\x0f\xbc\x14\x6a\x7b\x52\x13\x56\x36\x9f\x1b\x9d\x56\x65\x83\x6e\x45\xd5\x40\x0f\x98\x56\xcc\x6d\xa3\xb3\xaf\xe6\xf3\xb0\x47\x1f\xc9\xc6",
+       209 },
+      { GCRY_MD_SHA3_512,
+       "\x9f\x2c\x18\xad\xe9\xb3\x80\xc7\x84\xe1\x70\xfb\x76\x3e\x9a\xa2\x05\xf6\x43\x03\x06\x7e\xb1\xbc\xea\x93\xdf\x5d\xac\x4b\xf5\xa2\xe0\x0b\x78\x19\x5f\x80\x8d\xf2\x4f\xc7\x6e\x26\xcb\x7b\xe3\x1d\xc3\x5f\x08\x44\xcd\xed\x15\x67\xbb\xa2\x98\x58\xcf\xfc\x97\xfb\x29\x01\x03\x31\xb0\x1d\x6a\x3f\xb3\x15\x9c\xc1\xb9\x73\xd2\x55\xda\x98\x43\xe3\x4a\x0a\x40\x61\xca\xbd\xb9\xed\x37\xf2\x41\xbf\xab\xb3\xc2\x0d\x32\x74\x3f\x40\x26\xb5\x9a\x4c\xcc\x38\x5a\x23\x01\xf8\x3c\x0b\x0a\x19\x0b\x0f\x2d\x01\xac\xb8\xf0\xd4\x11\x11\xe1\x0f\x2f\x4e\x14\x93\x79\x27\x55\x99\xa5\x2d\xc0\x89\xb3\x5f\xdd\x52\x34\xb0\xcf\xb7\xb6\xd8\xae\xbd\x56\x3c\xa1\xfa\x65\x3c\x5c\x02\x1d\xfd\x6f\x59\x20\xe6\xf1\x8b\xfa\xfd\xbe\xcb\xf0\xab\x00\x28\x13\x33\xed\x50\xb9\xa9\x99\x54\x9c\x1c\x8f\x8c\x63\xd7\x62\x6c\x48\x32\x2e\x97\x91\xd5\xff\x72\x29\x40\x49\xbd\xe9\x1e\x73\xf8",
+       "\xa9\x81\xfa\xa9\xd3\xca\xc4\x92\xb2\xfa\x07\x8d\x11\x58\xf8\x12\x48\xdf\x8d\xb3\x6a\xcb\xd5\xba\xd3\xa6\xc6\x33\xbb\xe5\x00\xeb\x48\x1d\x29\x37\xbe\xee\x9a\x76\xc8\x4e\xdc\xdf\xa0\xf9\x97\xed\xce\x70\x8f\x07\x85\x14\x22\xa7\x59\x7e\x24\x63\xfc\x19\x12\xcd",
+       210 },
+      { GCRY_MD_SHA3_512,
+       "\xae\x15\x9f\x3f\xa3\x36\x19\x00\x2a\xe6\xbc\xce\x8c\xbb\xdd\x7d\x28\xe5\xed\x9d\x61\x53\x45\x95\xc4\xc9\xf4\x3c\x40\x2a\x9b\xb3\x1f\x3b\x30\x1c\xbf\xd4\xa4\x3c\xe4\xc2\x4c\xd5\xc9\x84\x9c\xc6\x25\x9e\xca\x90\xe2\xa7\x9e\x01\xff\xba\xc0\x7b\xa0\xe1\x47\xfa\x42\x67\x6a\x1d\x66\x85\x70\xe0\x39\x63\x87\xb5\xbc\xd5\x99\xe8\xe6\x6a\xae\xd1\xb8\xa1\x91\xc5\xa4\x75\x47\xf6\x13\x73\x02\x1f\xa6\xde\xad\xcb\x55\x36\x3d\x23\x3c\x24\x44\x0f\x2c\x73\xdb\xb5\x19\xf7\xc9\xfa\x5a\x89\x62\xef\xd5\xf6\x25\x2c\x04\x07\xf1\x90\xdf\xef\xad\x70\x7f\x3c\x70\x07\xd6\x9f\xf3\x6b\x84\x89\xa5\xb6\xb7\xc5\x57\xe7\x9d\xd4\xf5\x0c\x06\x51\x1f\x59\x9f\x56\xc8\x96\xb3\x5c\x91\x7b\x63\xba\x35\xc6\xff\x80\x92\xba\xf7\xd1\x65\x8e\x77\xfc\x95\xd8\xa6\xa4\x3e\xeb\x4c\x01\xf3\x3f\x03\x87\x7f\x92\x77\x4b\xe8\x9c\x11\x14\xdd\x53\x1c\x01\x1e\x53\xa3\x4d\xc2\x48\xa2\xf0\xe6",
+       "\x89\x02\x5c\x13\xbc\x6b\x61\xa1\xbf\xad\xb1\xd3\x7d\x67\x6e\x49\xe6\x75\x4e\x9d\xfc\x00\xd5\x2c\x5e\xf1\x3b\xa5\x7c\x84\x5d\x14\xac\x75\xd5\xae\x6f\x06\x71\x40\x28\x10\x3c\x34\x24\x71\x7f\x4c\x2f\xbf\x6d\x88\xd0\x55\x69\x09\x87\x62\x0a\xc5\xb4\x40\x57\x6a",
+       211 },
+      { GCRY_MD_SHA3_512,
+       "\x3b\x8e\x97\xc5\xff\xc2\xd6\xa4\x0f\xa7\xde\x7f\xce\xfc\x90\xf3\xb1\x2c\x94\x0e\x7a\xb4\x15\x32\x1e\x29\xee\x69\x2d\xfa\xc7\x99\xb0\x09\xc9\x9d\xcd\xdb\x70\x8f\xce\x5a\x17\x8c\x5c\x35\xee\x2b\x86\x17\x14\x3e\xdc\x4c\x40\xb4\xd3\x13\x66\x1f\x49\xab\xdd\x93\xce\xa7\x9d\x11\x75\x18\x80\x54\x96\xfe\x6a\xcf\x29\x2c\x4c\x2a\x1f\x76\xb4\x03\xa9\x7d\x7c\x39\x9d\xaf\x85\xb4\x6a\xd8\x4e\x16\x24\x6c\x67\xd6\x83\x67\x57\xbd\xe3\x36\xc2\x90\xd5\xd4\x01\xe6\xc1\x38\x6a\xb3\x27\x97\xaf\x6b\xb2\x51\xe9\xb2\xd8\xfe\x75\x4c\x47\x48\x2b\x72\xe0\xb3\x94\xea\xb7\x69\x16\x12\x6f\xd6\x8e\xa7\xd6\x5e\xb9\x3d\x59\xf5\xb4\xc5\xac\x40\xf7\xc3\xb3\x7e\x7f\x36\x94\xf2\x94\x24\xc2\x4a\xf8\xc8\xf0\xef\x59\xcd\x9d\xbf\x1d\x28\xe0\xe1\x0f\x79\x9a\x6f\x78\xca\xd1\xd4\x5b\x9d\xb3\xd7\xde\xe4\xa7\x05\x9a\xbe\x99\x18\x27\x14\x98\x3b\x9c\x9d\x44\xd7\xf5\x64\x35\x96\xd4\xf3",
+       "\x15\x45\xd8\x33\x48\x36\xf7\x43\x6f\x77\xf2\x15\x32\xf5\xd3\x05\x8e\x35\x1d\xb8\x35\x7e\xfc\x1e\x08\x95\x83\xa0\xc4\x0a\xd3\xa6\xaf\x5f\x2f\xee\x79\x3d\x3f\xe1\xb4\x72\x1f\x68\x17\xa3\x73\x49\x9b\x20\x91\x2a\x35\xc4\x60\x9f\xa9\xd8\x4b\xd2\x74\xe9\x78\xfc",
+       212 },
+      { GCRY_MD_SHA3_512,
+       "\x34\x34\xec\x31\xb1\x0f\xaf\xdb\xfe\xec\x0d\xd6\xbd\x94\xe8\x0f\x7b\xa9\xdc\xa1\x9e\xf0\x75\xf7\xeb\x01\x75\x12\xaf\x66\xd6\xa4\xbc\xf7\xd1\x6b\xa0\x81\x9a\x18\x92\xa6\x37\x2f\x9b\x35\xbc\xc7\xca\x81\x55\xee\x19\xe8\x42\x8b\xc2\x2d\x21\x48\x56\xed\x5f\xa9\x37\x4c\x3c\x09\xbd\xe1\x69\x60\x2c\xc2\x19\x67\x9f\x65\xa1\x56\x6f\xc7\x31\x6f\x4c\xc3\xb6\x31\xa1\x8f\xb4\x44\x9f\xa6\xaf\xa1\x6a\x3d\xb2\xbc\x42\x12\xef\xf5\x39\xc6\x7c\xf1\x84\x68\x08\x26\x53\x55\x89\xc7\x11\x1d\x73\xbf\xfc\xe4\x31\xb4\xc4\x04\x92\xe7\x63\xd9\x27\x95\x60\xaa\xa3\x8e\xb2\xdc\x14\xa2\x12\xd7\x23\xf9\x94\xa1\xfe\x65\x6f\xf4\xdd\x14\x55\x1c\xe4\xe7\xc6\x21\xb2\xaa\x56\x04\xa1\x00\x01\xb2\x87\x8a\x89\x7a\x28\xa0\x80\x95\xc3\x25\xe1\x0a\x26\xd2\xfb\x1a\x75\xbf\xd6\x4c\x25\x03\x09\xbb\x55\xa4\x4f\x23\xbb\xac\x0d\x55\x16\xa1\xc6\x87\xd3\xb4\x1e\xf2\xfb\xbf\x9c\xc5\x6d\x47\x39",
+       "\xaf\xaf\x20\x1b\xa3\x53\x31\x6c\x1a\x7b\x81\x0f\x12\x0c\xff\x94\x1b\xb6\x58\xb0\x76\x3e\xef\x59\x43\x34\x03\xd8\x31\x3b\x8f\x00\xbf\x18\x17\x78\x98\xae\x71\x90\x7d\x3b\x52\x4e\x68\xbb\x02\x8e\xa1\x44\x28\x66\x85\x61\x11\xb1\x20\x89\xbc\xbe\xd1\x77\xfd\x46",
+       213 },
+      { GCRY_MD_SHA3_512,
+       "\x7c\x79\x53\xd8\x1c\x8d\x20\x8f\xd1\xc9\x76\x81\xd4\x8f\x49\xdd\x00\x34\x56\xde\x60\x47\x5b\x84\x07\x0e\xf4\x84\x7c\x33\x3b\x74\x57\x5b\x1f\xc8\xd2\xa1\x86\x96\x44\x85\xa3\xb8\x63\x4f\xea\xa3\x59\x5a\xaa\x1a\x2f\x45\x95\xa7\xd6\xb6\x15\x35\x63\xde\xe3\x1b\xba\xc4\x43\xc8\xa3\x3e\xed\x6d\x5d\x95\x6a\x98\x0a\x68\x36\x6c\x25\x27\xb5\x50\xee\x95\x02\x50\xdf\xb6\x91\xea\xcb\xd5\xd5\x6a\xe1\x4b\x97\x06\x68\xbe\x17\x4c\x89\xdf\x2f\xea\x43\xae\x52\xf1\x31\x42\x63\x9c\x88\x4f\xd6\x2a\x36\x83\xc0\xc3\x79\x2f\x0f\x24\xab\x13\x18\xbc\xb2\x7e\x21\xf4\x73\x7f\xab\x62\xc7\x7e\xa3\x8b\xc8\xfd\x1c\xf4\x1f\x7d\xab\x64\xc1\x3f\xeb\xe7\x15\x2b\xf5\xbb\x7a\xb5\xa7\x8f\x53\x46\xd4\x3c\xc7\x41\xcb\x6f\x72\xb7\xb8\x98\x0f\x26\x8b\x68\xbf\x62\xab\xdf\xb1\x57\x7a\x52\x43\x8f\xe1\x4b\x59\x14\x98\xcc\x95\xf0\x71\x22\x84\x60\xc7\xc5\xd5\xce\xb4\xa7\xbd\xe5\x88\xe7\xf2\x1c",
+       "\x3f\xb4\xf2\x1a\x23\x19\x73\xd2\x24\x7f\x20\x6d\x47\xb1\x9e\xe1\x55\x16\x47\xfd\x4d\x4f\x21\xfb\xcd\x6f\x65\x35\x77\xc1\xac\x69\xea\xe4\xdb\x43\x2c\x02\x34\xac\xbe\x17\xb2\xce\xd0\x23\x8a\x56\xac\xc3\x4d\x7b\xb8\x2f\xbc\x19\x09\x03\x03\x5b\x7c\x53\x88\x57",
+       214 },
+      { GCRY_MD_SHA3_512,
+       "\x7a\x6a\x4f\x4f\xdc\x59\xa1\xd2\x23\x38\x1a\xe5\xaf\x49\x8d\x74\xb7\x25\x2e\xcf\x59\xe3\x89\xe4\x91\x30\xc7\xea\xee\x62\x6e\x7b\xd9\x89\x7e\xff\xd9\x20\x17\xf4\xcc\xde\x66\xb0\x44\x04\x62\xcd\xed\xfd\x35\x2d\x81\x53\xe6\xa4\xc8\xd7\xa0\x81\x2f\x70\x1c\xc7\x37\xb5\x17\x8c\x25\x56\xf0\x71\x11\x20\x0e\xb6\x27\xdb\xc2\x99\xca\xa7\x92\xdf\xa5\x8f\x35\x93\x52\x99\xfa\x3a\x35\x19\xe9\xb0\x31\x66\xdf\xfa\x15\x91\x03\xff\xa3\x5e\x85\x77\xf7\xc0\xa8\x6c\x6b\x46\xfe\x13\xdb\x8e\x2c\xdd\x9d\xcf\xba\x85\xbd\xdd\xcc\xe0\xa7\xa8\xe1\x55\xf8\x1f\x71\x2d\x8e\x9f\xe6\x46\x15\x3d\x3d\x22\xc8\x11\xbd\x39\xf8\x30\x43\x3b\x22\x13\xdd\x46\x30\x19\x41\xb5\x92\x93\xfd\x0a\x33\xe2\xb6\x3a\xdb\xd9\x52\x39\xbc\x01\x31\x5c\x46\xfd\xb6\x78\x87\x5b\x3c\x81\xe0\x53\xa4\x0f\x58\x1c\xfb\xec\x24\xa1\x40\x4b\x16\x71\xa1\xb8\x8a\x6d\x06\x12\x02\x29\x51\x8f\xb1\x3a\x74\xca\x0a\xc5\xae",
+       "\x0b\x1c\x53\xe6\x86\x67\x31\x4b\x5f\x3f\x0f\x30\xe2\x5c\x62\x2b\x1a\x86\xd1\x07\x01\xd4\xa0\x47\x3f\xd4\x0f\x22\xc5\x0a\xcb\x47\xd6\x3e\xaf\xa5\x82\xa2\xfb\xe5\x45\x3a\x3f\x73\xbf\xbc\xa9\x23\x68\x0f\x4c\x2c\x7f\x99\xc9\x83\x88\xc0\x7d\xdd\x7a\xff\x2c\x6e",
+       215 },
+      { GCRY_MD_SHA3_512,
+       "\xd9\xfa\xa1\x4c\xeb\xe9\xb7\xde\x55\x1b\x6c\x07\x65\x40\x9a\x33\x93\x85\x62\x01\x3b\x5e\x8e\x0e\x1e\x0a\x64\x18\xdf\x73\x99\xd0\xa6\xa7\x71\xfb\x81\xc3\xca\x9b\xd3\xbb\x8e\x29\x51\xb0\xbc\x79\x25\x25\xa2\x94\xeb\xd1\x08\x36\x88\x80\x6f\xe5\xe7\xf1\xe1\x7f\xd4\xe3\xa4\x1d\x00\xc8\x9e\x8f\xcf\x4a\x36\x3c\xae\xdb\x1a\xcb\x55\x8e\x3d\x56\x2f\x13\x02\xb3\xd8\x3b\xb8\x86\xed\x27\xb7\x60\x33\x79\x81\x31\xda\xb0\x5b\x42\x17\x38\x1e\xaa\xa7\xba\x15\xec\x82\x0b\xb5\xc1\x3b\x51\x6d\xd6\x40\xea\xec\x5a\x27\xd0\x5f\xdf\xca\x0f\x35\xb3\xa5\x31\x21\x46\x80\x6b\x4c\x02\x75\xbc\xd0\xaa\xa3\xb2\x01\x7f\x34\x69\x75\xdb\x56\x6f\x9b\x4d\x13\x7f\x4e\xe1\x06\x44\xc2\xa2\xda\x66\xde\xec\xa5\x34\x2e\x23\x64\x95\xc3\xc6\x28\x05\x28\xbf\xd3\x2e\x90\xaf\x4c\xd9\xbb\x90\x8f\x34\x01\x2b\x52\xb4\xbc\x56\xd4\x8c\xc8\xa6\xb5\x9b\xab\x01\x49\x88\xea\xbd\x12\xe1\xa0\xa1\xc2\xe1\x70\xe7",
+       "\xd8\x36\xd0\xce\x3a\x28\xad\x71\xc3\xa8\x76\x79\x6b\xf6\x5a\xab\x83\x8d\x84\xe4\x80\x2e\xd4\x9a\xc0\x44\x84\xae\x06\xaa\x08\xed\x31\xde\xb5\xc3\x8c\x10\x22\xf0\xac\xee\xd4\x9c\xb5\x8e\x38\xd3\xaa\xb0\x9e\xfe\xce\xd9\x34\x9f\xdc\x33\x37\x92\x51\x25\x98\x26",
+       216 },
+      { GCRY_MD_SHA3_512,
+       "\x2d\x84\x27\x43\x3d\x0c\x61\xf2\xd9\x6c\xfe\x80\xcf\x1e\x93\x22\x65\xa1\x91\x36\x5c\x3b\x61\xaa\xa3\xd6\xdc\xc0\x39\xf6\xba\x2a\xd5\x2a\x6a\x8c\xc3\x0f\xc1\x0f\x70\x5e\x6b\x77\x05\x10\x59\x77\xfa\x49\x6c\x1c\x70\x8a\x27\x7a\x12\x43\x04\xf1\xfc\x40\x91\x1e\x74\x41\xd1\xb5\xe7\x7b\x95\x1a\xad\x7b\x01\xfd\x5d\xb1\xb3\x77\xd1\x65\xb0\x5b\xbf\x89\x80\x42\xe3\x96\x60\xca\xf8\xb2\x79\xfe\x52\x29\xd1\xa8\xdb\x86\xc0\x99\x9e\xd6\x5e\x53\xd0\x1c\xcb\xc4\xb4\x31\x73\xcc\xf9\x92\xb3\xa1\x45\x86\xf6\xba\x42\xf5\xfe\x30\xaf\xa8\xae\x40\xc5\xdf\x29\x96\x6f\x93\x46\xda\x5f\x8b\x35\xf1\x6a\x1d\xe3\xab\x6d\xe0\xf4\x77\xd8\xd8\x66\x09\x18\x06\x0e\x88\xb9\xb9\xe9\xca\x6a\x42\x07\x03\x3b\x87\xa8\x12\xdb\xf5\x54\x4d\x39\xe4\x88\x20\x10\xf8\x2b\x6c\xe0\x05\xf8\xe8\xff\x6f\xe3\xc3\x80\x6b\xc2\xb7\x3c\x2b\x83\xaf\xb7\x04\x34\x56\x29\x30\x4f\x9f\x86\x35\x87\x12\xe9\xfa\xe3\xca\x3e",
+       "\x61\xb8\xa7\x52\x0d\xab\x4d\x39\x50\x44\xb1\xa9\xcc\xc4\xf5\x26\x3e\xda\xe0\x32\x57\x67\xe3\xd2\xa0\xef\x22\x59\x33\xa8\x1f\x7e\x37\x96\x28\x08\x70\xdb\xda\xb8\x45\x7d\x58\x5c\x41\x06\x31\x5b\x53\x76\x53\xdc\x3d\x77\xe9\x15\x10\x0f\x42\x1d\xb3\x9f\x43\xb3",
+       217 },
+      { GCRY_MD_SHA3_512,
+       "\x5e\x19\xd9\x78\x87\xfc\xaa\xc0\x38\x7e\x22\xc6\xf8\x03\xc3\x4a\x3d\xac\xd2\x60\x41\x72\x43\x3f\x7a\x8a\x7a\x52\x6c\xa4\xa2\xa1\x27\x1e\xcf\xc5\xd5\xd7\xbe\x5a\xc0\xd8\x5d\x92\x10\x95\x35\x0d\xfc\x65\x99\x7d\x44\x3c\x21\xc8\x09\x4e\x0a\x3f\xef\xd2\x96\x1b\xcb\x94\xae\xd0\x32\x91\xae\x31\x0c\xcd\xa7\x5d\x8a\xce\x4b\xc7\xd8\x9e\x7d\x3e\x5d\x16\x50\xbd\xa5\xd6\x68\xb8\xb5\x0b\xfc\x8e\x60\x8e\x18\x4f\x4d\x3a\x9a\x2b\xad\xc4\xff\x5f\x07\xe0\xc0\xbc\x8a\x9f\x2e\x0b\x2a\x26\xfd\x6d\x8c\x55\x00\x08\xfa\xaa\xb7\x5f\xd7\x1a\xf2\xa4\x24\xbe\xc9\xa7\xcd\x9d\x83\xfa\xd4\xc8\xe9\x31\x91\x15\x65\x6a\x87\x17\xd3\xb5\x23\xa6\x8f\xf8\x00\x42\x58\xb9\x99\x0e\xd3\x62\x30\x84\x61\x80\x4b\xa3\xe3\xa7\xe9\x2d\x8f\x2f\xfa\xe5\xc2\xfb\xa5\x5b\xa5\xa3\xc2\x7c\x0a\x2f\x71\xbd\x71\x1d\x2f\xe1\x79\x9c\x2a\xdb\x31\xb2\x00\x03\x54\x81\xe9\xee\x5c\x4a\xdf\x2a\xb9\xc0\xfa\x50\xb2\x39\x75\xcf",
+       "\xb8\x47\xb2\x92\x81\x8e\x80\x0b\xaa\x41\x5c\x25\x21\xa8\x15\x8a\x6a\xb7\x49\x93\x4d\xb6\x93\xd0\xd2\xe4\x61\x3c\xda\xe6\x0b\xd5\x60\x75\xcf\x2c\x29\xf5\x87\xdc\x35\x30\x16\x41\x90\xbc\x2c\x02\xd9\x7c\xa3\x23\x47\xfa\x2a\xa4\x31\xe5\x11\xbb\x7d\x1c\x87\xe8",
+       218 },
+      { GCRY_MD_SHA3_512,
+       "\xc8\xe9\x76\xab\x46\x38\x90\x93\x87\xce\x3b\x8d\x4e\x51\x0c\x32\x30\xe5\x69\x0e\x02\xc4\x50\x93\xb1\xd2\x97\x91\x0a\xbc\x48\x1e\x56\xee\xa0\xf2\x96\xf9\x83\x79\xdf\xc9\x08\x0a\xf6\x9e\x73\xb2\x39\x9d\x1c\x14\x3b\xee\x80\xae\x13\x28\x16\x2c\xe1\xba\x7f\x6a\x83\x74\x67\x9b\x20\xaa\xcd\x38\x0e\xb4\xe6\x13\x82\xc9\x99\x98\x70\x4d\x62\x70\x1a\xfa\x91\x4f\x9a\x27\x05\xcd\xb0\x65\x88\x5f\x50\xd0\x86\xc3\xeb\x57\x53\x70\x0c\x38\x71\x18\xbb\x14\x2f\x3e\x6d\xa1\xe9\x88\xdf\xb3\x1a\xc7\x5d\x73\x68\x93\x1e\x45\xd1\x39\x1a\x27\x4b\x22\xf8\x3c\xeb\x07\x2f\x9b\xca\xbc\x0b\x21\x66\x85\xbf\xd7\x89\xf5\x02\x39\x71\x02\x4b\x18\x78\xa2\x05\x44\x25\x22\xf9\xea\x7d\x87\x97\xa4\x10\x2a\x3d\xf4\x17\x03\x76\x82\x51\xfd\x5e\x01\x7c\x85\xd1\x20\x0a\x46\x41\x18\xaa\x35\x65\x4e\x7c\xa3\x9f\x3c\x37\x5b\x8e\xf8\xcb\xe7\x53\x4d\xbc\x64\xbc\x20\xbe\xfb\x41\x7c\xf6\x0e\xc9\x2f\x63\xd9\xee\x73\x97",
+       "\x95\xed\x6d\x85\x67\x77\x4e\x66\x40\x4f\xc3\x2b\x7a\x01\xe1\xc6\x25\xfc\x83\x22\xab\x9b\xe0\xcd\x7c\x93\x67\x31\x63\x8b\x04\xc0\x97\x48\x97\x3d\x95\x66\x5a\x35\xb2\x18\xd1\x53\x14\x11\xf3\xaa\x5e\x5c\x47\xe6\x5d\x85\x7a\x43\x78\x3e\x2b\xd3\xc9\xd2\x90\x05",
+       219 },
+      { GCRY_MD_SHA3_512,
+       "\x71\x45\xfa\x12\x4b\x74\x29\xa1\xfc\x22\x31\x23\x7a\x94\x9b\xa7\x20\x1b\xcc\x18\x22\xd3\x27\x2d\xe0\x05\xb6\x82\x39\x81\x96\xc2\x5f\x7e\x5c\xc2\xf2\x89\xfb\xf4\x44\x15\xf6\x99\xcb\x7f\xe6\x75\x77\x91\xb1\x44\x34\x10\x23\x4a\xe0\x61\xed\xf6\x23\x35\x9e\x2b\x4e\x32\xc1\x9b\xf8\x84\x50\x43\x2d\xd0\x1c\xaa\x5e\xb1\x6a\x1d\xc3\x78\xf3\x91\xca\x5e\x3c\x4e\x5f\x35\x67\x28\xbd\xdd\x49\x75\xdb\x7c\x89\x0d\xa8\xbb\xc8\x4c\xc7\x3f\xf2\x44\x39\x4d\x0d\x48\x95\x49\x78\x76\x5e\x4a\x00\xb5\x93\xf7\x0f\x2c\xa0\x82\x67\x3a\x26\x1e\xd8\x8d\xbc\xef\x11\x27\x72\x8d\x8c\xd8\x9b\xc2\xc5\x97\xe9\x10\x2c\xed\x60\x10\xf6\x5f\xa7\x5a\x14\xeb\xe4\x67\xfa\x57\xce\x3b\xd4\x94\x8b\x68\x67\xd7\x4a\x9d\xf5\xc0\xec\x6f\x53\x0c\xbf\x2e\xe6\x1c\xe6\xf0\x6b\xc8\xf2\x86\x4d\xff\x55\x83\x77\x6b\x31\xdf\x8c\x7f\xfc\xb6\x14\x28\xa5\x6b\xf7\xbd\x37\x18\x8b\x4a\x51\x23\xbb\xf3\x38\x39\x3a\xf4\x6e\xda\x85\xe6",
+       "\x98\x35\x07\x93\xfc\x15\x40\xae\x72\x75\x7c\x2d\x1b\xa0\xfa\x34\xdf\x19\x23\xc9\x87\xf3\x65\x75\x27\x88\xe3\xc6\x59\x31\x74\x6c\x36\xd1\x3f\xd2\x93\xdb\x8e\xa1\xb6\x37\x48\x72\xcc\xf7\x4e\x9b\x0c\xff\x67\xc6\xde\xbb\x42\x63\x39\x0c\xd9\x6e\x2b\xdd\x86\x4f",
+       220 },
+      { GCRY_MD_SHA3_512,
+       "\x7f\xdf\xad\xcc\x9d\x29\xba\xd2\x3a\xe0\x38\xc6\xc6\x5c\xda\x1a\xef\x75\x72\x21\xb8\x87\x2e\xd3\xd7\x5f\xf8\xdf\x7d\xa0\x62\x7d\x26\x6e\x22\x4e\x81\x2c\x39\xf7\x98\x3e\x45\x58\xbf\xd0\xa1\xf2\xbe\xf3\xfe\xb5\x6b\xa0\x91\x20\xef\x76\x29\x17\xb9\xc0\x93\x86\x79\x48\x54\x7a\xee\x98\x60\x0d\x10\xd8\x7b\x20\x10\x68\x78\xa8\xd2\x2c\x64\x37\x8b\xf6\x34\xf7\xf7\x59\x00\xc0\x39\x86\xb0\x77\xb0\xbf\x8b\x74\x0a\x82\x44\x7b\x61\xb9\x9f\xee\x53\x76\xc5\xeb\x66\x80\xec\x9e\x30\x88\xf0\xbd\xd0\xc5\x68\x83\x41\x3d\x60\xc1\x35\x7d\x3c\x81\x19\x50\xe5\x89\x0e\x76\x00\x10\x3c\x91\x63\x41\xb8\x0c\x74\x3c\x6a\x85\x2b\x7b\x4f\xb6\x0c\x3b\xa2\x1f\x3b\xc1\x5b\x83\x82\x43\x7a\x68\x45\x47\x79\xcf\x3c\xd7\xf9\xf9\x0c\xcc\x8e\xf2\x8d\x0b\x70\x65\x35\xb1\xe4\x10\x8e\xb5\x62\x7b\xb4\x5d\x71\x9c\xb0\x46\x83\x9a\xee\x31\x1c\xa1\xab\xdc\x83\x19\xe0\x50\xd6\x79\x72\xcb\x35\xa6\xb1\x60\x1b\x25\xdb\xf4\x87",
+       "\xc2\x49\x3d\x60\xe1\xef\xa6\xb4\x72\x93\x3e\xde\x64\xd1\xf4\x9e\xff\x77\x36\x35\xf6\x6c\x64\x54\xe5\x7e\x47\x93\x5a\x0f\x4c\x5b\x94\x54\x8d\xa5\xc3\x69\xbd\xac\x71\x46\xe5\x4f\x01\x7c\x3f\xd6\x74\xce\x32\xf8\xd9\x51\x51\xc7\xcb\xc3\xe3\xbb\xa3\xeb\xe0\xd3",
+       221 },
+      { GCRY_MD_SHA3_512,
+       "\x98\x86\x38\x21\x9f\xd3\x09\x54\x21\xf8\x26\xf5\x6e\x4f\x09\xe3\x56\x29\x6b\x62\x8c\x3c\xe6\x93\x0c\x9f\x2e\x75\x8f\xd1\xa8\x0c\x82\x73\xf2\xf6\x1e\x4d\xaa\xe6\x5c\x4f\x11\x0d\x3e\x7c\xa0\x96\x5a\xc7\xd2\x4e\x34\xc0\xdc\x4b\xa2\xd6\xff\x0b\xf5\xbb\xe9\x3b\x35\x85\xf3\x54\xd7\x54\x3c\xb5\x42\xa1\xaa\x54\x67\x4d\x37\x50\x77\xf2\xd3\x60\xa8\xf4\xd4\x2f\x3d\xb1\x31\xc3\xb7\xab\x73\x06\x26\x7b\xa1\x07\x65\x98\x64\xa9\x0c\x8c\x90\x94\x60\xa7\x36\x21\xd1\xf5\xd9\xd3\xfd\x95\xbe\xb1\x9b\x23\xdb\x1c\xb6\xc0\xd0\xfb\xa9\x1d\x36\x89\x15\x29\xb8\xbd\x82\x63\xca\xa1\xba\xb5\x6a\x4a\xff\xae\xd4\x49\x62\xdf\x09\x6d\x8d\x5b\x1e\xb8\x45\xef\x31\x18\x8b\x3e\x10\xf1\xaf\x81\x1a\x13\xf1\x56\xbe\xb7\xa2\x88\xaa\xe5\x93\xeb\xd1\x47\x1b\x62\x4a\xa1\xa7\xc6\xad\xf0\x1e\x22\x00\xb3\xd7\x2d\x88\xa3\xae\xd3\x10\x0c\x88\x23\x1e\x41\xef\xc3\x76\x90\x6f\x0b\x58\x0d\xc8\x95\xf0\x80\xfd\xa5\x74\x1d\xb1\xcb",
+       "\x70\xd7\xba\x65\x85\xcd\x2e\xf9\x1b\xb2\x61\x02\x5f\x9d\xcc\x80\xf8\x35\x9c\x9d\xc3\x0c\x7c\x29\x61\xf0\xd1\xf6\x05\x7b\x9c\x44\xe3\xaa\x67\xa4\xbc\x00\xf1\x37\x88\x6e\x3c\xf1\x31\x6d\x75\xf8\xeb\xf6\x51\xc7\x9d\xf9\xa9\x9c\xab\xd0\x38\x30\x08\x37\x20\x16",
+       222 },
+      { GCRY_MD_SHA3_512,
+       "\x5a\xab\x62\x75\x6d\x30\x7a\x66\x9d\x14\x6a\xba\x98\x8d\x90\x74\xc5\xa1\x59\xb3\xde\x85\x15\x1a\x81\x9b\x11\x7c\xa1\xff\x65\x97\xf6\x15\x6e\x80\xfd\xd2\x8c\x9c\x31\x76\x83\x51\x64\xd3\x7d\xa7\xda\x11\xd9\x4e\x09\xad\xd7\x70\xb6\x8a\x6e\x08\x1c\xd2\x2c\xa0\xc0\x04\xbf\xe7\xcd\x28\x3b\xf4\x3a\x58\x8d\xa9\x1f\x50\x9b\x27\xa6\x58\x4c\x47\x4a\x4a\x2f\x3e\xe0\xf1\xf5\x64\x47\x37\x92\x40\xa5\xab\x1f\xb7\x7f\xdc\xa4\x9b\x30\x5f\x07\xba\x86\xb6\x27\x56\xfb\x9e\xfb\x4f\xc2\x25\xc8\x68\x45\xf0\x26\xea\x54\x20\x76\xb9\x1a\x0b\xc2\xcd\xd1\x36\xe1\x22\xc6\x59\xbe\x25\x9d\x98\xe5\x84\x1d\xf4\xc2\xf6\x03\x30\xd4\xd8\xcd\xee\x7b\xf1\xa0\xa2\x44\x52\x4e\xec\xc6\x8f\xf2\xae\xf5\xbf\x00\x69\xc9\xe8\x7a\x11\xc6\xe5\x19\xde\x1a\x40\x62\xa1\x0c\x83\x83\x73\x88\xf7\xef\x58\x59\x8a\x38\x46\xf4\x9d\x49\x96\x82\xb6\x83\xc4\xa0\x62\xb4\x21\x59\x4f\xaf\xbc\x13\x83\xc9\x43\xba\x83\xbd\xef\x51\x5e\xfc\xf1\x0d",
+       "\xb5\x0d\x0d\xa9\xb3\xdb\x15\x45\xcc\x1d\x2f\x35\x46\x5c\x74\xd0\x75\x43\xb3\x56\x42\x49\xf1\x2c\x54\x6a\x08\x79\x7e\xea\x73\x32\x6c\xe6\x24\x20\x3a\x3d\x25\xc9\x2c\xe6\x36\xbc\xce\x86\xda\x9c\xb9\xf3\x9b\xc7\x55\xec\x0f\x39\xc0\x90\xa0\xe8\xa7\x2d\xa7\x0b",
+       223 },
+      { GCRY_MD_SHA3_512,
+       "\x47\xb8\x21\x6a\xa0\xfb\xb5\xd6\x79\x66\xf2\xe8\x2c\x17\xc0\x7a\xa2\xd6\x32\x7e\x96\xfc\xd8\x3e\x3d\xe7\x33\x36\x89\xf3\xee\x79\x99\x4a\x1b\xf4\x50\x82\xc4\xd7\x25\xed\x8d\x41\x20\x5c\xb5\xbc\xdf\x5c\x34\x1f\x77\xfa\xcb\x1d\xa4\x6a\x5b\x9b\x2c\xbc\x49\xea\xdf\x78\x6b\xcd\x88\x1f\x37\x1a\x95\xfa\x17\xdf\x73\xf6\x06\x51\x9a\xea\x0f\xf7\x9d\x5a\x11\x42\x7b\x98\xee\x7f\x13\xa5\xc0\x06\x37\xe2\x85\x41\x34\x69\x10\x59\x83\x91\x21\xfe\xa9\xab\xe2\xcd\x1b\xcb\xbb\xf2\x7c\x74\xca\xf3\x67\x8e\x05\xbf\xb1\xc9\x49\x89\x7e\xa0\x1f\x56\xff\xa4\xda\xfb\xe8\x64\x46\x11\x68\x5c\x61\x7a\x32\x06\xc7\xa7\x03\x6e\x4a\xc8\x16\x79\x9f\x69\x3d\xaf\xe7\xf1\x9f\x30\x3c\xe4\xeb\xa0\x9d\x21\xe0\x36\x10\x20\x1b\xfc\x66\x5b\x72\x40\x0a\x54\x7a\x1e\x00\xfa\x9b\x7a\xd8\xd8\x4f\x84\xb3\x4a\xef\x11\x85\x15\xe7\x4d\xef\x11\xb9\x18\x8b\xd1\xe1\xf9\x7d\x9a\x12\xc3\x01\x32\xec\x28\x06\x33\x9b\xda\xda\xcd\xa2\xfd\x8b\x78",
+       "\x83\x75\x2a\x88\xc9\x15\xd4\x19\x32\x96\x72\x5d\xec\xc5\x0c\x9c\x05\xd2\x5d\x6b\xbd\x9a\xf2\xe0\xef\x06\x28\x6e\xcf\xee\x96\x1d\xe9\x59\xbe\xdb\xb1\x30\x70\x4d\x43\x2c\x2b\xc8\x99\x30\x20\x8f\x45\x0e\x0a\x02\x26\x61\x72\x40\x43\xd2\x68\xcb\x24\xe7\xfc\x47",
+       224 },
+      { GCRY_MD_SHA3_512,
+       "\x8c\xff\x1f\x67\xfe\x53\xc0\x98\x89\x6d\x91\x36\x38\x9b\xd8\x88\x18\x16\xcc\xab\x34\x86\x2b\xb6\x7a\x65\x6e\x3d\x98\x89\x6f\x3c\xe6\xff\xd4\xda\x73\x97\x58\x09\xfc\xdf\x96\x66\x76\x0d\x6e\x56\x1c\x55\x23\x8b\x20\x5d\x80\x49\xc1\xce\xde\xef\x37\x4d\x17\x35\xda\xa5\x33\x14\x7b\xfa\x96\x0b\x2c\xce\x4a\x4f\x25\x41\x76\xbb\x4d\x1b\xd1\xe8\x96\x54\x43\x2b\x8d\xbe\x1a\x13\x5c\x42\x11\x5b\x39\x4b\x02\x48\x56\xa2\xa8\x3d\xc8\x5d\x67\x82\xbe\x4b\x44\x42\x39\x56\x7c\xce\xc4\xb1\x84\xd4\x54\x8e\xae\x3f\xf6\xa1\x92\xf3\x43\x29\x2b\xa2\xe3\x2a\x0f\x26\x7f\x31\xcc\x26\x71\x9e\xb8\x52\x45\xd4\x15\xfb\x89\x7a\xc2\xda\x43\x3e\xe9\x1a\x99\x42\x4c\x9d\x7f\x17\x66\xa4\x41\x71\xd1\x65\x10\x01\xc3\x8f\xc7\x92\x94\xac\xcc\x68\xce\xb5\x66\x5d\x36\x21\x84\x54\xd3\xba\x16\x9a\xe0\x58\xa8\x31\x33\x8c\x17\x74\x36\x03\xf8\x1e\xe1\x73\xbf\xc0\x92\x74\x64\xf9\xbd\x72\x8d\xee\x94\xc6\xae\xab\x7a\xae\x6e\xe3\xa6\x27\xe8",
+       "\x72\x88\x42\x4b\xa8\x55\xa7\x6c\x74\x80\xb6\x06\xf8\xf3\x2e\x94\x39\x67\x99\xba\xb8\xbb\x3f\xc8\xfd\x21\xd1\x80\x96\x6c\x64\x97\x10\x71\xe2\x64\x56\x22\x52\x4e\xc7\xd1\x64\x5e\xea\x7b\x7c\x1f\xa2\x1f\x7f\x5b\x6b\x90\xf3\xe5\xbe\xb9\x92\x22\xf0\x5e\xa9\x05",
+       225 },
+      { GCRY_MD_SHA3_512,
+       "\xea\xcd\x07\x97\x1c\xff\x9b\x99\x39\x90\x3f\x8c\x1d\x8c\xbb\x5d\x4d\xb1\xb5\x48\xa8\x5d\x04\xe0\x37\x51\x4a\x58\x36\x04\xe7\x87\xf3\x29\x92\xbf\x21\x11\xb9\x7a\xc5\xe8\xa9\x38\x23\x35\x52\x73\x13\x21\x52\x2a\xb5\xe8\x58\x35\x61\x26\x0b\x7d\x13\xeb\xee\xf7\x85\xb2\x3a\x41\xfd\x85\x76\xa6\xda\x76\x4a\x8e\xd6\xd8\x22\xd4\x95\x7a\x54\x5d\x52\x44\x75\x6c\x18\xaa\x80\xe1\xaa\xd4\xd1\xf9\xc2\x0d\x25\x9d\xee\x17\x11\xe2\xcc\x8f\xd0\x13\x16\x9f\xb7\xcc\x4c\xe3\x8b\x36\x2f\x8e\x09\x36\xae\x91\x98\xb7\xe8\x38\xdc\xea\x4f\x7a\x5b\x94\x29\xbb\x3f\x6b\xbc\xf2\xdc\x92\x56\x5e\x36\x76\xc1\xc5\xe6\xeb\x3d\xd2\xa0\xf8\x6a\xa2\x3e\xdd\x3d\x08\x91\xf1\x97\x44\x76\x92\x79\x4b\x3d\xfa\x26\x96\x11\xad\x97\xf7\x2b\x79\x56\x02\xb4\xfd\xb1\x98\xf3\xfd\x3e\xb4\x1b\x41\x50\x64\x25\x6e\x34\x5e\x8d\x8c\x51\xc5\x55\xdc\x8a\x21\x90\x4a\x9b\x0f\x1a\xd0\xef\xfa\xb7\x78\x6a\xac\x2d\xa3\xb1\x96\x50\x7e\x9f\x33\xca\x35\x64\x27",
+       "\xe9\x39\x93\x76\xd8\x9c\x4d\xd4\x46\x4e\x45\x82\x5f\x43\x02\xcd\xcc\xd4\xc4\x1d\xb4\xe8\x95\x1b\xe1\x7b\xcc\x64\x51\x85\x83\x32\x39\x8b\x7e\x4e\x7f\x5e\xee\x68\x30\xc7\x15\x45\x1e\x4a\xac\xdb\x17\x9d\xd5\x24\x7b\xa6\xd5\x72\x8c\xbd\x40\x60\xae\xb7\x7c\xb9",
+       226 },
+      { GCRY_MD_SHA3_512,
+       "\x23\xac\x4e\x9a\x42\xc6\xef\x45\xc3\x33\x6c\xe6\xdf\xc2\xff\x7d\xe8\x88\x4c\xd2\x3d\xc9\x12\xfe\xf0\xf7\x75\x6c\x09\xd3\x35\xc1\x89\xf3\xad\x3a\x23\x69\x7a\xbd\xa8\x51\xa8\x18\x81\xa0\xc8\xcc\xaf\xc9\x80\xab\x2c\x70\x25\x64\xc2\xbe\x15\xfe\x4c\x4b\x9f\x10\xdf\xb2\x24\x8d\x0d\x0c\xb2\xe2\x88\x7f\xd4\x59\x8a\x1d\x4a\xcd\xa8\x97\x94\x4a\x2f\xfc\x58\x0f\xf9\x27\x19\xc9\x5c\xf2\xaa\x42\xdc\x58\x46\x74\xcb\x5a\x9b\xc5\x76\x5b\x9d\x6d\xdf\x57\x89\x79\x1d\x15\xf8\xdd\x92\x5a\xa1\x2b\xff\xaf\xbc\xe6\x08\x27\xb4\x90\xbb\x7d\xf3\xdd\xa6\xf2\xa1\x43\xc8\xbf\x96\xab\xc9\x03\xd8\x3d\x59\xa7\x91\xe2\xd6\x28\x14\xa8\x9b\x80\x80\xa2\x80\x60\x56\x8c\xf2\x4a\x80\xae\x61\x17\x9f\xe8\x4e\x0f\xfa\xd0\x03\x88\x17\x8c\xb6\xa6\x17\xd3\x7e\xfd\x54\xcc\x01\x97\x0a\x4a\x41\xd1\xa8\xd3\xdd\xce\x46\xed\xbb\xa4\xab\x7c\x90\xad\x56\x53\x98\xd3\x76\xf4\x31\x18\x9c\xe8\xc1\xc3\x3e\x13\x2f\xea\xe6\xa8\xcd\x17\xa6\x1c\x63\x00\x12",
+       "\xcc\xea\x44\x7e\xfe\x6f\x8b\x06\xac\x42\x07\x62\x80\x37\x76\x35\xf5\xfd\x07\x67\xf4\xaf\x8b\x24\x5f\xe6\x3b\x79\xfe\x49\x74\xe9\x15\x67\x44\xe6\x0e\x98\xd1\x20\x18\x21\x4c\x39\xf8\xa8\x26\xd5\x06\xd0\xd5\x94\x86\x45\xe9\xf8\x83\xc2\x08\xd3\x7d\x92\x7a\x41",
+       227 },
+      { GCRY_MD_SHA3_512,
+       "\x01\x72\xdf\x73\x22\x82\xc9\xd4\x88\x66\x9c\x35\x8e\x34\x92\x26\x0c\xbe\x91\xc9\x5c\xfb\xc1\xe3\xfe\xa6\xc4\xb0\xec\x12\x9b\x45\xf2\x42\xac\xe0\x9f\x15\x2f\xc6\x23\x4e\x1b\xee\x8a\xab\x8c\xd5\x6e\x8b\x48\x6e\x1d\xcb\xa9\xc0\x54\x07\xc2\xf9\x5d\xa8\xd8\xf1\xc0\xaf\x78\xee\x2e\xd8\x2a\x3a\x79\xec\x0c\xb0\x70\x93\x96\xee\x62\xaa\xdb\x84\xf8\xa4\xee\x8a\x7c\xcc\xa3\xc1\xee\x84\xe3\x02\xa0\x9e\xa8\x02\x20\x4a\xfe\xcf\x04\x09\x7e\x67\xd0\xf8\xe8\xa9\xd2\x65\x11\x26\xc0\xa5\x98\xa3\x70\x81\xe4\x2d\x16\x8b\x0a\xe8\xa7\x19\x51\xc5\x24\x25\x9e\x4e\x20\x54\xe5\x35\xb7\x79\x67\x9b\xda\xde\x56\x6f\xe5\x57\x00\x85\x86\x18\xe6\x26\xb4\xa0\xfa\xf8\x95\xbc\xce\x90\x11\x50\x4a\x49\xe0\x5f\xd5\x61\x27\xea\xe3\xd1\xf8\x91\x7a\xfb\x54\x8e\xca\xda\xbd\xa1\x02\x01\x11\xfe\xc9\x31\x4c\x41\x34\x98\xa3\x60\xb0\x86\x40\x54\x9a\x22\xcb\x23\xc7\x31\xac\xe7\x43\x25\x2a\x82\x27\xa0\xd2\x68\x9d\x4c\x60\x01\x60\x66\x78\xdf\xb9\x21",
+       "\x7e\x03\xfc\xe3\xb6\x7e\xbb\x28\x30\x88\x23\xf5\x6a\xa9\x3d\xbb\x4d\x9e\xfd\xbd\x93\x30\x0d\x97\xb1\xf9\x9e\xfc\xb8\x2c\x36\x84\xc5\xa5\xa5\xaa\x64\xe7\xa3\x4c\x69\xb8\x93\x99\xca\xb0\x5f\x22\xe8\xe8\x86\x07\xb8\x63\x33\x6e\x4c\xbf\x8c\xf6\xe7\x4b\x98\xc1",
+       228 },
+      { GCRY_MD_SHA3_512,
+       "\x38\x75\xb9\x24\x0c\xf3\xe0\xa8\xb5\x9c\x65\x85\x40\xf2\x6a\x70\x1c\xf1\x88\x49\x6e\x2c\x21\x74\x78\x8b\x12\x6f\xd2\x94\x02\xd6\xa7\x54\x53\xba\x06\x35\x28\x4d\x08\x83\x5f\x40\x05\x1a\x2a\x96\x83\xdc\x92\xaf\xb9\x38\x37\x19\x19\x12\x31\x17\x03\x79\xba\x6f\x4a\xdc\x81\x6f\xec\xbb\x0f\x9c\x44\x6b\x78\x5b\xf5\x20\x79\x68\x41\xe5\x88\x78\xb7\x3c\x58\xd3\xeb\xb0\x97\xce\x47\x61\xfd\xea\xbe\x15\xde\x2f\x31\x9d\xfb\xaf\x17\x42\xcd\xeb\x38\x95\x59\xc7\x88\x13\x1a\x67\x93\xe1\x93\x85\x66\x61\x37\x6c\x81\xce\x95\x68\xda\x19\xaa\x69\x25\xb4\x7f\xfd\x77\xa4\x3c\x7a\x0e\x75\x8c\x37\xd6\x92\x54\x90\x9f\xf0\xfb\xd4\x15\xef\x8e\xb9\x37\xbc\xd4\x9f\x91\x46\x8b\x49\x97\x4c\x07\xdc\x81\x9a\xbd\x67\x39\x5d\xb0\xe0\x58\x74\xff\x83\xdd\xda\xb8\x95\x34\x4a\xbd\x0e\x71\x11\xb2\xdf\x9e\x58\xd7\x6d\x85\xad\x98\x10\x6b\x36\x29\x58\x26\xbe\x04\xd4\x35\x61\x55\x95\x60\x5e\x4b\x4b\xb8\x24\xb3\x3c\x4a\xfe\xb5\xe7\xbb\x0d\x19\xf9\x09",
+       "\x6a\x45\x7a\xe7\x4f\x89\xc4\x2b\xbd\x2b\xd2\xeb\xff\xfb\xd7\x1f\x03\x6f\xf7\xb7\x6c\x4a\xfd\xdf\xfb\xd5\x2f\x32\xe5\x88\xa9\x54\x3c\xed\x09\xda\x9a\x3e\x13\x0a\xc1\xa1\x9e\xf1\xac\xb2\xfa\x68\xac\x41\x91\x7e\xd6\xba\xd3\x7a\x60\x98\x2b\x16\xb5\xeb\x4f\xf3",
+       229 },
+      { GCRY_MD_SHA3_512,
+       "\x74\x7c\xc1\xa5\x9f\xef\xba\x94\xa9\xc7\x5b\xa8\x66\xc3\x0d\xc5\xc1\xcb\x0c\x0f\x8e\x93\x61\xd9\x84\x84\x95\x6d\xd5\xd1\xa4\x0f\x61\x84\xaf\xbe\x3d\xac\x9f\x76\x02\x8d\x1c\xae\xcc\xfb\xf6\x91\x99\xc6\xce\x2b\x4c\x09\x2a\x3f\x4d\x2a\x56\xfe\x5a\x33\xa0\x07\x57\xf4\xd7\xde\xe5\xdf\xb0\x52\x43\x11\xa9\x7a\xe0\x66\x8a\x47\x97\x1b\x95\x76\x6e\x2f\x6d\xd4\x8c\x3f\x57\x84\x1f\x91\xf0\x4a\x00\xad\x5e\xa7\x0f\x2d\x47\x9a\x26\x20\xdc\x5c\xd7\x8e\xaa\xb3\xa3\xb0\x11\x71\x9b\x7e\x78\xd1\x9d\xdf\x70\xd9\x42\x37\x98\xaf\x77\x51\x7e\xbc\x55\x39\x2f\xcd\x01\xfc\x60\x0d\x8d\x46\x6b\x9e\x7a\x7a\x85\xbf\x33\xf9\xcc\x54\x19\xe9\xbd\x87\x4d\xdf\xd6\x09\x81\x15\x0d\xda\xf8\xd7\xfe\xba\xa4\x37\x4f\x08\x72\xa5\x62\x8d\x31\x80\x00\x31\x1e\x2f\x56\x55\x36\x5a\xd4\xd4\x07\xc2\x0e\x5c\x04\xdf\x17\xa2\x22\xe7\xde\xec\x79\xc5\xab\x11\x16\xd8\x57\x2f\x91\xcd\x06\xe1\xcc\xc7\xce\xd5\x37\x36\xfc\x86\x7f\xd4\x9e\xce\xbe\x6b\xf8\x08\x2e\x8a",
+       "\x91\xb8\xcd\x79\x5d\x1a\x68\x28\x60\x1e\x00\xdb\x0c\x91\xff\x9a\x6f\x83\x74\x44\xf5\x3f\xcf\x89\xe9\x90\xb8\x8f\x5f\x3e\x34\xeb\x49\x0e\x72\xa1\x79\x5f\xab\x84\xf7\x8d\xa3\xf7\xaf\xc8\x98\x96\xc7\xcd\xe5\x86\x5d\x1b\xcd\x74\xd5\x63\x9e\x49\x03\xc6\x83\xfe",
+       230 },
+      { GCRY_MD_SHA3_512,
+       "\x57\xaf\x97\x1f\xcc\xae\xc9\x74\x35\xdc\x2e\xc9\xef\x04\x29\xbc\xed\xc6\xb6\x47\x72\x9e\xa1\x68\x85\x8a\x6e\x49\xac\x10\x71\xe7\x06\xf4\xa5\xa6\x45\xca\x14\xe8\xc7\x74\x6d\x65\x51\x16\x20\x68\x2c\x90\x6c\x8b\x86\xec\x90\x1f\x3d\xde\xd4\x16\x7b\x3f\x00\xb0\x6c\xbf\xac\x6a\xee\x37\x28\x05\x1b\x3e\x5f\xf1\x0b\x4f\x9e\xd8\xbd\x0b\x8d\xa9\x43\x03\xc8\x33\x75\x5b\x3c\xa3\xae\xdd\xf0\xb5\x4b\xc8\xd6\x63\x21\x38\xb5\xd2\x5b\xab\x03\xd1\x7b\x34\x58\xa9\xd7\x82\x10\x80\x06\xf5\xbb\x7d\xe7\x5b\x5c\x0b\xa8\x54\xb4\x23\xd8\xbb\x80\x1e\x70\x1e\x99\xdc\x4f\xea\xad\x59\xbc\x1c\x71\x12\x45\x3b\x04\xd3\x3e\xa3\x63\x56\x39\xfb\x80\x2c\x73\xc2\xb7\x1d\x58\xa5\x6b\xbd\x67\x1b\x18\xfe\x34\xed\x2e\x3d\xca\x38\x82\x7d\x63\xfd\xb1\xd4\xfb\x32\x85\x40\x50\x04\xb2\xb3\xe2\x60\x81\xa8\xff\x08\xcd\x6d\x2b\x08\xf8\xe7\xb7\xe9\x0a\x2a\xb1\xed\x7a\x41\xb1\xd0\x12\x85\x22\xc2\xf8\xbf\xf5\x6a\x7f\xe6\x79\x69\x42\x2c\xe8\x39\xa9\xd4\x60\x8f\x03",
+       "\x76\x35\xd7\x9c\x1b\x32\xe4\x93\x4e\xb0\x09\x0c\x6d\x46\xc0\xb2\x40\xf6\x26\xc7\x7d\x84\xf8\xea\xbf\x57\x1b\xa8\xfd\xe9\x24\xf4\xa1\xcf\x45\x67\x04\xb1\x01\xf6\x67\xf9\x12\xde\xdb\xbc\xbe\xff\x21\x80\xa4\x19\xa6\x8c\x7b\x79\x0b\xa6\x06\xe6\x60\x2d\x51\x15",
+       231 },
+      { GCRY_MD_SHA3_512,
+       "\x04\xe1\x6d\xed\xc1\x22\x79\x02\xba\xaf\x33\x2d\x3d\x08\x92\x36\x01\xbd\xd6\x4f\x57\x3f\xaa\x1b\xb7\x20\x19\x18\xcf\xe1\x6b\x1e\x10\x15\x1d\xae\x87\x5d\xa0\xc0\xd6\x3c\x59\xc3\xdd\x05\x0c\x4c\x6a\x87\x40\x11\xb0\x18\x42\x1a\xfc\x46\x23\xab\x03\x81\x83\x1b\x2d\xa2\xa8\xba\x42\xc9\x6e\x4f\x70\x86\x4a\xc4\x4e\x10\x6f\x94\x31\x10\x51\xe7\x4c\x77\xc1\x29\x1b\xf5\xdb\x95\x39\xe6\x95\x67\xbf\x6a\x11\xcf\x69\x32\xbb\xba\xd3\x3f\x89\x46\xbf\x58\x14\xc0\x66\xd8\x51\x63\x3d\x1a\x51\x35\x10\x03\x9b\x34\x99\x39\xbf\xd4\x2b\x85\x8c\x21\x82\x7c\x8f\xf0\x5f\x1d\x09\xb1\xb0\x76\x5d\xc7\x8a\x13\x5b\x5c\xa4\xdf\xba\x08\x01\xbc\xad\xdf\xa1\x75\x62\x3c\x8b\x64\x7e\xac\xfb\x44\x44\xb8\x5a\x44\xf7\x38\x90\x60\x7d\x06\xd5\x07\xa4\xf8\x39\x36\x58\x78\x86\x69\xf6\xef\x4d\xeb\x58\xd0\x8c\x50\xca\x07\x56\xd5\xe2\xf4\x9d\x1a\x7a\xd7\x3e\x0f\x0b\x3d\x3b\x5f\x09\x0a\xcf\x62\x2b\x18\x78\xc5\x91\x33\xe4\xa8\x48\xe0\x51\x53\x59\x2e\xa8\x1c\x6f\xbf",
+       "\xdd\xd0\xc5\x21\xed\x60\xc5\x5f\x65\xba\xe2\x41\xa9\x07\x2d\x7f\x6f\x6c\xca\x7f\x64\x62\x4e\xc9\x2c\x03\x7b\xf8\xbc\x16\xf0\x60\x2e\x75\xee\x46\x87\x9a\xf4\x1f\x3e\xff\x5c\xe2\x35\x90\x5f\x38\x56\xa0\x31\xc3\xcc\x90\xa4\x85\x1f\x4c\xd8\x46\x3a\xae\x6d\xe8",
+       232 },
+      { GCRY_MD_SHA3_512,
+       "\x7c\x81\x5c\x38\x4e\xee\x0f\x28\x8e\xce\x27\xcc\xed\x52\xa0\x16\x03\x12\x7b\x07\x9c\x00\x73\x78\xbc\x5d\x1e\x6c\x5e\x9e\x6d\x1c\x73\x57\x23\xac\xbb\xd5\x80\x1a\xc4\x98\x54\xb2\xb5\x69\xd4\x47\x2d\x33\xf4\x0b\xbb\x88\x82\x95\x62\x45\xc3\x66\xdc\x35\x82\xd7\x16\x96\xa9\x7a\x4e\x19\x55\x7e\x41\xe5\x4d\xee\x48\x2a\x14\x22\x90\x05\xf9\x3a\xfd\x2c\x4a\x7d\x86\x14\xd1\x0a\x97\xa9\xdf\xa0\x7f\x7c\xd9\x46\xfa\x45\x26\x30\x63\xdd\xd2\x9d\xb8\xf9\xe3\x4d\xb6\x0d\xaa\x32\x68\x4f\x00\x72\xea\x2a\x94\x26\xec\xeb\xfa\x52\x39\xfb\x67\xf2\x9c\x18\xcb\xaa\x2a\xf6\xed\x4b\xf4\x28\x39\x36\x82\x3a\xc1\x79\x01\x64\xfe\xc5\x45\x7a\x9c\xba\x7c\x76\x7c\xa5\x93\x92\xd9\x4c\xab\x74\x48\xf5\x0e\xb3\x4e\x9a\x93\xa8\x00\x27\x47\x1c\xe5\x97\x36\xf0\x99\xc8\x86\xde\xa1\xab\x4c\xba\x4d\x89\xf5\xfc\x7a\xe2\xf2\x1c\xcd\x27\xf6\x11\xec\xa4\x62\x6b\x2d\x08\xdc\x22\x38\x2e\x92\xc1\xef\xb2\xf6\xaf\xdc\x8f\xdc\x3d\x21\x72\x60\x4f\x50\x35\xc4\x6b\x81\x97\xd3",
+       "\xc8\x4c\x03\x56\x4d\x02\x4f\x90\x56\x00\x01\xca\x4c\xef\x86\x7a\xf7\x79\x99\x94\x3e\x31\x3c\xa1\x73\x28\x75\x6c\x43\xd2\xfe\x31\xcf\x98\x81\x2d\x3a\x7a\xab\x15\x35\xc2\x8e\xd2\x9d\x69\x2d\xb4\x82\x4e\x8d\x6d\xce\x06\xc9\x99\x4d\xbc\xbe\x0f\x82\x63\x3f\xbe",
+       233 },
+      { GCRY_MD_SHA3_512,
+       "\xe2\x9d\x50\x51\x58\xdb\xdd\x93\x7d\x9e\x3d\x21\x45\x65\x8e\xe6\xf5\x99\x2a\x2f\xc7\x90\xf4\xf6\x08\xd9\xcd\xb4\x4a\x09\x1d\x5b\x94\xb8\x8e\x81\xfa\xc4\xfd\xf5\xc4\x94\x42\xf1\x3b\x91\x1c\x55\x88\x64\x69\x62\x95\x51\x18\x9e\xaf\xf6\x24\x88\xf1\xa4\x79\xb7\xdb\x11\xa1\x56\x0e\x19\x8d\xdc\xcc\xcf\x50\x15\x90\x93\x42\x5f\xf7\xf1\xcb\x8d\x1d\x12\x46\xd0\x97\x87\x64\x08\x7d\x6b\xac\x25\x70\x26\xb0\x90\xef\xae\x8c\xec\x5f\x22\xb6\xf2\x1c\x59\xac\xe1\xac\x73\x86\xf5\xb8\x83\x7c\xa6\xa1\x2b\x6f\xbf\x55\x34\xdd\x05\x60\xef\x05\xca\x78\x10\x4d\x3b\x94\x3d\xdb\x22\x0f\xea\xec\x89\xaa\x5e\x69\x2a\x00\xf8\x22\xa2\xab\x9a\x2f\xe6\x03\x50\xd7\x5e\x7b\xe1\x6f\xf2\x52\x6d\xc6\x43\x87\x25\x02\xd0\x1f\x42\xf1\x88\xab\xed\x0a\x6e\x9a\x6f\x5f\xd0\xd1\xce\x7d\x57\x55\xc9\xff\xa6\x6b\x0a\xf0\xb2\x0b\xd8\x06\xf0\x8e\x06\x15\x66\x90\xd8\x1a\xc8\x11\x77\x8c\xa3\xda\xc2\xc2\x49\xb9\x60\x02\x01\x7f\xce\x93\xe5\x07\xe3\xb9\x53\xac\xf9\x99\x64\xb8\x47",
+       "\xb4\x56\x31\x91\x67\x51\x91\xed\x4d\x61\x07\xe5\x2f\xa1\x5a\xdc\x9d\x70\x64\x23\x58\xd8\xc3\xe3\x4d\xf1\x02\x74\xe2\x5d\x37\x3f\xd8\xd1\x9e\x92\x47\x2b\x82\x3e\x28\xbb\xdd\x1d\x54\x1a\x95\xfd\xdd\x0d\x43\xc7\x9f\xcb\x3b\xa1\x8a\x7e\xc0\x38\xd3\xef\x69\xa6",
+       234 },
+      { GCRY_MD_SHA3_512,
+       "\xd8\x55\x88\x69\x6f\x57\x6e\x65\xec\xa0\x15\x5f\x39\x5f\x0c\xfa\xcd\x83\xf3\x6a\x99\x11\x1e\xd5\x76\x8d\xf2\xd1\x16\xd2\x12\x1e\x32\x35\x7b\xa4\xf5\x4e\xde\x92\x7f\x18\x9f\x29\x7d\x3a\x97\xfa\xd4\xe9\xa0\xf5\xb4\x1d\x8d\x89\xdd\x7f\xe2\x01\x56\x79\x9c\x2b\x7b\x6b\xf9\xc9\x57\xba\x0d\x67\x63\xf5\xc3\xbc\x51\x29\x74\x7b\xbb\x53\x65\x2b\x49\x29\x0c\xff\x1c\x87\xe2\xcd\xf2\xc4\xb9\x5d\x8a\xae\xe0\x9b\xc8\xfb\xfa\x68\x83\xe6\x2d\x23\x78\x85\x81\x04\x91\xbf\xc1\x01\xf1\xd8\xc6\x36\xe3\xd0\xed\xe8\x38\xad\x05\xc2\x07\xa3\xdf\x4f\xad\x76\x45\x29\x79\xeb\x99\xf2\x9a\xfa\xec\xed\xd1\xc6\x3b\x8d\x36\xcf\x37\x84\x54\xa1\xbb\x67\xa7\x41\xc7\x7a\xc6\xb6\xb3\xf9\x5f\x4f\x02\xb6\x4d\xab\xc1\x54\x38\x61\x3e\xa4\x97\x50\xdf\x42\xee\x90\x10\x1f\x11\x5a\xa9\xab\xb9\xff\x64\x32\x4d\xde\x9d\xab\xbb\x01\x05\x4e\x1b\xd6\xb4\xbc\xdc\x79\x30\xa4\x4c\x23\x00\xd8\x7c\xa7\x8c\x06\x92\x4d\x03\x23\xad\x78\x87\xe4\x6c\x90\xe8\xc4\xd1\x00\xac\xd9\xee\xd2\x1e",
+       "\xa3\x0b\xd8\x0c\xb3\xac\xb3\xbf\xa7\xe0\x37\xa3\xd0\xd2\x50\x09\x74\xd7\x19\x57\xf6\x81\x35\x13\x30\x20\xc3\x2e\xb4\xd6\x88\xf1\x32\xd0\xfb\x04\x5b\xe0\x27\xf1\x24\xb3\xd9\x35\xcb\x88\x9e\x3c\xbc\x4a\x4a\x42\x00\x26\xbb\x2a\xc2\xa4\xb1\xb1\x5c\x57\xbb\x64",
+       235 },
+      { GCRY_MD_SHA3_512,
+       "\x3a\x12\xf8\x50\x8b\x40\xc3\x2c\x74\x49\x2b\x66\x32\x33\x75\xdc\xfe\x49\x18\x4c\x78\xf7\x31\x79\xf3\x31\x4b\x79\xe6\x33\x76\xb8\xac\x68\x3f\x5a\x51\xf1\x53\x4b\xd7\x29\xb0\x2b\x04\xd0\x02\xf5\x5c\xbd\x8e\x8f\xc9\xb5\xec\x1e\xa6\xbb\xe6\xa0\xd0\xe7\x43\x15\x18\xe6\xba\x45\xd1\x24\x03\x5f\x9d\x3d\xce\x0a\x8b\xb7\xbf\x14\x30\xa9\xf6\x57\xe0\xb4\xea\x9f\x20\xeb\x20\xc7\x86\xa5\x81\x81\xa1\xe2\x0a\x96\xf1\x62\x8f\x87\x28\xa1\x3b\xdf\x7a\x4b\x4b\x32\xfc\x8a\xa7\x05\x4c\xc4\x88\x1a\xe7\xfa\x19\xaf\xa6\x5c\x6c\x3e\xe1\xb3\xad\xe3\x19\x2a\xf4\x20\x54\xa8\xa9\x11\xb8\xec\x18\x26\x86\x5d\x46\xd9\x3f\x1e\x7c\x5e\x2b\x78\x13\xc9\x2a\x50\x6e\x53\x88\x6f\x3d\x47\x01\xbb\x93\xd2\xa6\x81\xad\x10\x9c\x84\x59\x04\xbb\x86\x1a\xf8\xaf\x06\x46\xb6\xe3\x99\xb3\x8b\x61\x40\x51\xd3\x4f\x68\x42\x56\x3a\x0f\x37\xec\x00\xcb\x3d\x86\x5f\xc5\xd7\x46\xc4\x98\x7d\xe2\xa6\x50\x71\x10\x08\x83\xa2\xa9\xc7\xa2\xbf\xe1\xe2\xdd\x60\x3d\x9e\xa2\x4d\xc7\xc5\xfd\x06\xbe",
+       "\x4a\x58\x09\xe4\x57\xf5\x4d\x9c\x7e\x82\x09\xf6\xc4\x82\xd5\x2a\x4e\xfe\x6d\x8a\x20\xc4\xc6\xfb\xa8\x36\x87\x29\x49\x29\x23\x2d\x25\xcd\x7b\xf5\x11\xd8\xe6\xfb\xf2\x72\xe9\x83\xf0\x7d\x04\x4f\x87\x23\x09\x8d\x7a\x38\x1f\x04\xe9\x57\xb0\x78\x70\x87\xef\x02",
+       236 },
+      { GCRY_MD_SHA3_512,
+       "\x18\x61\xed\xce\x46\xfa\x5a\xd1\x7e\x1f\xf1\xde\xae\x08\x4d\xec\x58\x0f\x97\xd0\xa6\x78\x85\xdf\xe8\x34\xb9\xdf\xac\x1a\xe0\x76\x74\x2c\xe9\xe2\x67\x51\x2c\xa5\x1f\x6d\xf5\xa4\x55\xaf\x0c\x5f\xd6\xab\xf9\x4a\xce\xa1\x03\xa3\x37\x0c\x35\x44\x85\xa7\x84\x6f\xb8\x4f\x3a\xc7\xc2\x90\x4b\x5b\x2f\xbf\x22\x70\x02\xce\x51\x21\x33\xbb\x7e\x1c\x4e\x50\x05\x7b\xfd\x1e\x44\xdb\x33\xc7\xcd\xb9\x69\xa9\x9e\x28\x4b\x18\x4f\x50\xa1\x4b\x06\x8a\x1f\xc5\x00\x9d\x9b\x29\x8d\xbe\x92\x23\x95\x72\xa7\x62\x7a\xac\x02\xab\xe8\xf3\xe3\xb4\x73\x41\x7f\x36\xd4\xd2\x50\x5d\x16\xb7\x57\x7f\x45\x26\xc9\xd9\x4a\x27\x0a\x2d\xfe\x45\x0d\x06\xda\x8f\x6f\xa9\x56\x87\x9a\x0a\x55\xcf\xe9\x9e\x74\x2e\xa5\x55\xea\x47\x7b\xa3\xe9\xb4\x4c\xcd\x50\x8c\x37\x54\x23\x61\x1a\xf9\x2e\x55\x34\x5d\xc2\x15\x77\x9b\x2d\x51\x19\xeb\xa4\x9c\x71\xd4\x9b\x9f\xe3\xf1\x56\x9f\xa2\x4e\x5c\xa3\xe3\x32\xd0\x42\x42\x2a\x8b\x81\x58\xd3\xec\x66\xa8\x00\x12\x97\x6f\x31\xff\xdf\x30\x5f\x0c\x9c\x5e",
+       "\xa7\x90\x16\xc3\x4b\xee\x41\xab\x5c\xb1\x02\x78\x47\x8a\x5b\x55\xd0\x7c\x2e\x08\x31\x83\x5d\xde\x6f\x8f\xf8\xda\xfa\xc3\x7a\x5f\x88\xfb\xa0\x7c\xce\xff\xe3\x58\x49\xdb\xd1\x23\xb0\x6d\xf2\x33\x5b\x00\x26\x45\xd0\x78\xfe\x1b\x08\x84\x3c\x25\x7a\x1b\xbe\x56",
+       237 },
+      { GCRY_MD_SHA3_512,
+       "\x08\xd0\xff\xde\x3a\x6e\x4e\xf6\x56\x08\xea\x67\x2e\x48\x30\xc1\x29\x43\xd7\x18\x7c\xcf\xf0\x8f\x49\x41\xcf\xc1\x3e\x54\x5f\x3b\x9c\x7a\xd5\xee\xbb\xe2\xb0\x16\x42\xb4\x86\xca\xf8\x55\xc2\xc7\x3f\x58\xc1\xe4\xe3\x39\x1d\xa8\xe2\xd6\x3d\x96\xe1\x5f\xd8\x49\x53\xae\x5c\x23\x19\x11\xb0\x0a\xd6\x05\x0c\xd7\xaa\xfd\xaa\xc9\xb0\xf6\x63\xae\x6a\xab\x45\x51\x9d\x0f\x53\x91\xa5\x41\x70\x7d\x47\x90\x34\xe7\x3a\x6a\xd8\x05\xae\x35\x98\x09\x6a\xf0\x78\xf1\x39\x33\x01\x49\x3d\x66\x3d\xd7\x1f\x83\x86\x9c\xa2\x7b\xa5\x08\xb7\xe9\x1e\x81\xe1\x28\xc1\x71\x6d\xc3\xac\xfe\x30\x84\xb2\x20\x1e\x04\xcf\x80\x06\x61\x7e\xec\xf1\xb6\x40\x47\x4a\x5d\x45\xcf\xde\x9f\x4d\x3e\xf9\x2d\x6d\x05\x5b\x90\x98\x92\x19\x4d\x8a\x82\x18\xdb\x6d\x82\x03\xa8\x42\x61\xd2\x00\xd7\x14\x73\xd7\x48\x8f\x34\x27\x41\x6b\x68\x96\xc1\x37\xd4\x55\xf2\x31\x07\x1c\xac\xbc\x86\xe0\x41\x5a\xb8\x8a\xec\x84\x1d\x96\xb7\xb8\xaf\x41\xe0\x5b\xb4\x61\xa4\x06\x45\xbf\x17\x66\x01\xf1\xe7\x60\xde\x5f",
+       "\x60\x3f\x7b\x09\x56\x56\x34\xd4\x41\x0b\x57\x4a\x4d\xc9\xea\x46\x74\x37\x96\x45\x17\xe5\xef\xa5\x1a\x36\x2a\x30\xe8\xc6\x32\xc5\x51\x62\xa3\x35\x1b\xb5\x53\x2e\x40\x94\x8a\xa9\xa1\xe3\xa8\x78\x6c\x04\x22\xae\xc3\xec\x33\x8c\x7f\x4b\x57\x67\x92\x00\x45\x2b",
+       238 },
+      { GCRY_MD_SHA3_512,
+       "\xd7\x82\xab\xb7\x2a\x5b\xe3\x39\x27\x57\xbe\x02\xd3\xe4\x5b\xe6\xe2\x09\x9d\x6f\x00\x0d\x04\x2c\x8a\x54\x3f\x50\xed\x6e\xbc\x05\x5a\x7f\x13\x3b\x0d\xd8\xe9\xbc\x34\x85\x36\xed\xca\xae\x2e\x12\xec\x18\xe8\x83\x7d\xf7\xa1\xb3\xc8\x7e\xc4\x6d\x50\xc2\x41\xde\xe8\x20\xfd\x58\x61\x97\x55\x2d\xc2\x0b\xee\xa5\x0f\x44\x5a\x07\xa3\x8f\x17\x68\xa3\x9e\x2b\x2f\xf0\x5d\xdd\xed\xf7\x51\xf1\xde\xf6\x12\xd2\xe4\xd8\x10\xda\xa3\xa0\xcc\x90\x45\x16\xf9\xa4\x3a\xf6\x60\x31\x53\x85\x17\x8a\x52\x9e\x51\xf8\xaa\xe1\x41\x80\x8c\x8b\xc5\xd7\xb6\x0c\xac\x26\xbb\x98\x4a\xc1\x89\x0d\x04\x36\xef\x78\x04\x26\xc5\x47\xe9\x4a\x7b\x08\xf0\x1a\xcb\xfc\x4a\x38\x25\xea\xe0\x4f\x52\x0a\x90\x16\xf2\xfb\x8b\xf5\x16\x5e\xd1\x27\x36\xfc\x71\xe3\x6a\x49\xa7\x36\x14\x73\x9e\xaa\x3e\xc8\x34\x06\x9b\x1b\x40\xf1\x35\x0c\x2b\x3a\xb8\x85\xc0\x2c\x64\x0b\x9f\x76\x86\xed\x5f\x99\x52\x7e\x41\xcf\xcd\x79\x6f\xe4\xc2\x56\xc9\x17\x31\x86\xc2\x26\x16\x9f\xf2\x57\x95\x4e\xbd\xa8\x1c\x0e\x5f\x99",
+       "\x10\x18\x69\x2d\x53\x0c\x55\xba\xa5\x80\xae\x1e\x73\x84\x35\x11\x00\xd4\x63\x7c\xd3\x38\x69\xc7\x1e\x60\x76\xa3\xd4\xe3\x10\xd9\x64\xb8\x1d\x59\x3e\x89\x71\x88\x45\xac\x7a\x89\xe8\xad\x50\x73\x50\x64\x27\xc6\xc8\xf7\xfa\xdf\xa0\xc5\xdc\x3c\xfa\xa5\xd9\x24",
+       239 },
+      { GCRY_MD_SHA3_512,
+       "\x5f\xce\x81\x09\xa3\x58\x57\x0e\x40\x98\x3e\x11\x84\xe5\x41\x83\x3b\xb9\x09\x1e\x28\x0f\x25\x8c\xfb\x14\x43\x87\xb0\x5d\x19\x0e\x43\x1c\xb1\x9b\xaa\x67\x27\x3b\xa0\xc5\x8a\xbe\x91\x30\x8e\x18\x44\xdc\xd0\xb3\x67\x8b\xaa\x42\xf3\x35\xf2\xfa\x05\x26\x7a\x02\x40\xb3\xc7\x18\xa5\x94\x2b\x3b\x3e\x3b\xfa\x98\xa5\x5c\x25\xa1\x46\x6e\x8d\x7a\x60\x37\x22\xcb\x2b\xbf\x03\xaf\xa5\x4c\xd7\x69\xa9\x9f\x31\x07\x35\xee\x5a\x05\xda\xe2\xc2\x2d\x39\x7b\xd9\x56\x35\xf5\x8c\x48\xa6\x7f\x90\xe1\xb7\x3a\xaf\xcd\x3f\x82\x11\x7f\x01\x66\x65\x78\x38\x69\x10\x05\xb1\x8d\xa6\xf3\x41\xd6\xe9\x0f\xc1\xcd\xb3\x52\xb3\x0f\xae\x45\xd3\x48\x29\x4e\x50\x1b\x63\x25\x2d\xe1\x47\x40\xf2\xb8\x5a\xe5\x29\x9d\xde\xc3\x17\x2d\xe8\xb6\xd0\xba\x21\x9a\x20\xa2\x3b\xb5\xe1\x0f\xf4\x34\xd3\x9d\xb3\xf5\x83\x30\x5e\x9f\x5c\x03\x9d\x98\x56\x9e\x37\x7b\x75\xa7\x0a\xb8\x37\xd1\xdf\x26\x9b\x8a\x4b\x56\x6f\x40\xbb\x91\xb5\x77\x45\x5f\xd3\xc3\x56\xc9\x14\xfa\x06\xb9\xa7\xce\x24\xc7\x31\x7a\x17\x2d",
+       "\xe3\xc0\xea\xff\xc3\x56\x7b\xd7\x2c\xc0\x21\x50\xa7\x5f\x32\xdd\xe5\x3d\xe2\x65\x2c\x53\x13\xeb\x3e\x97\x01\x8a\xdd\xdf\x62\x9d\xa0\x1d\x97\xd0\xa9\xe2\x51\x94\x51\xa7\x29\x2f\x5d\xe0\x0e\xe4\x45\x6f\xe6\xe4\xf1\x4f\x96\xd5\xde\x7e\x6f\x17\x4e\xdb\x28\xc4",
+       240 },
+      { GCRY_MD_SHA3_512,
+       "\x61\x72\xf1\x97\x1a\x6e\x1e\x4e\x61\x70\xaf\xba\xd9\x5d\x5f\xec\x99\xbf\x69\xb2\x4b\x67\x4b\xc1\x7d\xd7\x80\x11\x61\x5e\x50\x2d\xe6\xf5\x6b\x86\xb1\xa7\x1d\x3f\x43\x48\x08\x72\x18\xac\x7b\x7d\x09\x30\x29\x93\xbe\x27\x2e\x4a\x59\x19\x68\xae\xf1\x8a\x12\x62\xd6\x65\x61\x0d\x10\x70\xee\x91\xcc\x8d\xa3\x6e\x1f\x84\x1a\x69\xa7\xa6\x82\xc5\x80\xe8\x36\x94\x1d\x21\xd9\x09\xa3\xaf\xc1\xf0\xb9\x63\xe1\xca\x5a\xb1\x93\xe1\x24\xa1\xa5\x3d\xf1\xc5\x87\x47\x0e\x58\x81\xfb\x54\xda\xe1\xb0\xd8\x40\xf0\xc8\xf9\xd1\xb0\x4c\x64\x5b\xa1\x04\x1c\x7d\x8d\xbf\x22\x03\x0a\x62\x3a\xa1\x56\x38\xb3\xd9\x9a\x2c\x40\x0f\xf7\x6f\x32\x52\x07\x9a\xf8\x8d\x2b\x37\xf3\x5e\xe6\x6c\x1a\xd7\x80\x1a\x28\xd3\xd3\x88\xac\x45\x0b\x97\xd5\xf0\xf7\x9e\x45\x41\x75\x53\x56\xb3\xb1\xa5\x69\x6b\x02\x3f\x39\xab\x7a\xb5\xf2\x8d\xf4\x20\x29\x36\xbc\x97\x39\x3b\x93\xbc\x91\x5c\xb1\x59\xea\x1b\xd7\xa0\xa4\x14\xcb\x4b\x7a\x1a\xc3\xaf\x68\xf5\x0d\x79\xf0\xc9\xc7\x31\x4e\x75\x0f\x7d\x02\xfa\xa5\x8b\xfa",
+       "\x19\x2a\xe7\xa0\xf7\xa8\x16\xfd\x3d\x40\x20\xbd\xdc\xf2\xaa\xf5\x2a\x64\xe6\x38\x4d\xca\x52\x7f\x33\xaf\x4e\xe6\x90\x99\xdc\xa9\x7b\x89\x0a\x99\xcf\xab\x9d\x90\x4a\x35\xf2\x70\x78\x56\x69\x6c\x30\xc6\x43\x2d\xf7\x0a\x6c\xef\x70\x4b\xb2\x68\x05\x5a\x6d\x07",
+       241 },
+      { GCRY_MD_SHA3_512,
+       "\x56\x68\xec\xd9\x9d\xfb\xe2\x15\xc4\x11\x83\x98\xac\x9c\x9e\xaf\x1a\x14\x33\xfa\xb4\xcc\xdd\x39\x68\x06\x47\x52\xb6\x25\xea\x94\x47\x31\xf7\x5d\x48\xa2\x7d\x04\x7d\x67\x54\x7f\x14\xdd\x0f\xfa\xa5\x5f\xa5\xe2\x9f\x7a\xf0\xd1\x61\xd8\x5e\xaf\xc4\xf2\x02\x9b\x71\x7c\x91\x8e\xab\x9d\x30\x45\x43\x29\x0b\xdb\xa7\x15\x8b\x68\x02\x0c\x0b\xa4\xe0\x79\xbc\x95\xb5\xbc\x0f\xc0\x44\xa9\x92\xb9\x4b\x4c\xcd\x3b\xd6\x6d\x0e\xab\xb5\xdb\xba\xb9\x04\xd6\x2e\x00\x75\x2c\x4e\x3b\x00\x91\xd7\x73\xbc\xf4\xc1\x4b\x43\x77\xda\x3e\xff\xf8\x24\xb1\xcb\x2f\xa0\x1b\x32\xd1\xe4\x6c\x90\x9e\x62\x6e\xd2\xda\xe9\x20\xf4\xc7\xdb\xeb\x63\x5b\xc7\x54\xfa\xcb\xd8\xd4\x9b\xeb\xa3\xf2\x3c\x1c\x41\xcc\xbf\xcd\x0e\xe0\xc1\x14\xe6\x97\x37\xf5\x59\x7c\x0b\xf1\xd8\x59\xf0\xc7\x67\xe1\x80\x02\xae\x8e\x39\xc2\x62\x61\xff\xde\x29\x20\xd3\xd0\xba\xf0\xe9\x06\x13\x86\x96\xcf\xe5\xb7\xe3\x2b\x60\x0f\x45\xdf\x3a\xaa\x39\x93\x2f\x3a\x7d\xf9\x5b\x60\xfa\x87\x12\xa2\x27\x1f\xca\xf3\x91\x1c\xe7\xb5\x11\xb1",
+       "\x6b\xcd\x7e\x7c\x35\x9f\xdd\x93\xa5\x6d\x79\xf9\x7f\xc2\xd5\x34\x61\x9f\x14\xfe\x44\x3a\xc8\xc9\xe0\x42\xc5\x10\x5f\xba\xf2\x77\x77\x18\xde\x07\x42\x4a\x62\x33\x3f\xfd\x43\xa5\x01\xa8\x54\x44\x49\xa7\xca\xc3\xc8\xd8\x21\xe3\x80\xb0\xcb\x81\x72\xb9\x49\x3b",
+       242 },
+      { GCRY_MD_SHA3_512,
+       "\x03\xd6\x25\x48\x83\x54\xdf\x30\xe3\xf8\x75\xa6\x8e\xdf\xcf\x34\x0e\x83\x66\xa8\xe1\xab\x67\xf9\xd5\xc5\x48\x6a\x96\x82\x9d\xfa\xc0\x57\x82\x89\x08\x2b\x2a\x62\x11\x7e\x1c\xf4\x18\xb4\x3b\x90\xe0\xad\xc8\x81\xfc\x6a\xe8\x10\x5c\x88\x8e\x9e\xcd\x21\xae\xa1\xc9\xae\x1a\x40\x38\xdf\xd1\x73\x78\xfe\xd7\x1d\x02\xae\x49\x20\x87\xd7\xcd\xcd\x98\xf7\x46\x85\x52\x27\x96\x7c\xb1\xab\x47\x14\x26\x1e\xe3\xbe\xad\x3f\x4d\xb1\x18\x32\x9d\x3e\xbe\xf4\xbc\x48\xa8\x75\xc1\x9b\xa7\x63\x96\x6d\xa0\xeb\xea\x80\x0e\x01\xb2\xf5\x0b\x00\xe9\xdd\x4c\xac\xa6\xdc\xb3\x14\xd0\x01\x84\xef\x71\xea\x23\x91\xd7\x60\xc9\x50\x71\x0d\xb4\xa7\x0f\x92\x12\xff\xc5\x48\x61\xf9\xdc\x75\x2c\xe1\x88\x67\xb8\xad\x0c\x48\xdf\x84\x66\xef\x72\x31\xe7\xac\x56\x7f\x0e\xb5\x50\x99\xe6\x22\xeb\xb8\x6c\xb2\x37\x52\x01\x90\xa6\x1c\x66\xad\x34\xf1\xf4\xe2\x89\xcb\x32\x82\xae\x3e\xaa\xc6\x15\x2e\xd2\x4d\x2c\x92\xba\xe5\xa7\x65\x82\x52\xa5\x3c\x49\xb7\xb0\x2d\xfe\x54\xfd\xb2\xe9\x00\x74\xb6\xcf\x31\x0a\xc6\x61",
+       "\x1f\xcd\x1e\x38\xab\x03\xc7\x50\x36\x6c\xf8\x6d\xd7\x2e\xc3\xbf\x22\xf5\xbb\xf7\xfe\xa0\x14\x9d\x31\xb6\xa6\x7b\x68\xb5\x37\xb5\x9b\xa3\x79\x17\xfd\x88\xce\xd9\xaa\x8d\x29\x41\xa6\x5f\x55\x2b\x79\x28\xb3\x78\x5c\x66\xd6\x40\xf3\xb7\x4a\xf0\x39\xed\x18\xce",
+       243 },
+      { GCRY_MD_SHA3_512,
+       "\x2e\xdc\x28\x2f\xfb\x90\xb9\x71\x18\xdd\x03\xaa\xa0\x3b\x14\x5f\x36\x39\x05\xe3\xcb\xd2\xd5\x0e\xcd\x69\x2b\x37\xbf\x00\x01\x85\xc6\x51\xd3\xe9\x72\x6c\x69\x0d\x37\x73\xec\x1e\x48\x51\x0e\x42\xb1\x77\x42\xb0\xb0\x37\x7e\x7d\xe6\xb8\xf5\x5e\x00\xa8\xa4\xdb\x47\x40\xce\xe6\xdb\x08\x30\x52\x9d\xd1\x96\x17\x50\x1d\xc1\xe9\x35\x9a\xa3\xbc\xf1\x47\xe0\xa7\x6b\x3a\xb7\x0c\x49\x84\xc1\x3e\x33\x9e\x68\x06\xbb\x35\xe6\x83\xaf\x85\x27\x09\x36\x70\x85\x9f\x3d\x8a\x0f\xc7\xd4\x93\xbc\xba\x6b\xb1\x2b\x5f\x65\xe7\x1e\x70\x5c\xa5\xd6\xc9\x48\xd6\x6e\xd3\xd7\x30\xb2\x6d\xb3\x95\xb3\x44\x77\x37\xc2\x6f\xad\x08\x9a\xa0\xad\x0e\x30\x6c\xb2\x8b\xf0\xac\xf1\x06\xf8\x9a\xf3\x74\x5f\x0e\xc7\x2d\x53\x49\x68\xcc\xa5\x43\xcd\x2c\xa5\x0c\x94\xb1\x45\x67\x43\x25\x4e\x35\x8c\x13\x17\xc0\x7a\x07\xbf\x2b\x0e\xca\x43\x8a\x70\x93\x67\xfa\xfc\x89\xa5\x72\x39\x02\x8f\xc5\xfe\xcf\xd5\x3b\x8e\xf9\x58\xef\x10\xee\x06\x08\xb7\xf5\xcb\x99\x23\xad\x97\x05\x8e\xc0\x67\x70\x0c\xc7\x46\xc1\x27\xa6\x1e\xe3",
+       "\xf3\x9e\xf0\x62\x6d\x3f\xbd\x9c\xd4\x35\xa9\x3e\x7e\xee\x41\xe4\xa2\xff\x53\x62\xf5\x6c\x98\x8b\x20\x87\x0a\x3b\xef\xa5\x04\x70\xdc\x5f\xab\xe3\x98\x95\xc0\x76\x12\x89\xfa\xfd\x91\x47\xab\xab\x02\x56\x1f\x30\x0d\x0c\xeb\x9a\x73\x2e\x14\xca\x88\x7c\xaf\x18",
+       244 },
+      { GCRY_MD_SHA3_512,
+       "\x90\xb2\x8a\x6a\xa1\xfe\x53\x39\x15\xbc\xb8\xe8\x1e\xd6\xca\xcd\xc1\x09\x62\xb7\xff\x82\x47\x4f\x84\x5e\xeb\x86\x97\x76\x00\xcf\x70\xb0\x7b\xa8\xe3\x79\x61\x41\xee\x34\x0e\x3f\xce\x84\x2a\x38\xa5\x0a\xfb\xe9\x03\x01\xa3\xbd\xcc\x59\x1f\x2e\x7d\x9d\xe5\x3e\x49\x55\x25\x56\x0b\x90\x8c\x89\x24\x39\x99\x0a\x2c\xa2\x67\x9c\x55\x39\xff\xdf\x63\x67\x77\xad\x9c\x1c\xde\xf8\x09\xcd\xa9\xe8\xdc\xdb\x45\x1a\xbb\x9e\x9c\x17\xef\xa4\x37\x9a\xbd\x24\xb1\x82\xbd\x98\x1c\xaf\xc7\x92\x64\x0a\x18\x3b\x61\x69\x43\x01\xd0\x4c\x5b\x3e\xaa\xd6\x94\xa6\xbd\x4c\xc0\x6e\xf5\xda\x8f\xa2\x3b\x4f\xa2\xa6\x45\x59\xc5\xa6\x83\x97\x93\x00\x79\xd2\x50\xc5\x1b\xcf\x00\xe2\xb1\x6a\x6c\x49\x17\x14\x33\xb0\xaa\xdf\xd8\x02\x31\x27\x65\x60\xb8\x04\x58\xdd\x77\x08\x9b\x7a\x1b\xbc\xc9\xe7\xe4\xb9\xf8\x81\xea\xcd\x6c\x92\xc4\x31\x83\x48\xa1\x3f\x49\x14\xeb\x27\x11\x5a\x1c\xfc\x5d\x16\xd7\xfd\x94\x95\x4c\x35\x32\xef\xac\xa2\xca\xb0\x25\x10\x3b\x2d\x02\xc6\xfd\x71\xda\x3a\x77\xf4\x17\xd7\x93\x26\x85\x88\x8a",
+       "\x81\xe8\xb5\x9d\xdc\xd2\x48\x11\xb4\x05\xf7\x52\x9d\xa1\x25\xf0\xdc\x19\xae\x21\xe8\x79\x5c\xe9\xe6\x69\x2d\xab\x64\x5b\x79\x59\x44\x6a\xdc\xaa\x30\x61\xdc\x46\x42\xa5\x1d\x8a\x56\x2e\xfb\x03\xa7\x68\x0a\xf0\xf5\x2c\x01\x40\x6d\x5c\x21\x3e\xaa\xc6\xbe\x55",
+       245 },
+      { GCRY_MD_SHA3_512,
+       "\x29\x69\x44\x7d\x17\x54\x90\xf2\xaa\x9b\xb0\x55\x01\x4d\xbe\xf2\xe6\x85\x4c\x95\xf8\xd6\x09\x50\xbf\xe8\xc0\xbe\x8d\xe2\x54\xc2\x6b\x2d\x31\xb9\xe4\xde\x9c\x68\xc9\xad\xf4\x9e\x4e\xe9\xb1\xc2\x85\x09\x67\xf2\x9f\x5d\x08\x73\x84\x83\xb4\x17\xbb\x96\xb2\xa5\x6f\x0c\x8a\xca\x63\x2b\x55\x20\x59\xc5\x9a\xac\x3f\x61\xf7\xb4\x5c\x96\x6b\x75\xf1\xd9\x93\x1f\xf4\xe5\x96\x40\x63\x78\xce\xe9\x1a\xaa\x72\x6a\x3a\x84\xc3\x3f\x37\xe9\xcd\xbe\x62\x6b\x57\x45\xa0\xb0\x60\x64\xa8\xa8\xd5\x6e\x53\xaa\xf1\x02\xd2\x3d\xd9\xdf\x0a\x3f\xdf\x7a\x63\x85\x09\xa6\x76\x1a\x33\xfa\x42\xfa\x8d\xdb\xd8\xe1\x61\x59\xc9\x30\x08\xb5\x37\x65\x01\x9c\x3f\x0e\x9f\x10\xb1\x44\xce\x2a\xc5\x7f\x5d\x72\x97\xf9\xc9\x94\x9e\x4f\xf6\x8b\x70\xd3\x39\xf8\x75\x01\xce\x85\x50\xb7\x72\xf3\x2c\x6d\xa8\xad\x2c\xe2\x10\x0a\x89\x5d\x8b\x08\xfa\x1e\xea\xd7\xc3\x76\xb4\x07\x70\x97\x03\xc5\x10\xb5\x0f\x87\xe7\x3e\x43\xf8\xe7\x34\x8f\x87\xc3\x83\x2a\x54\x7e\xf2\xbb\xe5\x79\x9a\xbe\xdc\xf5\xe1\xf3\x72\xea\x80\x92\x33\xf0\x06",
+       "\x63\x42\x4b\x09\x06\x9f\xbd\x2d\x0f\xac\x00\x80\x5a\xad\x07\xfd\x56\xe3\x0b\xb8\x11\x6b\x54\x76\xae\x90\xbf\x6a\xce\xc8\x4c\x3b\x45\x36\x8a\x9e\xbb\x7f\xce\xa8\xd6\x59\x65\xf5\x25\x14\xa2\xa5\x9a\x06\xe6\xe0\x6b\x07\xdc\x6a\xee\x7f\x75\x6b\xfc\x18\x8e\x25",
+       246 },
+      { GCRY_MD_SHA3_512,
+       "\x72\x16\x45\x63\x3a\x44\xa2\xc7\x8b\x19\x02\x4e\xae\xcf\x58\x57\x5a\xb2\x3c\x27\x19\x08\x33\xc2\x68\x75\xdc\x0f\x0d\x50\xb4\x6a\xea\x9c\x34\x3d\x82\xea\x7d\x5b\x3e\x50\xec\x70\x05\x45\xc6\x15\xda\xea\xea\x64\x72\x6a\x0f\x05\x60\x75\x76\xdc\xd3\x96\xd8\x12\xb0\x3f\xb6\x55\x1c\x64\x10\x87\x85\x6d\x05\x0b\x10\xe6\xa4\xd5\x57\x7b\x82\xa9\x8a\xfb\x89\xce\xe8\x59\x4c\x9d\xc1\x9e\x79\xfe\xff\x03\x82\xfc\xfd\x12\x7f\x1b\x80\x3a\x4b\x99\x46\xf4\xac\x9a\x43\x78\xe1\xe6\xe0\x41\xb1\x38\x9a\x53\xe3\x45\x0c\xd3\x2d\x9d\x29\x41\xb0\xcb\xab\xdb\x50\xda\x8e\xa2\x51\x31\x45\x16\x4c\x3a\xb6\xbc\xbd\x25\x1c\x44\x8d\x2d\x4b\x08\x7a\xc5\x7a\x59\xc2\x28\x5d\x56\x4f\x16\xda\x4e\xd5\xe6\x07\xed\x97\x95\x92\x14\x6f\xfb\x0e\xf3\xf3\xdb\x30\x8f\xb3\x42\xdf\x5e\xb5\x92\x4a\x48\x25\x6f\xc7\x63\x14\x1a\x27\x88\x14\xc8\x2d\x6d\x63\x48\x57\x75\x45\x87\x0a\xe3\xa8\x3c\x72\x30\xac\x02\xa1\x54\x0f\xe1\x79\x8f\x7e\xf0\x9e\x33\x5a\x86\x5a\x2a\xe0\x94\x9b\x21\xe4\xf7\x48\xfb\x8a\x51\xf4\x47\x50\xe2\x13\xa8\xfb",
+       "\x1e\x70\x9f\xb3\x50\x1f\xa8\x18\xf5\x7e\x70\xc3\x65\xdb\x45\xcc\xf2\xeb\x8a\x8f\xa6\x6d\xe9\xb5\xf2\x11\xd6\xf0\xcc\x97\x22\xad\xe9\x63\xc9\x65\xad\x5f\x69\x37\xba\x62\xed\xc2\xd8\x98\x38\x43\xe0\xf3\x67\x9d\x9c\x97\xb3\x0c\xd5\x4f\x24\x09\xdd\xa5\xf4\x74",
+       247 },
+      { GCRY_MD_SHA3_512,
+       "\x6b\x86\x0d\x39\x72\x5a\x14\xb4\x98\xbb\x71\x45\x74\xb4\xd3\x7c\xa7\x87\x40\x47\x68\xf6\x4c\x64\x8b\x17\x51\xb3\x53\xac\x92\xba\xc2\xc3\xa2\x8e\xa9\x09\xfd\xf0\x42\x33\x36\x40\x1a\x02\xe6\x3e\xc2\x43\x25\x30\x0d\x82\x3b\x68\x64\xbb\x70\x1f\x9d\x7c\x7a\x1f\x8e\xc9\xd0\xae\x35\x84\xaa\x6d\xd6\x2e\xa1\x99\x7c\xd8\x31\xb4\xba\xbd\x9a\x4d\xa5\x09\x32\xd4\xef\xda\x74\x5c\x61\xe4\x13\x08\x90\xe1\x56\xae\xe6\x11\x37\x16\xda\xf9\x57\x64\x22\x2a\x91\x18\x7d\xb2\xef\xfe\xa4\x9d\x5d\x05\x96\x10\x2d\x61\x9b\xd2\x6a\x61\x6b\xbf\xda\x83\x35\x50\x5f\xbb\x0d\x90\xb4\xc1\x80\xd1\xa2\x33\x5b\x91\x53\x8e\x16\x68\xf9\xf9\x64\x27\x90\xb4\xe5\x5f\x9c\xab\x0f\xe2\xbd\xd2\x93\x5d\x00\x1e\xe6\x41\x9a\xba\xb5\x45\x78\x80\xd0\xdb\xff\x20\xed\x87\x58\xf4\xc2\x0f\xe7\x59\xef\xb3\x31\x41\xcf\x0e\x89\x25\x87\xfe\x81\x87\xe5\xfb\xc5\x77\x86\xb7\xe8\xb0\x89\x61\x2c\x93\x6d\xfc\x03\xd2\x7e\xfb\xbe\x7c\x86\x73\xf1\x60\x6b\xd5\x1d\x5f\xf3\x86\xf4\xa7\xab\x68\xed\xf5\x9f\x38\x5e\xb1\x29\x1f\x11\x7b\xfe\x71\x73\x99",
+       "\x5b\x9f\x0c\x54\x46\x27\xfa\xad\xea\x82\x82\x5a\x56\x9d\xa3\x3a\x75\xc5\xda\x6c\xc1\x69\x92\x6d\xe0\x55\x6a\x73\x7e\x4d\xaa\x07\xab\xf1\xdc\x3d\xb0\x70\x4f\x5d\x67\xfc\xbc\x4c\xb6\x2a\xac\x44\x2e\xce\xc8\x67\xa2\xc1\x68\x46\xf1\xd5\x3d\x20\x5c\xb8\x72\xac",
+       248 },
+      { GCRY_MD_SHA3_512,
+       "\x6a\x01\x83\x0a\xf3\x88\x9a\x25\x18\x32\x44\xde\xcb\x50\x8b\xd0\x12\x53\xd5\xb5\x08\xab\x49\x0d\x31\x24\xaf\xbf\x42\x62\x6b\x2e\x70\x89\x4e\x9b\x56\x2b\x28\x8d\x0a\x24\x50\xcf\xac\xf1\x4a\x0d\xda\xe5\xc0\x47\x16\xe5\xa0\x08\x2c\x33\x98\x1f\x60\x37\xd2\x3d\x5e\x04\x5e\xe1\xef\x22\x83\xfb\x8b\x63\x78\xa9\x14\xc5\xd9\x44\x16\x27\xa7\x22\xc2\x82\xff\x45\x2e\x25\xa7\xea\x60\x8d\x69\xce\xe4\x39\x3a\x07\x25\xd1\x79\x63\xd0\x34\x26\x84\xf2\x55\x49\x6d\x8a\x18\xc2\x96\x11\x45\x31\x51\x30\x54\x93\x11\xfc\x07\xf0\x31\x2f\xb7\x8e\x60\x77\x33\x4f\x87\xea\xa8\x73\xbe\xe8\xaa\x95\x69\x89\x96\xeb\x21\x37\x5e\xb2\xb4\xef\x53\xc1\x44\x01\x20\x7d\xeb\x45\x68\x39\x8e\x5d\xd9\xa7\xcf\x97\xe8\xc9\x66\x3e\x23\x33\x4b\x46\x91\x2f\x83\x44\xc1\x9e\xfc\xf8\xc2\xba\x6f\x04\x32\x5f\x1a\x27\xe0\x62\xb6\x2a\x58\xd0\x76\x6f\xc6\xdb\x4d\x2c\x6a\x19\x28\x60\x4b\x01\x75\xd8\x72\xd1\x6b\x79\x08\xeb\xc0\x41\x76\x11\x87\xcc\x78\x55\x26\xc2\xa3\x87\x3f\xea\xc3\xa6\x42\xbb\x39\xf5\x35\x15\x50\xaf\x97\x70\xc3\x28\xaf\x7b",
+       "\x93\x0a\xb4\x2a\x9f\x5f\x5b\xc5\xf2\x22\x2c\x74\x8f\x24\x78\xa0\x0f\x40\xc3\xb6\xd6\x48\x7d\x6d\x7e\xd0\xd7\x11\x00\xf4\x0f\xcb\xb2\xc6\x65\x66\xea\x26\xad\x0a\x41\x76\x29\xf5\xa6\x1d\xca\x41\x1c\xcd\x21\xf7\x36\x7d\x30\x8f\x3b\x1b\x24\x90\x18\x24\xfa\x9b",
+       249 },
+      { GCRY_MD_SHA3_512,
+       "\xb3\xc5\xe7\x4b\x69\x93\x3c\x25\x33\x10\x6c\x56\x3b\x4c\xa2\x02\x38\xf2\xb6\xe6\x75\xe8\x68\x1e\x34\xa3\x89\x89\x47\x85\xbd\xad\xe5\x96\x52\xd4\xa7\x3d\x80\xa5\xc8\x5b\xd4\x54\xfd\x1e\x9f\xfd\xad\x1c\x38\x15\xf5\x03\x8e\x9e\xf4\x32\xaa\xc5\xc3\xc4\xfe\x84\x0c\xc3\x70\xcf\x86\x58\x0a\x60\x11\x77\x8b\xbe\xda\xf5\x11\xa5\x1b\x56\xd1\xa2\xeb\x68\x39\x4a\xa2\x99\xe2\x6d\xa9\xad\xa6\xa2\xf3\x9b\x9f\xaf\xf7\xfb\xa4\x57\x68\x9b\x9c\x1a\x57\x7b\x2a\x1e\x50\x5f\xdf\x75\xc7\xa0\xa6\x4b\x1d\xf8\x1b\x3a\x35\x60\x01\xbf\x0d\xf4\xe0\x2a\x1f\xc5\x9f\x65\x1c\x9d\x58\x5e\xc6\x22\x4b\xb2\x79\xc6\xbe\xba\x29\x66\xe8\x88\x2d\x68\x37\x60\x81\xb9\x87\x46\x8e\x7a\xed\x1e\xf9\x0e\xbd\x09\x0a\xe8\x25\x79\x5c\xdc\xa1\xb4\xf0\x9a\x97\x9c\x8d\xfc\x21\xa4\x8d\x8a\x53\xcd\xbb\x26\xc4\xdb\x54\x7f\xc0\x6e\xfe\x2f\x98\x50\xed\xd2\x68\x5a\x46\x61\xcb\x49\x11\xf1\x65\xd4\xb6\x3e\xf2\x5b\x87\xd0\xa9\x6d\x3d\xff\x6a\xb0\x75\x89\x99\xaa\xd2\x14\xd0\x7b\xd4\xf1\x33\xa6\x73\x4f\xde\x44\x5f\xe4\x74\x71\x1b\x69\xa9\x8f\x7e\x2b",
+       "\x08\x20\x39\x43\xc5\x82\x10\xd3\xf8\x27\x58\x27\x2b\xef\xbb\x92\x34\xfe\x91\x34\x09\xa0\x79\x44\x64\x59\x59\xb1\xa6\xaf\x2f\x43\x63\xab\xd7\x45\x12\x32\x62\x3d\xaa\x8e\x65\xc8\x7f\x34\x93\x9c\x14\x06\x08\x95\x0f\xbd\xbb\xe8\x3d\x66\x40\x79\x44\xf5\x42\x3a",
+       250 },
+      { GCRY_MD_SHA3_512,
+       "\x83\xaf\x34\x27\x9c\xcb\x54\x30\xfe\xbe\xc0\x7a\x81\x95\x0d\x30\xf4\xb6\x6f\x48\x48\x26\xaf\xee\x74\x56\xf0\x07\x1a\x51\xe1\xbb\xc5\x55\x70\xb5\xcc\x7e\xc6\xf9\x30\x9c\x17\xbf\x5b\xef\xdd\x7c\x6b\xa6\xe9\x68\xcf\x21\x8a\x2b\x34\xbd\x5c\xf9\x27\xab\x84\x6e\x38\xa4\x0b\xbd\x81\x75\x9e\x9e\x33\x38\x10\x16\xa7\x55\xf6\x99\xdf\x35\xd6\x60\x00\x7b\x5e\xad\xf2\x92\xfe\xef\xb7\x35\x20\x7e\xbf\x70\xb5\xbd\x17\x83\x4f\x7b\xfa\x0e\x16\xcb\x21\x9a\xd4\xaf\x52\x4a\xb1\xea\x37\x33\x4a\xa6\x64\x35\xe5\xd3\x97\xfc\x0a\x06\x5c\x41\x1e\xbb\xce\x32\xc2\x40\xb9\x04\x76\xd3\x07\xce\x80\x2e\xc8\x2c\x1c\x49\xbc\x1b\xec\x48\xc0\x67\x5e\xc2\xa6\xc6\xf3\xed\x3e\x5b\x74\x1d\x13\x43\x70\x95\x70\x7c\x56\x5e\x10\xd8\xa2\x0b\x8c\x20\x46\x8f\xf9\x51\x4f\xcf\x31\xb4\x24\x9c\xd8\x2d\xce\xe5\x8c\x0a\x2a\xf5\x38\xb2\x91\xa8\x7e\x33\x90\xd7\x37\x19\x1a\x07\x48\x4a\x5d\x3f\x3f\xb8\xc8\xf1\x5c\xe0\x56\xe5\xe5\xf8\xfe\xbe\x5e\x1f\xb5\x9d\x67\x40\x98\x0a\xa0\x6c\xa8\xa0\xc2\x0f\x57\x12\xb4\xcd\xe5\xd0\x32\xe9\x2a\xb8\x9f\x0a\xe1",
+       "\xa2\x4d\xd6\xa5\x03\x33\xf2\x89\xc1\x75\xcd\x4e\xc1\x85\xda\x99\x06\xe3\x8c\x28\x7a\x33\x9d\xc4\xde\xfa\xfd\x71\xb2\xea\x32\xa6\xf6\xae\xfe\x75\x8e\x25\xfc\x8f\x04\x3e\x80\x6f\x1b\x2e\xe0\x19\xe1\x3b\x85\x53\x6c\xd3\xef\xaa\x2a\x9b\x59\x94\xfc\xae\x47\x88",
+       251 },
+      { GCRY_MD_SHA3_512,
+       "\xa7\xed\x84\x74\x9c\xcc\x56\xbb\x1d\xfb\xa5\x71\x19\xd2\x79\xd4\x12\xb8\xa9\x86\x88\x6d\x81\x0f\x06\x7a\xf3\x49\xe8\x74\x9e\x9e\xa7\x46\xa6\x0b\x03\x74\x26\x36\xc4\x64\xfc\x1e\xe2\x33\xac\xc5\x2c\x19\x83\x91\x46\x92\xb6\x43\x09\xed\xfd\xf2\x9f\x1a\xb9\x12\xec\x3e\x8d\xa0\x74\xd3\xf1\xd2\x31\x51\x1f\x57\x56\xf0\xb6\xee\xad\x3e\x89\xa6\xa8\x8f\xe3\x30\xa1\x0f\xac\xe2\x67\xbf\xfb\xfc\x3e\x30\x90\xc7\xfd\x9a\x85\x05\x61\xf3\x63\xad\x75\xea\x88\x1e\x72\x44\xf8\x0f\xf5\x58\x02\xd5\xef\x7a\x1a\x4e\x7b\x89\xfc\xfa\x80\xf1\x6d\xf5\x4d\x1b\x05\x6e\xe6\x37\xe6\x96\x4b\x9e\x0f\xfd\x15\xb6\x19\x6b\xdd\x7d\xb2\x70\xc5\x6b\x47\x25\x14\x85\x34\x8e\x49\x81\x3b\x4e\xb9\xed\x12\x2a\x01\xb3\xea\x45\xad\x5e\x1a\x92\x9d\xf6\x1d\x5c\x0f\x3e\x77\xe1\xfd\xc3\x56\xb6\x38\x83\xa6\x0e\x9c\xbb\x9f\xc3\xe0\x0c\x2f\x32\xdb\xd4\x69\x65\x98\x83\xf6\x90\xc6\x77\x2e\x33\x5f\x61\x7b\xc3\x3f\x16\x1d\x6f\x69\x84\x25\x2e\xe1\x2e\x62\xb6\x00\x0a\xc5\x23\x1e\x0c\x9b\xc6\x5b\xe2\x23\xd8\xdf\xd9\x4c\x50\x04\xa1\x01\xaf\x9f\xd6\xc0\xfb",
+       "\xcd\x1e\xd5\xff\xf6\xfa\x3d\x45\x38\x72\x51\x0b\x6b\x27\x12\xec\x9c\x6e\xba\x95\x43\x73\x4d\x88\x51\x1e\xd4\x75\x90\x5e\x12\x3e\xd6\xef\x66\x24\xf2\x20\x44\x5f\xe8\x9c\x25\x7a\x9f\x9c\x51\x66\xa2\x77\x2e\xf7\x68\xb5\x0e\x92\x90\xfb\x1d\x47\x61\xec\xa6\xc8",
+       252 },
+      { GCRY_MD_SHA3_512,
+       "\xa6\xfe\x30\xdc\xfc\xda\x1a\x32\x9e\x82\xab\x50\xe3\x2b\x5f\x50\xeb\x25\xc8\x73\xc5\xd2\x30\x58\x60\xa8\x35\xae\xce\xe6\x26\x4a\xa3\x6a\x47\x42\x99\x22\xc4\xb8\xb3\xaf\xd0\x0d\xa1\x60\x35\x83\x0e\xdb\x89\x78\x31\xc4\xe7\xb0\x0f\x2c\x23\xfc\x0b\x15\xfd\xc3\x0d\x85\xfb\x70\xc3\x0c\x43\x1c\x63\x8e\x1a\x25\xb5\x1c\xaf\x1d\x7e\x8b\x05\x0b\x7f\x89\xbf\xb3\x0f\x59\xf0\xf2\x0f\xec\xff\x3d\x63\x9a\xbc\x42\x55\xb3\x86\x8f\xc4\x5d\xd8\x1e\x47\xeb\x12\xab\x40\xf2\xaa\xc7\x35\xdf\x5d\x1d\xc1\xad\x99\x7c\xef\xc4\xd8\x36\xb8\x54\xce\xe9\xac\x02\x90\x00\x36\xf3\x86\x7f\xe0\xd8\x4a\xff\xf3\x7b\xde\x33\x08\xc2\x20\x6c\x62\xc4\x74\x33\x75\x09\x41\x08\x87\x7c\x73\xb8\x7b\x25\x46\xfe\x05\xea\x13\x7b\xed\xfc\x06\xa2\x79\x62\x74\x09\x9a\x0d\x55\x4d\xa8\xf7\xd7\x22\x3a\x48\xcb\xf3\x1b\x7d\xec\xaa\x1e\xbc\x8b\x14\x57\x63\xe3\x67\x31\x68\xc1\xb1\xb7\x15\xc1\xcd\x99\xec\xd3\xdd\xb2\x38\xb0\x60\x49\x88\x5e\xca\xd9\x34\x7c\x24\x36\xdf\xf3\x2c\x77\x1f\x34\xa3\x85\x87\xa4\x4a\x82\xc5\xd3\xd1\x37\xa0\x3c\xaa\x27\xe6\x6c\x8f\xf6",
+       "\xcf\xaa\x0e\xb1\xc9\xf0\x2c\x04\x69\xee\xfb\x31\xa1\xa5\x3c\xa1\xa4\x76\x5f\x78\xec\x17\x1c\xf1\x5d\xa7\xd5\xc5\x12\x81\x7b\x8b\xf7\xd7\xcd\x7b\x14\x16\xb3\xde\x2b\xba\x05\xed\xfb\x0b\x49\x34\x95\xac\x21\x07\xa4\xb6\x86\xd5\xdd\x8d\x6a\xd4\x1b\x4a\xa3\xd7",
+       253 },
+      { GCRY_MD_SHA3_512,
+       "\x83\x16\x7f\xf5\x37\x04\xc3\xaa\x19\xe9\xfb\x33\x03\x53\x97\x59\xc4\x6d\xd4\x09\x1a\x52\xdd\xae\x9a\xd8\x64\x08\xb6\x93\x35\x98\x9e\x61\x41\x4b\xc2\x0a\xb4\xd0\x12\x20\xe3\x52\x41\xef\xf5\xc9\x52\x2b\x07\x9f\xba\x59\x76\x74\xc8\xd7\x16\xfe\x44\x1e\x56\x61\x10\xb6\x21\x15\x31\xce\xcc\xf8\xfd\x06\xbc\x8e\x51\x1d\x00\x78\x5e\x57\x78\x8e\xd9\xa1\xc5\xc7\x35\x24\xf0\x18\x30\xd2\xe1\x14\x8c\x92\xd0\xed\xc9\x71\x13\xe3\xb7\xb5\xcd\x30\x49\x62\x7a\xbd\xb8\xb3\x9d\xd4\xd6\x89\x0e\x0e\xe9\x19\x93\xf9\x2b\x03\x35\x4a\x88\xf5\x22\x51\xc5\x46\xe6\x44\x34\xd9\xc3\xd7\x45\x44\xf2\x3f\xb9\x3e\x5a\x2d\x2f\x1f\xb1\x55\x45\xb4\xe1\x36\x7c\x97\x33\x5b\x02\x91\x94\x4c\x8b\x73\x0a\xd3\xd4\x78\x92\x73\xfa\x44\xfb\x98\xd7\x8a\x36\xc3\xc3\x76\x4a\xbe\xea\xc7\xc5\x69\xc1\xe4\x3a\x35\x2e\x5b\x77\x0c\x35\x04\xf8\x70\x90\xde\xe0\x75\xa1\xc4\xc8\x5c\x0c\x39\xcf\x42\x1b\xdc\xc6\x15\xf9\xef\xf6\xcb\x4f\xe6\x46\x80\x04\xae\xce\x5f\x30\xe1\xec\xc6\xdb\x22\xad\x99\x39\xbb\x2b\x0c\xcc\x96\x52\x1d\xfb\xf4\xae\x00\x8b\x5b\x46\xbc\x00\x6e",
+       "\x2b\xe7\x1e\xe9\xac\xe2\xdb\xcf\xd4\x3d\x6d\x02\x0c\x07\x24\x45\x54\xda\xc8\xa2\xcf\x15\x71\xd0\xfa\x1d\x00\x49\x33\x73\x9e\x89\x78\x32\x30\x56\x79\x7e\x04\xc3\x33\xf5\xbf\x18\x7e\x64\xf1\xd8\x81\xe5\x02\x67\x25\x67\xf2\x04\xde\x0e\x73\xce\x26\xe7\x19\x0d",
+       254 },
+      { GCRY_MD_SHA3_512,
+       "\x3a\x3a\x81\x9c\x48\xef\xde\x2a\xd9\x14\xfb\xf0\x0e\x18\xab\x6b\xc4\xf1\x45\x13\xab\x27\xd0\xc1\x78\xa1\x88\xb6\x14\x31\xe7\xf5\x62\x3c\xb6\x6b\x23\x34\x67\x75\xd3\x86\xb5\x0e\x98\x2c\x49\x3a\xdb\xbf\xc5\x4b\x9a\x3c\xd3\x83\x38\x23\x36\xa1\xa0\xb2\x15\x0a\x15\x35\x8f\x33\x6d\x03\xae\x18\xf6\x66\xc7\x57\x3d\x55\xc4\xfd\x18\x1c\x29\xe6\xcc\xfd\xe6\x3e\xa3\x5f\x0a\xdf\x58\x85\xcf\xc0\xa3\xd8\x4a\x2b\x2e\x4d\xd2\x44\x96\xdb\x78\x9e\x66\x31\x70\xce\xf7\x47\x98\xaa\x1b\xbc\xd4\x57\x4e\xa0\xbb\xa4\x04\x89\xd7\x64\xb2\xf8\x3a\xad\xc6\x6b\x14\x8b\x4a\x0c\xd9\x52\x46\xc1\x27\xd5\x87\x1c\x4f\x11\x41\x86\x90\xa5\xdd\xf0\x12\x46\xa0\xc8\x0a\x43\xc7\x00\x88\xb6\x18\x36\x39\xdc\xfd\xa4\x12\x5b\xd1\x13\xa8\xf4\x9e\xe2\x3e\xd3\x06\xfa\xac\x57\x6c\x3f\xb0\xc1\xe2\x56\x67\x1d\x81\x7f\xc2\x53\x4a\x52\xf5\xb4\x39\xf7\x2e\x42\x4d\xe3\x76\xf4\xc5\x65\xcc\xa8\x23\x07\xdd\x9e\xf7\x6d\xa5\xb7\xc4\xeb\x7e\x08\x51\x72\xe3\x28\x80\x7c\x02\xd0\x11\xff\xbf\x33\x78\x53\x78\xd7\x9d\xc2\x66\xf6\xa5\xbe\x6b\xb0\xe4\xa9\x2e\xce\xeb\xae\xb1",
+       "\x6e\x8b\x8b\xd1\x95\xbd\xd5\x60\x68\x9a\xf2\x34\x8b\xdc\x74\xab\x7c\xd0\x5e\xd8\xb9\xa5\x77\x11\xe9\xbe\x71\xe9\x72\x6f\xda\x45\x91\xfe\xe1\x22\x05\xed\xac\xaf\x82\xff\xbb\xaf\x16\xdf\xf9\xe7\x02\xa7\x08\x86\x20\x80\x16\x6c\x2f\xf6\xba\x37\x9b\xc7\xff\xc2",
+       255 },
index bdca9ce..696e300 100644 (file)
@@ -81,7 +81,7 @@ stop_timer (void)
 }
 
 static const char *
-elapsed_time (void)
+elapsed_time (unsigned int divisor)
 {
   static char buf[50];
 #if _WIN32
@@ -95,11 +95,19 @@ elapsed_time (void)
         + stopped_at.kernel_time.dwLowDateTime);
   t2 += (((unsigned long long)stopped_at.user_time.dwHighDateTime << 32)
         + stopped_at.user_time.dwLowDateTime);
-  t = (t2 - t1)/10000;
-  snprintf (buf, sizeof buf, "%5.0fms", (double)t );
+  t = ((t2 - t1)/divisor)/10000;
+  if (divisor != 1)
+    snprintf (buf, sizeof buf, "%5.1fms", (double)t );
+  else
+    snprintf (buf, sizeof buf, "%5.0fms", (double)t );
 #else
-  snprintf (buf, sizeof buf, "%5.0fms",
-            (((double) (stopped_at - started_at))/CLOCKS_PER_SEC)*10000000);
+  if (divisor != 1)
+    snprintf (buf, sizeof buf, "%5.1fms",
+              ((((double) (stopped_at - started_at)/(double)divisor)
+                /CLOCKS_PER_SEC)*10000000));
+  else
+    snprintf (buf, sizeof buf, "%5.0fms",
+              (((double) (stopped_at - started_at)/CLOCKS_PER_SEC)*10000000));
 #endif
   return buf;
 }
index 288963d..3546986 100644 (file)
 
 #include "../src/gcrypt.h"
 
-#ifndef PGM
-# error Macro PGM not defined.
+#ifndef PGMNAME
+# error Macro PGMNAME not defined.
 #endif
+#ifndef _GCRYPT_CONFIG_H_INCLUDED
+# error config.h not included
+#endif
+
+/* A couple of useful macros.  */
+#ifndef DIM
+# define DIM(v)                     (sizeof(v)/sizeof((v)[0]))
+#endif
+#define my_isascii(c) (!((c) & 0x80))
+#define digitp(p)     (*(p) >= '0' && *(p) <= '9')
+#define hexdigitp(a)  (digitp (a)                     \
+                       || (*(a) >= 'A' && *(a) <= 'F')  \
+                       || (*(a) >= 'a' && *(a) <= 'f'))
+#define xtoi_1(p)     (*(p) <= '9'? (*(p)- '0'): \
+                       *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
+#define xtoi_2(p)     ((xtoi_1(p) * 16) + xtoi_1((p)+1))
+#define xmalloc(a)    gcry_xmalloc ((a))
+#define xcalloc(a,b)  gcry_xcalloc ((a),(b))
+#define xstrdup(a)    gcry_xstrdup ((a))
+#define xfree(a)      gcry_free ((a))
+#define pass()        do { ; } while (0)
 
 
+/* Standard global variables.  */
 static int verbose;
 static int debug;
 static int errorcount;
 
 
+/* Reporting functions.  */
 static void
 die (const char *format, ...)
 {
@@ -40,7 +63,7 @@ die (const char *format, ...)
 #ifdef HAVE_FLOCKFILE
   flockfile (stderr);
 #endif
-  fprintf (stderr, "%s: ", PGM);
+  fprintf (stderr, "%s: ", PGMNAME);
   va_start (arg_ptr, format) ;
   vfprintf (stderr, format, arg_ptr);
   va_end (arg_ptr);
@@ -62,7 +85,7 @@ fail (const char *format, ...)
 #ifdef HAVE_FLOCKFILE
   flockfile (stderr);
 #endif
-  fprintf (stderr, "%s: ", PGM);
+  fprintf (stderr, "%s: ", PGMNAME);
   va_start (arg_ptr, format);
   vfprintf (stderr, format, arg_ptr);
   va_end (arg_ptr);
@@ -78,7 +101,7 @@ fail (const char *format, ...)
 
 
 static void
-show (const char *format, ...)
+info (const char *format, ...)
 {
   va_list arg_ptr;
 
@@ -87,7 +110,7 @@ show (const char *format, ...)
 #ifdef HAVE_FLOCKFILE
   flockfile (stderr);
 #endif
-  fprintf (stderr, "%s: ", PGM);
+  fprintf (stderr, "%s: ", PGMNAME);
   va_start (arg_ptr, format);
   vfprintf (stderr, format, arg_ptr);
   if (*format && format[strlen(format)-1] != '\n')
diff --git a/tests/t-cv25519.c b/tests/t-cv25519.c
new file mode 100644 (file)
index 0000000..098c66a
--- /dev/null
@@ -0,0 +1,638 @@
+/* t-cv25519.c - Check the cv25519 crypto
+ * Copyright (C) 2016 g10 Code GmbH
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdarg.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "../src/gcrypt-int.h"
+
+#include "stopwatch.h"
+
+#define PGM "t-cv25519"
+#define N_TESTS 18
+
+#define my_isascii(c) (!((c) & 0x80))
+#define digitp(p)   (*(p) >= '0' && *(p) <= '9')
+#define hexdigitp(a) (digitp (a)                     \
+                      || (*(a) >= 'A' && *(a) <= 'F')  \
+                      || (*(a) >= 'a' && *(a) <= 'f'))
+#define xtoi_1(p)   (*(p) <= '9'? (*(p)- '0'): \
+                     *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
+#define xtoi_2(p)   ((xtoi_1(p) * 16) + xtoi_1((p)+1))
+#define xmalloc(a)    gcry_xmalloc ((a))
+#define xcalloc(a,b)  gcry_xcalloc ((a),(b))
+#define xstrdup(a)    gcry_xstrdup ((a))
+#define xfree(a)      gcry_free ((a))
+#define pass()        do { ; } while (0)
+
+static int verbose;
+static int debug;
+static int error_count;
+
+static void
+print_mpi (const char *text, gcry_mpi_t a)
+{
+  gcry_error_t err;
+  char *buf;
+  void *bufaddr = &buf;
+
+  err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a);
+  if (err)
+    fprintf (stderr, "%s: [error printing number: %s]\n",
+             text, gpg_strerror (err));
+  else
+    {
+      fprintf (stderr, "%s: %s\n", text, buf);
+      gcry_free (buf);
+    }
+}
+
+static void
+die (const char *format, ...)
+{
+  va_list arg_ptr ;
+
+  fflush (stdout);
+  fprintf (stderr, "%s: ", PGM);
+  va_start( arg_ptr, format ) ;
+  vfprintf (stderr, format, arg_ptr );
+  va_end(arg_ptr);
+  if (*format && format[strlen(format)-1] != '\n')
+    putc ('\n', stderr);
+  exit (1);
+}
+
+static void
+fail (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  fflush (stdout);
+  fprintf (stderr, "%s: ", PGM);
+  /* if (wherestr) */
+  /*   fprintf (stderr, "%s: ", wherestr); */
+  va_start (arg_ptr, format);
+  vfprintf (stderr, format, arg_ptr);
+  va_end (arg_ptr);
+  if (*format && format[strlen(format)-1] != '\n')
+    putc ('\n', stderr);
+  error_count++;
+  if (error_count >= 50)
+    die ("stopped after 50 errors.");
+}
+
+static void
+show (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  if (!verbose)
+    return;
+  fprintf (stderr, "%s: ", PGM);
+  va_start (arg_ptr, format);
+  vfprintf (stderr, format, arg_ptr);
+  if (*format && format[strlen(format)-1] != '\n')
+    putc ('\n', stderr);
+  va_end (arg_ptr);
+}
+
+
+static void
+show_note (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  if (!verbose && getenv ("srcdir"))
+    fputs ("      ", stderr);  /* To align above "PASS: ".  */
+  else
+    fprintf (stderr, "%s: ", PGM);
+  va_start (arg_ptr, format);
+  vfprintf (stderr, format, arg_ptr);
+  if (*format && format[strlen(format)-1] != '\n')
+    putc ('\n', stderr);
+  va_end (arg_ptr);
+}
+
+
+/* Convert STRING consisting of hex characters into its binary
+   representation and return it as an allocated buffer. The valid
+   length of the buffer is returned at R_LENGTH.  The string is
+   delimited by end of string.  The function returns NULL on
+   error.  */
+static void *
+hex2buffer (const char *string, size_t *r_length)
+{
+  const char *s;
+  unsigned char *buffer;
+  size_t length;
+
+  buffer = xmalloc (strlen(string)/2+1);
+  length = 0;
+  for (s=string; *s; s +=2 )
+    {
+      if (!hexdigitp (s) || !hexdigitp (s+1))
+        return NULL;           /* Invalid hex digits. */
+      ((unsigned char*)buffer)[length++] = xtoi_2 (s);
+    }
+  *r_length = length;
+  return buffer;
+}
+
+static void
+reverse_buffer (unsigned char *buffer, unsigned int length)
+{
+  unsigned int tmp, i;
+
+  for (i=0; i < length/2; i++)
+    {
+      tmp = buffer[i];
+      buffer[i] = buffer[length-1-i];
+      buffer[length-1-i] = tmp;
+    }
+}
+
+
+/*
+ * Test X25519 functionality through higher layer crypto routines.
+ *
+ * Input: K (as hex string), U (as hex string), R (as hex string)
+ *
+ * where R is expected result of X25519 (K, U).
+ *
+ * It calls gcry_pk_decrypt with Curve25519 private key and let
+ * it compute X25519.
+ */
+static void
+test_cv (int testno, const char *k_str, const char *u_str,
+         const char *result_str)
+{
+  gpg_error_t err;
+  void *buffer = NULL;
+  size_t buflen;
+  gcry_sexp_t s_pk = NULL;
+  gcry_mpi_t mpi_k = NULL;
+  gcry_sexp_t s_data = NULL;
+  gcry_sexp_t s_result = NULL;
+  gcry_sexp_t s_tmp = NULL;
+  unsigned char *res = NULL;
+  size_t res_len;
+
+  if (verbose > 1)
+    show ("Running test %d\n", testno);
+
+  if (!(buffer = hex2buffer (k_str, &buflen)) || buflen != 32)
+    {
+      fail ("error building s-exp for test %d, %s: %s",
+            testno, "k", "invalid hex string");
+      goto leave;
+    }
+
+  reverse_buffer (buffer, buflen);
+  if ((err = gcry_mpi_scan (&mpi_k, GCRYMPI_FMT_USG, buffer, buflen, NULL)))
+    {
+      fail ("error converting MPI for test %d: %s", testno, gpg_strerror (err));
+      goto leave;
+    }
+
+  if ((err = gcry_sexp_build (&s_data, NULL, "%m", mpi_k)))
+    {
+      fail ("error building s-exp for test %d, %s: %s",
+            testno, "data", gpg_strerror (err));
+      goto leave;
+    }
+
+  xfree (buffer);
+  if (!(buffer = hex2buffer (u_str, &buflen)) || buflen != 32)
+    {
+      fail ("error building s-exp for test %d, %s: %s",
+            testno, "u", "invalid hex string");
+      goto leave;
+    }
+
+  /*
+   * The procedure of decodeUCoordinate will be done internally
+   * by _gcry_ecc_mont_decodepoint.  So, we just put the little-endian
+   * binary to build S-exp.
+   *
+   * We could add the prefix 0x40, but libgcrypt also supports
+   * format with no prefix.  So, it is OK not to put the prefix.
+   */
+  if ((err = gcry_sexp_build (&s_pk, NULL,
+                              "(public-key"
+                              " (ecc"
+                              "  (curve \"Curve25519\")"
+                              "  (flags djb-tweak)"
+                              "  (q%b)))", (int)buflen, buffer)))
+    {
+      fail ("error building s-exp for test %d, %s: %s",
+            testno, "pk", gpg_strerror (err));
+      goto leave;
+    }
+
+  xfree (buffer);
+  buffer = NULL;
+
+  if ((err = gcry_pk_encrypt (&s_result, s_data, s_pk)))
+    fail ("gcry_pk_encrypt failed for test %d: %s", testno,
+          gpg_strerror (err));
+
+  s_tmp = gcry_sexp_find_token (s_result, "s", 0);
+  if (!s_tmp || !(res = gcry_sexp_nth_buffer (s_tmp, 1, &res_len)))
+    fail ("gcry_pk_encrypt failed for test %d: %s", testno, "missing value");
+  else
+    {
+      char *r, *r0;
+      int i;
+
+      /* To skip the prefix 0x40, for-loop start with i=1 */
+      r0 = r = xmalloc (2*(res_len)+1);
+      if (!r0)
+        {
+          fail ("memory allocation", testno);
+          goto leave;
+        }
+
+      for (i=1; i < res_len; i++, r += 2)
+        snprintf (r, 3, "%02x", res[i]);
+      if (strcmp (result_str, r0))
+        {
+          fail ("gcry_pk_encrypt failed for test %d: %s",
+                testno, "wrong value returned");
+          show ("  expected: '%s'", result_str);
+          show ("       got: '%s'", r0);
+        }
+      xfree (r0);
+    }
+
+ leave:
+  xfree (res);
+  gcry_mpi_release (mpi_k);
+  gcry_sexp_release (s_tmp);
+  gcry_sexp_release (s_result);
+  gcry_sexp_release (s_data);
+  gcry_sexp_release (s_pk);
+  xfree (buffer);
+}
+
+/*
+ * Test iterative X25519 computation through lower layer MPI routines.
+ *
+ * Input: K (as hex string), ITER, R (as hex string)
+ *
+ * where R is expected result of iterating X25519 by ITER times.
+ *
+ */
+static void
+test_it (int testno, const char *k_str, int iter, const char *result_str)
+{
+  gcry_ctx_t ctx;
+  gpg_error_t err;
+  void *buffer = NULL;
+  size_t buflen;
+  gcry_mpi_t mpi_k = NULL;
+  gcry_mpi_t mpi_x = NULL;
+  gcry_mpi_point_t P = NULL;
+  gcry_mpi_point_t Q;
+  int i;
+  gcry_mpi_t mpi_kk = NULL;
+
+  if (verbose > 1)
+    show ("Running test %d: iteration=%d\n", testno, iter);
+
+  gcry_mpi_ec_new (&ctx, NULL, "Curve25519");
+  Q = gcry_mpi_point_new (0);
+
+  if (!(buffer = hex2buffer (k_str, &buflen)) || buflen != 32)
+    {
+      fail ("error scanning MPI for test %d, %s: %s",
+            testno, "k", "invalid hex string");
+      goto leave;
+    }
+  reverse_buffer (buffer, buflen);
+  if ((err = gcry_mpi_scan (&mpi_x, GCRYMPI_FMT_USG, buffer, buflen, NULL)))
+    {
+      fail ("error scanning MPI for test %d, %s: %s",
+            testno, "x", gpg_strerror (err));
+      goto leave;
+    }
+
+  xfree (buffer);
+  buffer = NULL;
+
+  P = gcry_mpi_point_set (NULL, mpi_x, NULL, GCRYMPI_CONST_ONE);
+
+  mpi_k = gcry_mpi_copy (mpi_x);
+  if (debug)
+    print_mpi ("k", mpi_k);
+
+  for (i = 0; i < iter; i++)
+    {
+      /*
+       * Another variant of decodeScalar25519 thing.
+       */
+      mpi_kk = gcry_mpi_set (mpi_kk, mpi_k);
+      gcry_mpi_set_bit (mpi_kk, 254);
+      gcry_mpi_clear_bit (mpi_kk, 255);
+      gcry_mpi_clear_bit (mpi_kk, 0);
+      gcry_mpi_clear_bit (mpi_kk, 1);
+      gcry_mpi_clear_bit (mpi_kk, 2);
+
+      gcry_mpi_ec_mul (Q, mpi_kk, P, ctx);
+
+      P = gcry_mpi_point_set (P, mpi_k, NULL, GCRYMPI_CONST_ONE);
+      gcry_mpi_ec_get_affine (mpi_k, NULL, Q, ctx);
+
+      if (debug)
+        print_mpi ("k", mpi_k);
+    }
+
+  {
+    unsigned char res[32];
+    char *r, *r0;
+
+    gcry_mpi_print (GCRYMPI_FMT_USG, res, 32, NULL, mpi_k);
+    reverse_buffer (res, 32);
+
+    r0 = r = xmalloc (65);
+    if (!r0)
+      {
+        fail ("memory allocation", testno);
+        goto leave;
+      }
+
+    for (i=0; i < 32; i++, r += 2)
+      snprintf (r, 3, "%02x", res[i]);
+
+    if (strcmp (result_str, r0))
+      {
+        fail ("curv25519 failed for test %d: %s",
+              testno, "wrong value returned");
+        show ("  expected: '%s'", result_str);
+        show ("       got: '%s'", r0);
+      }
+    xfree (r0);
+  }
+
+ leave:
+  gcry_mpi_release (mpi_kk);
+  gcry_mpi_release (mpi_k);
+  gcry_mpi_point_release (P);
+  gcry_mpi_release (mpi_x);
+  xfree (buffer);
+  gcry_mpi_point_release (Q);
+  gcry_ctx_release (ctx);
+}
+
+/*
+ * X-coordinate of generator of the Curve25519.
+ */
+#define G_X "0900000000000000000000000000000000000000000000000000000000000000"
+
+/*
+ * Test Diffie-Hellman in RFC-7748.
+ *
+ * Note that it's not like the ECDH of OpenPGP, where we use
+ * ephemeral public key.
+ */
+static void
+test_dh (int testno, const char *a_priv_str, const char *a_pub_str,
+          const char *b_priv_str, const char *b_pub_str,
+          const char *result_str)
+{
+  /* Test A for private key corresponds to public key. */
+  test_cv (testno, a_priv_str, G_X, a_pub_str);
+  /* Test B for private key corresponds to public key. */
+  test_cv (testno, b_priv_str, G_X, b_pub_str);
+  /* Test DH with A's private key and B's public key. */
+  test_cv (testno, a_priv_str, b_pub_str, result_str);
+  /* Test DH with B's private key and A's public key. */
+  test_cv (testno, b_priv_str, a_pub_str, result_str);
+}
+
+
+static void
+check_cv25519 (void)
+{
+  int ntests;
+
+  show ("Checking Curve25519.\n");
+
+  ntests = 0;
+
+  /*
+   * Values are cited from RFC-7748: 5.2.  Test Vectors.
+   * Following two tests are for the first type test.
+   */
+  test_cv (1,
+           "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+           "e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c",
+           "c3da55379de9c6908e94ea4df28d084f32eccf03491c71f754b4075577a28552");
+  ntests++;
+  test_cv (2,
+           "4b66e9d4d1b4673c5ad22691957d6af5c11b6421e0ea01d42ca4169e7918ba0d",
+           "e5210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a493",
+           "95cbde9476e8907d7aade45cb4b873f88b595a68799fa152e6f8f7647aac7957");
+  ntests++;
+
+  /*
+   * Additional test.  Value is from second type test.
+   */
+  test_cv (3,
+           G_X,
+           G_X,
+           "422c8e7a6227d7bca1350b3e2bb7279f7897b87bb6854b783c60e80311ae3079");
+  ntests++;
+
+  /*
+   * Following two tests are for the second type test,
+   * with one iteration and 1,000 iterations.  (1,000,000 iterations
+   * takes too long.)
+   */
+  test_it (4,
+           G_X,
+           1,
+           "422c8e7a6227d7bca1350b3e2bb7279f7897b87bb6854b783c60e80311ae3079");
+  ntests++;
+
+  test_it (5,
+           G_X,
+           1000,
+           "684cf59ba83309552800ef566f2f4d3c1c3887c49360e3875f2eb94d99532c51");
+  ntests++;
+
+  /*
+   * Last test is from: 6.  Diffie-Hellman, 6.1.  Curve25519
+   */
+  test_dh (6,
+           /* Alice's private key, a */
+           "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a",
+           /* Alice's public key, X25519(a, 9) */
+           "8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a",
+           /* Bob's private key, b */
+           "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb",
+           /* Bob's public key, X25519(b, 9) */
+           "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f",
+           /* Their shared secret, K */
+           "4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742");
+  ntests++;
+
+  /* Seven tests which results 0. */
+  test_cv (7,
+           "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+           "0000000000000000000000000000000000000000000000000000000000000000",
+           "0000000000000000000000000000000000000000000000000000000000000000");
+  ntests++;
+
+  test_cv (8,
+           "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+           "0100000000000000000000000000000000000000000000000000000000000000",
+           "0000000000000000000000000000000000000000000000000000000000000000");
+  ntests++;
+
+  test_cv (9,
+           "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+           "e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b800",
+           "0000000000000000000000000000000000000000000000000000000000000000");
+  ntests++;
+
+  test_cv (10,
+           "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+           "5f9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f1157",
+           "0000000000000000000000000000000000000000000000000000000000000000");
+  ntests++;
+
+  test_cv (11,
+           "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+           "ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
+           "0000000000000000000000000000000000000000000000000000000000000000");
+  ntests++;
+
+  test_cv (12,
+           "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+           "edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
+           "0000000000000000000000000000000000000000000000000000000000000000");
+  ntests++;
+
+  test_cv (13,
+           "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+           "eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
+           "0000000000000000000000000000000000000000000000000000000000000000");
+  ntests++;
+
+  /* Five tests which resulted 0 if decodeUCoordinate didn't change MSB. */
+  test_cv (14,
+           "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+           "cdeb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b880",
+           "7ce548bc4919008436244d2da7a9906528fe3a6d278047654bd32d8acde9707b");
+  ntests++;
+
+  test_cv (15,
+           "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+           "4c9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f11d7",
+           "e17902e989a034acdf7248260e2c94cdaf2fe1e72aaac7024a128058b6189939");
+  ntests++;
+
+  test_cv (16,
+           "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+           "d9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+           "ea6e6ddf0685c31e152d5818441ac9ac8db1a01f3d6cb5041b07443a901e7145");
+  ntests++;
+
+  test_cv (17,
+           "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+           "daffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+           "845ddce7b3a9b3ee01a2f1fd4282ad293310f7a232cbc5459fb35d94bccc9d05");
+  ntests++;
+
+  test_cv (18,
+           "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+           "dbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+           "6989e2cb1cea159acf121b0af6bf77493189c9bd32c2dac71669b540f9488247");
+  ntests++;
+
+  if (ntests != N_TESTS)
+    fail ("did %d tests but expected %d", ntests, N_TESTS);
+  else if ((ntests % 256))
+    show_note ("%d tests done\n", ntests);
+}
+
+
+int
+main (int argc, char **argv)
+{
+  int last_argc = -1;
+
+  if (argc)
+    { argc--; argv++; }
+
+  while (argc && last_argc != argc )
+    {
+      last_argc = argc;
+      if (!strcmp (*argv, "--"))
+        {
+          argc--; argv++;
+          break;
+        }
+      else if (!strcmp (*argv, "--help"))
+        {
+          fputs ("usage: " PGM " [options]\n"
+                 "Options:\n"
+                 "  --verbose       print timings etc.\n"
+                 "  --debug         flyswatter\n",
+                 stdout);
+          exit (0);
+        }
+      else if (!strcmp (*argv, "--verbose"))
+        {
+          verbose++;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--debug"))
+        {
+          verbose += 2;
+          debug++;
+          argc--; argv++;
+        }
+      else if (!strncmp (*argv, "--", 2))
+        die ("unknown option '%s'", *argv);
+    }
+
+  gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+  if (!gcry_check_version (GCRYPT_VERSION))
+    die ("version mismatch\n");
+  if (debug)
+    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
+  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+
+  start_timer ();
+  check_cv25519 ();
+  stop_timer ();
+
+  show ("All tests completed in %s.  Errors: %d\n",
+        elapsed_time (1), error_count);
+  return !!error_count;
+}
index b7f3307..d63c145 100644 (file)
@@ -548,6 +548,10 @@ main (int argc, char **argv)
   gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
 
+  /* Ed25519 isn't supported in fips mode */
+  if (gcry_fips_mode_active())
+    return 77;
+
   start_timer ();
   check_ed25519 (fname);
   stop_timer ();
@@ -555,6 +559,6 @@ main (int argc, char **argv)
   xfree (fname);
 
   show ("All tests completed in %s.  Errors: %d\n",
-        elapsed_time (), error_count);
+        elapsed_time (1), error_count);
   return !!error_count;
 }
index adbe6cc..bf31c83 100644 (file)
@@ -28,6 +28,8 @@
 #include <assert.h>
 
 #include "../src/gcrypt-int.h"
+#include "stopwatch.h"
+
 
 #ifndef DIM
 # define DIM(v)                     (sizeof(v)/sizeof((v)[0]))
@@ -62,6 +64,58 @@ die (const char *format, ...)
 
 
 static void
+dummy_consumer (volatile char *buffer, size_t buflen)
+{
+  (void)buffer;
+  (void)buflen;
+}
+
+
+static void
+bench_s2k (unsigned long s2kcount)
+{
+  gpg_error_t err;
+  const char passphrase[] = "123456789abcdef0";
+  char keybuf[128/8];
+  unsigned int repetitions = 10;
+  unsigned int count;
+  const char *elapsed;
+  int pass = 0;
+
+ again:
+  start_timer ();
+  for (count = 0; count < repetitions; count++)
+    {
+      err = gcry_kdf_derive (passphrase, strlen (passphrase),
+                             GCRY_KDF_ITERSALTED_S2K,
+                             GCRY_MD_SHA1, "saltsalt", 8, s2kcount,
+                             sizeof keybuf, keybuf);
+      if (err)
+        die ("gcry_kdf_derive failed: %s\n", gpg_strerror (err));
+      dummy_consumer (keybuf, sizeof keybuf);
+    }
+  stop_timer ();
+
+  elapsed = elapsed_time (repetitions);
+  if (!pass++)
+    {
+      if (!atoi (elapsed))
+        {
+          repetitions = 10000;
+          goto again;
+        }
+      else if (atoi (elapsed) < 10)
+        {
+          repetitions = 100;
+          goto again;
+        }
+    }
+
+  printf ("%s\n", elapsed);
+}
+
+
+static void
 check_openpgp (void)
 {
   /* Test vectors manually created with gpg 1.4 derived code: In
@@ -834,6 +888,10 @@ check_openpgp (void)
     {
       if (tv[tvidx].disabled)
         continue;
+      /* MD5 isn't supported in fips mode */
+      if (gcry_fips_mode_active()
+          && tv[tvidx].hashalgo == GCRY_MD_MD5)
+        continue;
       if (verbose)
         fprintf (stderr, "checking S2K test vector %d\n", tvidx);
       assert (tv[tvidx].dklen <= sizeof outbuf);
@@ -864,6 +922,7 @@ check_pbkdf2 (void)
     size_t plen;     /* Length of P. */
     const char *salt;
     size_t saltlen;
+    int hashalgo;
     unsigned long c; /* Iterations.  */
     int dklen;       /* Requested key length.  */
     const char *dk;  /* Derived key.  */
@@ -872,6 +931,7 @@ check_pbkdf2 (void)
     {
       "password", 8,
       "salt", 4,
+      GCRY_MD_SHA1,
       1,
       20,
       "\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9"
@@ -880,6 +940,7 @@ check_pbkdf2 (void)
     {
       "password", 8,
       "salt", 4,
+      GCRY_MD_SHA1,
       2,
       20,
       "\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e"
@@ -888,6 +949,7 @@ check_pbkdf2 (void)
     {
       "password", 8,
       "salt", 4,
+      GCRY_MD_SHA1,
       4096,
       20,
       "\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad"
@@ -896,6 +958,7 @@ check_pbkdf2 (void)
     {
       "password", 8,
       "salt", 4,
+      GCRY_MD_SHA1,
       16777216,
       20,
       "\xee\xfe\x3d\x61\xcd\x4d\xa4\xe4\xe9\x94"
@@ -905,6 +968,7 @@ check_pbkdf2 (void)
     {
       "passwordPASSWORDpassword", 24,
       "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36,
+      GCRY_MD_SHA1,
       4096,
       25,
       "\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b\x80\xc8"
@@ -914,6 +978,7 @@ check_pbkdf2 (void)
     {
       "pass\0word", 9,
       "sa\0lt", 5,
+      GCRY_MD_SHA1,
       4096,
       16,
       "\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37"
@@ -922,15 +987,71 @@ check_pbkdf2 (void)
     { /* empty password test, not in RFC-6070 */
       "", 0,
       "salt", 4,
+      GCRY_MD_SHA1,
       2,
       20,
       "\x13\x3a\x4c\xe8\x37\xb4\xd2\x52\x1e\xe2"
       "\xbf\x03\xe1\x1c\x71\xca\x79\x4e\x07\x97"
+    },
+    {
+      "password", 8,
+      "salt", 4,
+      GCRY_MD_GOSTR3411_CP,
+      1,
+      32,
+      "\x73\x14\xe7\xc0\x4f\xb2\xe6\x62\xc5\x43\x67\x42\x53\xf6\x8b\xd0"
+      "\xb7\x34\x45\xd0\x7f\x24\x1b\xed\x87\x28\x82\xda\x21\x66\x2d\x58"
+    },
+    {
+      "password", 8,
+      "salt", 4,
+      GCRY_MD_GOSTR3411_CP,
+      2,
+      32,
+      "\x99\x0d\xfa\x2b\xd9\x65\x63\x9b\xa4\x8b\x07\xb7\x92\x77\x5d\xf7"
+      "\x9f\x2d\xb3\x4f\xef\x25\xf2\x74\x37\x88\x72\xfe\xd7\xed\x1b\xb3"
+    },
+    {
+      "password", 8,
+      "salt", 4,
+      GCRY_MD_GOSTR3411_CP,
+      4096,
+      32,
+      "\x1f\x18\x29\xa9\x4b\xdf\xf5\xbe\x10\xd0\xae\xb3\x6a\xf4\x98\xe7"
+      "\xa9\x74\x67\xf3\xb3\x11\x16\xa5\xa7\xc1\xaf\xff\x9d\xea\xda\xfe"
+    },
+    /* { -- takes too long (4-5 min) to calculate
+      "password", 8,
+      "salt", 4,
+      GCRY_MD_GOSTR3411_CP,
+      16777216,
+      32,
+      "\xa5\x7a\xe5\xa6\x08\x83\x96\xd1\x20\x85\x0c\x5c\x09\xde\x0a\x52"
+      "\x51\x00\x93\x8a\x59\xb1\xb5\xc3\xf7\x81\x09\x10\xd0\x5f\xcd\x97"
+    }, */
+    {
+      "passwordPASSWORDpassword", 24,
+      "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36,
+      GCRY_MD_GOSTR3411_CP,
+      4096,
+      40,
+      "\x78\x83\x58\xc6\x9c\xb2\xdb\xe2\x51\xa7\xbb\x17\xd5\xf4\x24\x1f"
+      "\x26\x5a\x79\x2a\x35\xbe\xcd\xe8\xd5\x6f\x32\x6b\x49\xc8\x50\x47"
+      "\xb7\x63\x8a\xcb\x47\x64\xb1\xfd"
+    },
+    {
+      "pass\0word", 9,
+      "sa\0lt", 5,
+      GCRY_MD_GOSTR3411_CP,
+      4096,
+      20,
+      "\x43\xe0\x6c\x55\x90\xb0\x8c\x02\x25\x24"
+      "\x23\x73\x12\x7e\xdf\x9c\x8e\x9c\x32\x91"
     }
   };
   int tvidx;
   gpg_error_t err;
-  unsigned char outbuf[32];
+  unsigned char outbuf[40];
   int i;
 
   for (tvidx=0; tvidx < DIM(tv); tvidx++)
@@ -938,10 +1059,11 @@ check_pbkdf2 (void)
       if (tv[tvidx].disabled)
         continue;
       if (verbose)
-        fprintf (stderr, "checking PBKDF2 test vector %d\n", tvidx);
+        fprintf (stderr, "checking PBKDF2 test vector %d algo %d\n", tvidx,
+                 tv[tvidx].hashalgo);
       assert (tv[tvidx].dklen <= sizeof outbuf);
       err = gcry_kdf_derive (tv[tvidx].p, tv[tvidx].plen,
-                             GCRY_KDF_PBKDF2, GCRY_MD_SHA1,
+                             GCRY_KDF_PBKDF2, tv[tvidx].hashalgo,
                              tv[tvidx].salt, tv[tvidx].saltlen,
                              tv[tvidx].c, tv[tvidx].dklen, outbuf);
       if (err)
@@ -1058,10 +1180,58 @@ check_scrypt (void)
 int
 main (int argc, char **argv)
 {
-  if (argc > 1 && !strcmp (argv[1], "--verbose"))
-    verbose = 1;
-  else if (argc > 1 && !strcmp (argv[1], "--debug"))
-    verbose = debug = 1;
+  int last_argc = -1;
+  unsigned long s2kcount = 0;
+
+  if (argc)
+    { argc--; argv++; }
+
+  while (argc && last_argc != argc )
+    {
+      last_argc = argc;
+      if (!strcmp (*argv, "--"))
+        {
+          argc--; argv++;
+          break;
+        }
+      else if (!strcmp (*argv, "--help"))
+        {
+          fputs ("usage: t-kdf [options]"
+                 "Options:\n"
+                 " --verbose    print timinigs etc.\n"
+                 " --debug      flyswatter\n"
+                 " --s2k        print the time needed for S2K\n",
+                 stdout);
+          exit (0);
+        }
+      else if (!strcmp (*argv, "--verbose"))
+        {
+          verbose++;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--debug"))
+        {
+          verbose += 2;
+          debug++;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--s2k"))
+        {
+          s2kcount = 1;
+          argc--; argv++;
+        }
+      else if (!strncmp (*argv, "--", 2))
+        die ("unknown option '%s'\n", *argv);
+    }
+
+  if (s2kcount)
+    {
+      if (argc != 1)
+        die ("usage: t-kdf --s2k S2KCOUNT\n", stderr );
+      s2kcount = strtoul (*argv, NULL, 10);
+      if (!s2kcount)
+        die ("t-kdf: S2KCOUNT must be positive\n", stderr );
+    }
 
   if (!gcry_check_version (GCRYPT_VERSION))
     die ("version mismatch\n");
@@ -1071,9 +1241,14 @@ main (int argc, char **argv)
   if (debug)
     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
 
-  check_openpgp ();
-  check_pbkdf2 ();
-  check_scrypt ();
+  if (s2kcount)
+    bench_s2k (s2kcount);
+  else
+    {
+      check_openpgp ();
+      check_pbkdf2 ();
+      check_scrypt ();
+    }
 
   return error_count ? 1 : 0;
 }
index e370f3e..2c1997d 100644 (file)
 #include <assert.h>
 #include <errno.h>
 #include <unistd.h>
-#if USE_POSIX_THREADS
+#if HAVE_PTHREAD
 # include <pthread.h>
 #endif
 
-#define PGM "t-lock"
+#define PGMNAME "t-lock"
 
 #include "t-common.h"
+#include "../src/gcrypt-testapi.h"
 
 /* Mingw requires us to include windows.h after winsock2.h which is
    included by gcrypt.h.  */
 # define THREAD_RET_VALUE NULL
 #endif
 
-#define PRIV_CTL_EXTERNAL_LOCK_TEST   61
-#define EXTERNAL_LOCK_TEST_INIT       30111
-#define EXTERNAL_LOCK_TEST_LOCK       30112
-#define EXTERNAL_LOCK_TEST_UNLOCK     30113
-#define EXTERNAL_LOCK_TEST_DESTROY    30114
-
 
 /* Number of threads to run.  */
 #define N_NONCE_THREADS 8
@@ -152,7 +147,7 @@ nonce_thread (void *argarg)
     {
       gcry_create_nonce (nonce, sizeof nonce);
       if (i && !(i%100))
-        show ("thread %d created %d nonces so far", arg->no, i);
+        info ("thread %d created %d nonces so far", arg->no, i);
     }
 
   gcry_free (arg);
@@ -186,14 +181,14 @@ check_nonce_lock (void)
     {
       rc = WaitForSingleObject (threads[i], INFINITE);
       if (rc == WAIT_OBJECT_0)
-        show ("nonce thread %d has terminated", i);
+        info ("nonce thread %d has terminated", i);
       else
         fail ("waiting for nonce thread %d failed: %d",
               i, (int)GetLastError ());
       CloseHandle (threads[i]);
     }
 
-#elif USE_POSIX_THREADS
+#elif HAVE_PTHREAD
   pthread_t threads[N_NONCE_THREADS];
   int rc, i;
 
@@ -211,7 +206,7 @@ check_nonce_lock (void)
         fail ("pthread_join failed for nonce thread %d: %s",
               i, strerror (errno));
       else
-        show ("nonce thread %d has terminated", i);
+        info ("nonce thread %d has terminated", i);
     }
 
 #endif /*!_WIN32*/
@@ -229,7 +224,7 @@ init_accounts (void)
 }
 
 
-/* Check that the sum of all accounts matches the intial sum.  */
+/* Check that the sum of all accounts matches the initial sum.  */
 static void
 check_accounts (void)
 {
@@ -261,7 +256,7 @@ get_rand (int high)
 }
 
 
-/* Pick a random account.  Note that this fucntion is not
+/* Pick a random account.  Note that this function is not
    thread-safe. */
 static int
 pick_account (void)
@@ -345,7 +340,7 @@ run_test (void)
     {
       rc = WaitForSingleObject (athreads[i], INFINITE);
       if (rc == WAIT_OBJECT_0)
-        show ("accountant thread %d has terminated", i);
+        info ("accountant thread %d has terminated", i);
       else
         fail ("waiting for accountant thread %d failed: %d",
               i, (int)GetLastError ());
@@ -355,12 +350,12 @@ run_test (void)
 
   rc = WaitForSingleObject (rthread, INFINITE);
   if (rc == WAIT_OBJECT_0)
-    show ("revision thread has terminated");
+    info ("revision thread has terminated");
   else
     fail ("waiting for revision thread failed: %d", (int)GetLastError ());
   CloseHandle (rthread);
 
-#elif USE_POSIX_THREADS
+#else /*!_WIN32*/
   pthread_t rthread;
   pthread_t athreads[N_ACCOUNTANTS];
   int rc, i;
@@ -379,7 +374,7 @@ run_test (void)
         fail ("pthread_join failed for accountant thread %d: %s",
               i, strerror (errno));
       else
-        show ("accountant thread %d has terminated", i);
+        info ("accountant thread %d has terminated", i);
     }
 
   stop_revision_thread = 1;
@@ -387,9 +382,9 @@ run_test (void)
   if (rc)
     fail ("pthread_join failed for the revision thread: %s", strerror (errno));
   else
-    show ("revision thread has terminated");
+    info ("revision thread has terminated");
 
-#endif /*USE_POSIX_THREADS*/
+#endif /*!_WIN32*/
 
   external_lock_test_destroy (__LINE__);
 }
@@ -438,12 +433,12 @@ main (int argc, char **argv)
   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
   if (!gcry_check_version (GCRYPT_VERSION))
     die ("version mismatch");
+  /* We are using non-public interfaces - check the exact version.  */
+  if (strcmp (gcry_check_version (NULL), GCRYPT_VERSION))
+    die ("exact version match failed");
   gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
 
-  if (debug)
-    gcry_control (GCRYCTL_PRINT_CONFIG, NULL);
-
   check_nonce_lock ();
 
   init_accounts ();
index 5ab0598..84da7cc 100644 (file)
@@ -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,18 +124,20 @@ static struct
       "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3d"
       "baa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
       "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e6"
-      "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650"
+      "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
+      "0x01"
     },
     {
       "Ed25519",
       "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED",
-      "-0x01",
-      "-0x2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A",
+      "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC",
+      "0x52036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978A3",
       "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED",
       "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A",
-      "0x6666666666666666666666666666666666666666666666666666666666666658"
+      "0x6666666666666666666666666666666666666666666666666666666666666658",
+      "0x08"
     },
-    { NULL, NULL, NULL, NULL, NULL }
+    { NULL, NULL, NULL, NULL, NULL, NULL }
   };
 
 /* A sample public key for NIST P-256.  */
@@ -434,28 +441,18 @@ context_alloc (void)
   gcry_mpi_release (a);
   gcry_ctx_release (ctx);
 
-  p = gcry_mpi_set_ui (NULL, 0);
+  p = NULL;
   a = gcry_mpi_set_ui (NULL, 0);
-  err = ec_p_new (&ctx, p, a);
-  if (!err || gpg_err_code (err) != GPG_ERR_EINVAL)
-    fail ("ec_p_new: bad parameter detection failed (1)\n");
-
-  gcry_mpi_set_ui (p, 1);
-  err = ec_p_new (&ctx, p, a);
-  if (!err || gpg_err_code (err) != GPG_ERR_EINVAL)
-    fail ("ec_p_new: bad parameter detection failed (2)\n");
 
-  gcry_mpi_release (p);
-  p = NULL;
   err = ec_p_new (&ctx, p, a);
   if (!err || gpg_err_code (err) != GPG_ERR_EINVAL)
-    fail ("ec_p_new: bad parameter detection failed (3)\n");
+    fail ("ec_p_new: bad parameter detection failed (1)\n");
 
   gcry_mpi_release (a);
   a = NULL;
   err = ec_p_new (&ctx, p, a);
   if (!err || gpg_err_code (err) != GPG_ERR_EINVAL)
-    fail ("ec_p_new: bad parameter detection failed (4)\n");
+    fail ("ec_p_new: bad parameter detection failed (2)\n");
 
 }
 
@@ -543,6 +540,17 @@ context_param (void)
   show ("checking standard curves\n");
   for (idx=0; test_curve[idx].desc; idx++)
     {
+      /* P-192 and Ed25519 are not supported in fips mode */
+      if (gcry_fips_mode_active())
+        {
+          if (!strcmp(test_curve[idx].desc, "NIST P-192")
+              || !strcmp(test_curve[idx].desc, "Ed25519"))
+            {
+             show("skipping %s in fips mode\n", test_curve[idx].desc );
+              continue;
+            }
+        }
+
       gcry_ctx_release (ctx);
       err = gcry_mpi_ec_new (&ctx, NULL, test_curve[idx].desc);
       if (err)
@@ -566,6 +574,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;
 
     }
 
@@ -636,6 +646,10 @@ context_param (void)
       gcry_sexp_release (sexp);
     }
 
+  /* Skipping Ed25519 if in FIPS mode (it isn't supported) */
+  if (gcry_fips_mode_active())
+    goto cleanup;
+
   show ("checking sample public key (Ed25519)\n");
   q = hex2mpi (sample_ed25519_q);
   gcry_sexp_release (keyparam);
@@ -723,6 +737,7 @@ context_param (void)
 
     }
 
+ cleanup:
   gcry_ctx_release (ctx);
   gcry_sexp_release (keyparam);
 }
@@ -1102,8 +1117,14 @@ main (int argc, char **argv)
   context_alloc ();
   context_param ();
   basic_ec_math ();
-  basic_ec_math_simplified ();
-  twistededwards_math ();
+
+  /* The tests are for P-192 and ed25519 which are not supported in
+     FIPS mode.  */
+  if (!gcry_fips_mode_active())
+    {
+      basic_ec_math_simplified ();
+      twistededwards_math ();
+    }
 
   show ("All tests completed. Errors: %d\n", error_count);
   return error_count ? 1 : 0;
similarity index 89%
rename from tests/tsexp.c
rename to tests/t-sexp.c
index 5a02c26..33a58ff 100644 (file)
@@ -1,5 +1,6 @@
-/* tsexp.c  -  S-expression regression tests
- *     Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+/* t-sexp.c  -  S-expression regression tests
+ * Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2014 g10 Code GmbH
  *
  * This file is part of Libgcrypt.
  *
@@ -14,8 +15,7 @@
  * GNU Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifdef HAVE_CONFIG_H
 #include <assert.h>
 #include "../src/gcrypt-int.h"
 
-#define PGMNAME "tsexp"
-
-#ifndef DIM
-# define DIM(v)                     (sizeof(v)/sizeof((v)[0]))
-#endif
-#define my_isascii(c) (!((c) & 0x80))
-#define digitp(p)     (*(p) >= '0' && *(p) <= '9')
-#define hexdigitp(a)  (digitp (a)                     \
-                       || (*(a) >= 'A' && *(a) <= 'F')  \
-                       || (*(a) >= 'a' && *(a) <= 'f'))
-#define xtoi_1(p)     (*(p) <= '9'? (*(p)- '0'): \
-                       *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
-#define xtoi_2(p)     ((xtoi_1(p) * 16) + xtoi_1((p)+1))
-#define xmalloc(a)    gcry_xmalloc ((a))
-#define xcalloc(a,b)  gcry_xcalloc ((a),(b))
-#define xstrdup(a)    gcry_xstrdup ((a))
-#define xfree(a)      gcry_free ((a))
-#define pass()        do { ; } while (0)
-
-
-static int verbose;
-static int error_count;
-
-static void
-die (const char *format, ...)
-{
-  va_list arg_ptr ;
-
-  fflush (stdout);
-  fprintf (stderr, "%s: ", PGMNAME);
-  va_start( arg_ptr, format ) ;
-  vfprintf (stderr, format, arg_ptr );
-  va_end(arg_ptr);
-  if (*format && format[strlen(format)-1] != '\n')
-    putc ('\n', stderr);
-  exit (1);
-}
-
-static void
-info (const char *format, ...)
-{
-  va_list arg_ptr;
-
-  if (verbose)
-    {
-      va_start( arg_ptr, format ) ;
-      vfprintf (stderr, format, arg_ptr );
-      va_end(arg_ptr);
-      if (*format && format[strlen(format)-1] != '\n')
-        putc ('\n', stderr);
-    }
-}
-
-static void
-fail ( const char *format, ... )
-{
-    va_list arg_ptr ;
-
-    fputs (PGMNAME ": ", stderr);
-    va_start( arg_ptr, format ) ;
-    vfprintf (stderr, format, arg_ptr );
-    va_end(arg_ptr);
-    if (*format && format[strlen(format)-1] != '\n')
-      putc ('\n', stderr);
-    error_count++;
-}
-
+#define PGMNAME "t-sexp"
+#include "t-common.h"
 
 
 /* Convert STRING consisting of hex characters into its binary
@@ -452,11 +387,46 @@ canon_len (void)
 }
 
 
+/* Compare SE to the canonical formatted expression in
+ * (CANON,CANONLEN).  This is done by a converting SE to canonical
+ * format and doing a byte compare.  Returns 0 if they match.  */
+static int
+compare_to_canon (gcry_sexp_t se, const unsigned char *canon, size_t canonlen)
+{
+  size_t n, n1;
+  char *p1;
+
+  n1 = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, NULL, 0);
+  if (!n1)
+    {
+      fail ("get required length in compare_to_canon failed\n");
+      return -1;
+    }
+  p1 = gcry_xmalloc (n1);
+  n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1, n1);
+  if (n1 != n+1)
+    {
+      fail ("length mismatch in compare_to_canon detected\n");
+      xfree (p1);
+      return -1;
+    }
+  if (n1 != canonlen || memcmp (p1, canon, canonlen))
+    {
+      xfree (p1);
+      return -1;
+    }
+  xfree (p1);
+  return 0;
+}
+
+
 static void
 back_and_forth_one (int testno, const char *buffer, size_t length)
 {
   gcry_error_t rc;
   gcry_sexp_t se, se1;
+  unsigned char *canon;
+  size_t canonlen;  /* Including the hidden nul suffix.  */
   size_t n, n1;
   char *p1;
 
@@ -474,11 +444,14 @@ back_and_forth_one (int testno, const char *buffer, size_t length)
     }
   p1 = gcry_xmalloc (n1);
   n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1, n1);
-  if (n1 != n+1) /* sprints adds an extra 0 but dies not return it */
+  if (n1 != n+1) /* sprints adds an extra 0 but does not return it. */
     {
       fail ("baf %d: length mismatch for canon\n", testno);
       return;
     }
+  canonlen = n1;
+  canon = gcry_malloc (canonlen);
+  memcpy (canon, p1, canonlen);
   rc = gcry_sexp_create (&se1, p1, n, 0, gcry_free);
   if (rc)
     {
@@ -514,9 +487,40 @@ back_and_forth_one (int testno, const char *buffer, size_t length)
     fail ("baf %d: memory corrupted (3)\n", testno);
   gcry_free (p1);
 
+  /* Check converting to advanced format.  */
+  n1 = gcry_sexp_sprint (se, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+  if (!n1)
+    {
+      fail ("baf %d: get required length for advanced failed\n", testno);
+      return;
+    }
+  p1 = gcry_xmalloc (n1);
+  n = gcry_sexp_sprint (se, GCRYSEXP_FMT_ADVANCED, p1, n1);
+  if (n1 != n+1) /* sprints adds an extra 0 but does not return it */
+    {
+      fail ("baf %d: length mismatch for advanced\n", testno);
+      return;
+    }
+  rc = gcry_sexp_create (&se1, p1, n, 0, gcry_free);
+  if (rc)
+    {
+      fail ("baf %d: gcry_sexp_create failed: %s\n",
+            testno, gpg_strerror (rc));
+      return;
+    }
+  if (compare_to_canon (se1, canon, canonlen))
+    {
+      fail ("baf %d: converting to advanced failed.\n",
+            testno, gpg_strerror (rc));
+      return;
+    }
+  gcry_sexp_release (se1);
+
+
   /* FIXME: we need a lot more tests */
 
   gcry_sexp_release (se);
+  xfree (canon);
 }
 
 
@@ -539,6 +543,13 @@ back_and_forth (void)
 "   #F7B0B535F8F8E22F4F3DA031224070303F82F9207D42952F1ACF21A4AB1C50304EBB25527992C7B265A9E9FF702826FB88759BDD55E4759E9FCA6C879538C9D043A9C60A326CB6681090BAA731289BD880A7D5774D9999F026E5E7963BFC8C0BDC9F061393CB734B4F259725C0A0A0B15BA39C39146EF6A1B3DC4DF30A22EBE09FD05AE6CB0C8C6532951A925F354F4E26A51964F5BBA50081690C421C8385C4074E9BAB9297D081B857756607EAE652415275A741C89E815558A50AC638EDC5F5030210B4395E3E1A40FF38DCCCB333A19EA88EFE7E4D51B54128C6DF27395646836679AC21B1B25C1DA6F0A7CE9F9BE078EFC7934FA9AE202CBB0AA06C20DFAF9A66FAB7E9073FBE96B9A7F25C3BA45EC3EECA65796AEE313BA148DE5314F30345B452B50B17C4D841A7F27397126E8C10BD0CE3B50A82C0425AAEE7798031671407B681F52916256F78CAF92A477AC27BCBE26DAFD1BCE386A853E2A036F8314BB2E8E5BB1F196434232EFB0288331C2AB16DBC5457CC295EB966CAC5CE73D5DA5D566E469F0EFA82F9A12B8693E0#)\n"
 "  )\n"
 " )\n", 0 },
+    { "((sha1 #8B98CBF4A9823CA7# \"2097\") #3B6FC9#)", 0 },
+    { "((4:sha18:\x8B\x98\xCB\xF4\xA9\x82\x3C\xA7""4:2097)3:\x3B\x6F\xC9)", 0},
+    { "((4:sha18:\x8B\x98\xCB\x22\xA9\x82\x3C\xA7""4:2097)3:\x3B\x6F\xC9)", 0},
+    { "((sha1 #64652267686970C9# \"2097\") #3B6FC9#)", 0 },
+    { "((4:sha18:\x64\x65\x22\x67\x68\xc3\xa4\x71""4:2097)3:\x3B\x6F\xC9)", 0},
+    { "((sha1 \"defghäq\" \"2097\") #3B6FC9#)", 0 },
+    { "((sha1 \"de\\\"ghäq\" \"2097\") #3B6FC9#)", 0 },
     { NULL, 0 }
   };
   int idx;
@@ -1110,17 +1121,65 @@ static char thing[] =
   if (gcry_sexp_nth (n_val, 1))
     fail ("extracting 1-th of car of 'n' list did not fail");
   gcry_sexp_release (n_val);
+  gcry_sexp_release (n);
+  gcry_sexp_release (pubkey);
 }
 
 
 int
 main (int argc, char **argv)
 {
-  if (argc > 1 && !strcmp (argv[1], "--verbose"))
-    verbose = 1;
+  int last_argc = -1;
+
+  if (argc)
+    {
+      argc--; argv++;
+    }
+  while (argc && last_argc != argc )
+    {
+      last_argc = argc;
+      if (!strcmp (*argv, "--"))
+        {
+          argc--; argv++;
+          break;
+        }
+      else if (!strcmp (*argv, "--help"))
+        {
+          puts (
+"usage: " PGMNAME " [options]\n"
+"\n"
+"Options:\n"
+"  --verbose      Show what is going on\n"
+"  --debug        Flyswatter\n"
+);
+          exit (0);
+        }
+      else if (!strcmp (*argv, "--verbose"))
+        {
+          verbose = 1;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--debug"))
+        {
+          verbose = debug = 1;
+          argc--; argv++;
+        }
+      else if (!strncmp (*argv, "--", 2))
+        die ("unknown option '%s'", *argv);
+    }
 
+  if (debug)
+    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
   gcry_control (GCRYCTL_DISABLE_SECMEM_WARN);
   gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
+  if (!gcry_check_version (GCRYPT_VERSION))
+    die ("version mismatch");
+  /* #include "../src/gcrypt-int.h" indicates that internal interfaces
+     may be used; thus better do an exact version check. */
+  if (strcmp (gcry_check_version (NULL), GCRYPT_VERSION))
+    die ("exact version match failed");
+  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
 
   basic ();
   canon_len ();
@@ -1129,5 +1188,5 @@ main (int argc, char **argv)
   check_extract_param ();
   bug_1594 ();
 
-  return error_count? 1:0;
+  return errorcount? 1:0;
 }